Page MenuHomePhabricator (Chris)

No OneTemporary

Authored By
Unknown
Size
689 KB
Referenced Files
None
Subscribers
None
This file is larger than 256 KB, so syntax highlighting was skipped.
diff --git a/.gitignore b/.gitignore
index d0581d5b..26923617 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
.scon*
*.log
*.pyc
+build
diff --git a/SConstruct b/SConstruct
index 9e7aa348..659e6d43 100644
--- a/SConstruct
+++ b/SConstruct
@@ -1,10 +1,23 @@
import os
import scons.utils
import scons.checks
SetOption('num_jobs', scons.utils.detectCPUs())
-env = Environment(ENV = os.environ)
+includedir = '{0}/include'.format(os.getcwd())
+
+env = Environment(ENV = os.environ, CPPPATH=includedir)
config = env.Configure(custom_tests = {'CheckAllegro5': scons.checks.checkAllegro5(False)})
config.CheckAllegro5()
env = config.Finish()
+
+#TODO Need to do separate checks later
+env.ParseConfig('freetype-config --libs --cflags')
+
+build_dir = 'build'
+options = {'networking': False,
+ 'allegro5': True
+ }
+
+env.VariantDir(build_dir, 'src')
+env.Library('r-tech1', env.SConscript('src/SConscript', variant_dir=build_dir, exports=['env', 'options']))
diff --git a/include/argument.h b/include/r-tech1/argument.h
similarity index 100%
rename from include/argument.h
rename to include/r-tech1/argument.h
diff --git a/include/compress.h b/include/r-tech1/compress.h
similarity index 100%
rename from include/compress.h
rename to include/r-tech1/compress.h
diff --git a/include/configuration.h b/include/r-tech1/configuration.h
similarity index 100%
rename from include/configuration.h
rename to include/r-tech1/configuration.h
diff --git a/include/console.h b/include/r-tech1/console.h
similarity index 100%
rename from include/console.h
rename to include/r-tech1/console.h
diff --git a/include/debug.h b/include/r-tech1/debug.h
similarity index 100%
rename from include/debug.h
rename to include/r-tech1/debug.h
diff --git a/include/ebox.h b/include/r-tech1/ebox.h
similarity index 100%
rename from include/ebox.h
rename to include/r-tech1/ebox.h
diff --git a/include/events.h b/include/r-tech1/events.h
similarity index 100%
rename from include/events.h
rename to include/r-tech1/events.h
diff --git a/include/exceptions/exception.h b/include/r-tech1/exceptions/exception.h
similarity index 100%
rename from include/exceptions/exception.h
rename to include/r-tech1/exceptions/exception.h
diff --git a/include/exceptions/load_exception.h b/include/r-tech1/exceptions/load_exception.h
similarity index 100%
rename from include/exceptions/load_exception.h
rename to include/r-tech1/exceptions/load_exception.h
diff --git a/include/exceptions/shutdown_exception.h b/include/r-tech1/exceptions/shutdown_exception.h
similarity index 100%
rename from include/exceptions/shutdown_exception.h
rename to include/r-tech1/exceptions/shutdown_exception.h
diff --git a/include/file-system.h b/include/r-tech1/file-system.h
similarity index 100%
rename from include/file-system.h
rename to include/r-tech1/file-system.h
diff --git a/include/font.h b/include/r-tech1/font.h
similarity index 100%
rename from include/font.h
rename to include/r-tech1/font.h
diff --git a/include/font_factory.h b/include/r-tech1/font_factory.h
similarity index 100%
rename from include/font_factory.h
rename to include/r-tech1/font_factory.h
diff --git a/include/ftalleg.h b/include/r-tech1/ftalleg.h
similarity index 100%
rename from include/ftalleg.h
rename to include/r-tech1/ftalleg.h
diff --git a/include/funcs.h b/include/r-tech1/funcs.h
similarity index 100%
rename from include/funcs.h
rename to include/r-tech1/funcs.h
diff --git a/include/graphics/allegro5/bitmap.h b/include/r-tech1/graphics/allegro5/bitmap.h
similarity index 100%
rename from include/graphics/allegro5/bitmap.h
rename to include/r-tech1/graphics/allegro5/bitmap.h
diff --git a/include/graphics/bitmap.h b/include/r-tech1/graphics/bitmap.h
similarity index 100%
rename from include/graphics/bitmap.h
rename to include/r-tech1/graphics/bitmap.h
diff --git a/include/graphics/color.h b/include/r-tech1/graphics/color.h
similarity index 100%
rename from include/graphics/color.h
rename to include/r-tech1/graphics/color.h
diff --git a/include/graphics/fire.h b/include/r-tech1/graphics/fire.h
similarity index 100%
rename from include/graphics/fire.h
rename to include/r-tech1/graphics/fire.h
diff --git a/include/graphics/gradient.h b/include/r-tech1/graphics/gradient.h
similarity index 100%
rename from include/graphics/gradient.h
rename to include/r-tech1/graphics/gradient.h
diff --git a/include/gui/animation.h b/include/r-tech1/gui/animation.h
similarity index 99%
rename from include/gui/animation.h
rename to include/r-tech1/gui/animation.h
index c419bc46..3b6c044a 100644
--- a/include/gui/animation.h
+++ b/include/r-tech1/gui/animation.h
@@ -1,393 +1,393 @@
#ifndef _paintown_gui_animation_h
#define _paintown_gui_animation_h
#include <vector>
#include <map>
#include <string>
#include "coordinate.h"
-#include "util/pointer.h"
-#include "util/graphics/gradient.h"
+#include "r-tech1/pointer.h"
+#include "r-tech1/graphics/gradient.h"
class Filesystem;
namespace Path{
class AbsolutePath;
}
typedef Path::AbsolutePath AbsolutePath;
namespace Graphics{
class Bitmap;
}
namespace Util{
class Draw;
}
class Token;
namespace Gui{
// To hold images by number easier to access and reuse
typedef std::map<int, Util::ReferenceCount<Graphics::Bitmap> > ImageMap;
/*! Base Element class for frame types */
class Element{
public:
virtual ~Element();
virtual void act(double xvel, double yvel);
virtual void draw(int xaxis, int yaxis, const Graphics::Bitmap &) = 0;
virtual void draw(const Graphics::Bitmap &) = 0;
virtual void reset() = 0;
virtual void setToEnd(const RelativePoint &) = 0;
virtual const std::string getInfo() = 0;
virtual inline const RelativePoint getOffset() const {
return this->offset;
}
virtual inline const RelativePoint getScrollOffset() const {
return this->offset;
}
virtual inline int getTime() const {
return this->time;
}
virtual inline int getAlpha() const {
return this->alpha;
}
protected:
Element(const Token *);
RelativePoint offset;
RelativePoint scrollOffset;
int time;
int alpha;
private:
void parseToken(const Token *);
};
/*! Image Frame */
class ImageFrame : public Element{
public:
ImageFrame(const Token *, ImageMap &, const std::string &);
ImageFrame(Util::ReferenceCount<Graphics::Bitmap> bmp);
virtual ~ImageFrame();
virtual void act(double xvel, double yvel);
virtual void draw(int xaxis, int yaxis, const Graphics::Bitmap &);
virtual void draw(const Graphics::Bitmap &);
virtual void reset();
virtual void setToEnd(const RelativePoint &);
virtual const std::string getInfo();
virtual inline const Util::ReferenceCount<Graphics::Bitmap> & getBitmap() const {
return this->bmp;
}
protected:
virtual void parseToken(const Token *, const std::string &, ImageMap &);
protected:
Util::ReferenceCount<Graphics::Bitmap> bmp;
bool horizontalFlip;
bool verticalFlip;
};
/*! Text Frame */
class TextFrame: public Element {
public:
TextFrame(const Token *);
virtual ~TextFrame();
virtual void act(double xvel, double yvel);
virtual void draw(int xaxis, int yaxis, const Graphics::Bitmap &);
virtual void draw(const Graphics::Bitmap &);
virtual void reset();
virtual void setToEnd(const RelativePoint &);
virtual const std::string getInfo();
protected:
virtual void parseToken(const Token *);
/* FIXME: default this to Globals::DEFAULT_FONT */
std::string font;
std::string message;
int fontWidth, fontHeight;
Effects::Gradient gradient;
};
/* Iterates over a series of items */
class Sequence{
public:
Sequence();
virtual Util::ReferenceCount<Element> getCurrentFrame() const = 0;
virtual int totalTicks() const = 0;
virtual void setToEnd() = 0;
/* Move the sequence along by the number of ticks and at the specified speed
* Returns true if the sequence can't move any farther.
*/
virtual bool forward(int tickCount, double velocityX, double velocityY) = 0;
virtual bool reverse(int tickCount, double velocityX, double velocityY) = 0;
virtual void draw(int xaxis, int yaxis, const Graphics::Bitmap &) const = 0;
virtual void reset() = 0;
virtual void resetTicks() = 0;
/* Forcifully move to the next/previous frame */
virtual void forwardFrame() = 0;
virtual void backFrame() = 0;
virtual ~Sequence();
};
class SequenceFrame: public Sequence {
public:
SequenceFrame(const Util::ReferenceCount<Element> & frame);
virtual Util::ReferenceCount<Element> getCurrentFrame() const;
virtual int totalTicks() const;
virtual void reset();
virtual void resetTicks();
virtual void setToEnd();
virtual void draw(int xaxis, int yaxis, const Graphics::Bitmap &) const;
/* Move the sequence along by the number of ticks and at the specified speed */
virtual bool forward(int tickCount, double velocityX, double velocityY);
virtual bool reverse(int tickCount, double velocityX, double velocityY);
/* Forcifully move to the next/previous frame */
virtual void forwardFrame();
virtual void backFrame();
protected:
Util::ReferenceCount<Element> frame;
int ticks;
};
/* Shows sequences in a loop */
class SequenceLoop: public Sequence {
public:
SequenceLoop(int loops);
virtual Util::ReferenceCount<Element> getCurrentFrame() const;
virtual void reset();
virtual void resetTicks();
virtual void setToEnd();
virtual void addSequence(const Util::ReferenceCount<Sequence> & sequence);
virtual void parse(const Token * token, ImageMap & map, const std::string & baseDir);
virtual void draw(int xaxis, int yaxis, const Graphics::Bitmap &) const;
virtual int totalTicks() const;
/* Move the sequence along by the number of ticks and at the specified speed */
virtual bool forward(int tickCount, double velocityX, double velocityY);
virtual bool reverse(int tickCount, double velocityX, double velocityY);
/* Forcifully move to the next/previous frame */
virtual void forwardFrame();
virtual void backFrame();
protected:
void resetChildrenTicks();
virtual Util::ReferenceCount<Sequence> getCurrentSequence() const;
/* The current frame to display */
unsigned int currentFrame;
/* The number of times left to loop */
unsigned int currentLoop;
/* The total number of times to loop */
const unsigned int loopTimes;
std::vector<Util::ReferenceCount<Sequence> > frames;
};
/* Shows all sequences simaltaneously */
class SequenceAll: public Sequence {
public:
SequenceAll(const Token * token, ImageMap & images, const std::string & baseDir);
virtual Util::ReferenceCount<Element> getCurrentFrame() const;
virtual void reset();
virtual void resetTicks();
virtual void setToEnd();
virtual void addSequence(const Util::ReferenceCount<Sequence> & sequence);
virtual void draw(int xaxis, int yaxis, const Graphics::Bitmap &) const;
virtual int totalTicks() const;
/* Move the sequence along by the number of ticks and at the specified speed */
virtual bool forward(int tickCount, double velocityX, double velocityY);
virtual bool reverse(int tickCount, double velocityX, double velocityY);
/* Forcifully move to the next/previous frame */
virtual void forwardFrame();
virtual void backFrame();
protected:
std::vector<Util::ReferenceCount<Sequence> > sequences;
typedef std::vector<Util::ReferenceCount<Sequence> >::iterator SequenceIterator;
typedef std::vector<Util::ReferenceCount<Sequence> >::const_iterator SequenceConstIterator;
};
/* Displays a random child node for its duration */
class SequenceRandom: public Sequence {
public:
SequenceRandom(const Token * token, ImageMap & images, const std::string & baseDir);
virtual Util::ReferenceCount<Element> getCurrentFrame() const;
virtual void reset();
virtual void resetTicks();
virtual void setToEnd();
virtual void addSequence(const Util::ReferenceCount<Sequence> & sequence);
virtual void draw(int xaxis, int yaxis, const Graphics::Bitmap &) const;
virtual int totalTicks() const;
/* Move the sequence along by the number of ticks and at the specified speed */
virtual bool forward(int tickCount, double velocityX, double velocityY);
virtual bool reverse(int tickCount, double velocityX, double velocityY);
/* Forcifully move to the next/previous frame */
virtual void forwardFrame();
virtual void backFrame();
protected:
unsigned int current;
std::vector<Util::ReferenceCount<Sequence> > sequences;
typedef std::vector<Util::ReferenceCount<Sequence> >::iterator SequenceIterator;
typedef std::vector<Util::ReferenceCount<Sequence> >::const_iterator SequenceConstIterator;
};
/* Handles a series of bitmaps */
class Animation{
protected:
Animation();
public:
Animation(const Token *token);
/*! Load only a single bitmap (for backwards compatibility of backgrounds in menu) */
Animation(const std::string &);
Animation(const AbsolutePath &);
/*! use an existing bitmap */
Animation(Util::ReferenceCount<Graphics::Bitmap> image);
virtual ~Animation();
/*! Reverse with ticks */
virtual void reverse(int tickCount = 1);
/*! Forward with ticks */
virtual void forward(int tickCount = 1);
/*! Logic ticking per iteration and moving to subsequent frames */
virtual void act();
/*! Draw */
virtual void draw(const Graphics::Bitmap &) const;
virtual void draw(int x, int y, int width, int height, const Graphics::Bitmap &) const;
/*! Forward to next frame with no regard to ticks */
virtual void forwardFrame();
/*! Back a frame with no regard to ticks */
virtual void backFrame();
/*! Reset everything to the beginning of the start of the animation */
virtual void resetAll();
/*! Set everything to the end of the animation */
virtual void setToEnd();
/*! Get printable information regarding current frame */
virtual const std::string getInfo();
/*! Reset only frame ticks and other things are ignored */
virtual void reset();
/* Total number of ticks used by this animation. If any frames have a time
* of -1 then the total time will also be -1, meaning infinity.
*/
virtual int totalTicks() const;
/*! Return ID */
virtual inline int getID() const {
return id;
}
/*! Depth of animation
TODO make depth unlimited and just use integers for weight of depth
*/
enum Depth {
BackgroundBottom,
BackgroundMiddle,
BackgroundTop,
ForegroundBottom,
ForegroundMiddle,
ForegroundTop,
};
/*! Get depth */
inline const Depth & getDepth() const {
return this->depth;
}
protected:
int id;
Depth depth;
unsigned int currentSequence;
bool allowReset;
RelativePoint axis;
// This allows the frames to scroll in place
RelativePoint velocity;
Coordinate window;
// std::vector<Util::ReferenceCount<Frame> > frames;
SequenceLoop sequence;
ImageMap images;
};
/* Handles a Util::Draw, which really can't be controlled in any way. This just wraps the drawer.draw() method */
class DrawableAnimation: public Animation {
public:
DrawableAnimation(const Util::ReferenceCount<Util::Draw> & drawer, Depth depth);
DrawableAnimation(const Util::ReferenceCount<Util::Draw> & drawer);
virtual void draw(const Graphics::Bitmap &) const;
virtual void draw(int x, int y, int width, int height, const Graphics::Bitmap &) const;
protected:
const Util::ReferenceCount<Util::Draw> drawer;
};
/*! Generalized to for re-use in other contexts (menu, cutscene, characterselect, etc) */
class AnimationManager{
public:
AnimationManager();
AnimationManager(const AnimationManager &);
virtual ~AnimationManager();
const AnimationManager & operator=(const AnimationManager &);
void forward(int tickCount = 1);
void reverse(int tickCount = 1);
void act();
void render(const Gui::Animation::Depth &, const Graphics::Bitmap &) const;
void add(const Util::ReferenceCount<Gui::Animation > & animation);
void reset();
void setToEnd();
int totalTicks() const;
const std::string getInfo(int id, bool all = false);
const std::vector<int> getIdList();
virtual inline const bool empty() const{
return this->animations.empty();
}
protected:
int countTicks(const std::vector<Util::ReferenceCount<Gui::Animation> > & toCount) const;
private:
std::map< Gui::Animation::Depth, std::vector< Util::ReferenceCount<Gui::Animation> > > animations;
};
}
#endif
diff --git a/include/gui/box.h b/include/r-tech1/gui/box.h
similarity index 100%
rename from include/gui/box.h
rename to include/r-tech1/gui/box.h
diff --git a/include/gui/container.h b/include/r-tech1/gui/container.h
similarity index 100%
rename from include/gui/container.h
rename to include/r-tech1/gui/container.h
diff --git a/include/gui/context-box.h b/include/r-tech1/gui/context-box.h
similarity index 97%
rename from include/gui/context-box.h
rename to include/r-tech1/gui/context-box.h
index d3f84ce7..3d6d7d27 100644
--- a/include/gui/context-box.h
+++ b/include/r-tech1/gui/context-box.h
@@ -1,262 +1,262 @@
#ifndef _paintown_gui_context_box_h
#define _paintown_gui_context_box_h
#include <string>
#include <vector>
#include "widget.h"
#include "popup-box.h"
#include "scroll-list.h"
-#include "../language-string.h"
-#include "util/graphics/gradient.h"
-#include "../file-system.h"
+#include "r-tech1/language-string.h"
+#include "r-tech1/graphics/gradient.h"
+#include "r-tech1/file-system.h"
-#include "util/pointer.h"
+#include "r-tech1/pointer.h"
class Token;
namespace Gui{
Effects::Gradient standardGradient(int max);
Effects::Gradient modifiedGradient(Graphics::Color low, Graphics::Color high, int max);
class ListValues{
public:
ListValues();
ListValues(const ListValues &);
virtual ~ListValues();
const ListValues & operator=(const ListValues &);
void getValues(const Token *);
virtual inline bool getInterpolate() const {
return this->interpolate;
}
virtual inline void setInterpolate(bool interpolate){
this->interpolate = interpolate;
}
virtual inline Graphics::Color getLowColor() const {
return this->lowColor;
}
virtual inline void setLowColor(Graphics::Color color){
this->lowColor = color;
}
virtual inline Graphics::Color getHighColor() const {
return this->highColor;
}
virtual inline void setHighColor(Graphics::Color color){
this->highColor = color;
}
virtual inline int getMaxGradient() const {
return this->maxGradient;
}
virtual inline void setMaxGradient(int max){
this->maxGradient = max;
}
virtual inline Graphics::Color getSelectedColor() const {
return this->selectedColor;
}
virtual inline void setSelectedColor(Graphics::Color color){
this->selectedColor = color;
}
virtual inline int getSelectedAlpha() const {
return this->selectedAlpha;
}
virtual inline void setSelectedAlpha(int alpha){
this->selectedAlpha = alpha;
}
virtual inline Graphics::Color getOtherColor() const {
return this->otherColor;
}
virtual inline void setOtherColor(Graphics::Color color){
this->otherColor = color;
}
virtual inline int getOtherAlpha() const {
return this->otherAlpha;
}
virtual inline void setOtherAlpha(int alpha){
this->otherAlpha = alpha;
}
virtual inline double getDistanceFadeMultiplier() const{
return this->distanceFadeMultiplier;
}
virtual inline void setDistanceFadeMultiplier(double multiplier){
this->distanceFadeMultiplier = multiplier;
}
virtual inline bool getDistanceFade() const {
return this->fade;
}
/* Whether or not non-selected items are faded proportional to their distance from the
* selected item.
*/
virtual inline void setDistanceFade(bool fade){
this->fade = fade;
}
protected:
bool interpolate;
Graphics::Color lowColor, highColor;
int maxGradient;
Graphics::Color selectedColor;
int selectedAlpha;
Graphics::Color otherColor;
int otherAlpha;
double distanceFadeMultiplier;
bool fade;
};
class ContextBox;
class ScrollListInterface;
class ContextItem: public ScrollItem {
public:
ContextItem(const std::string &, const ContextBox &);
virtual ~ContextItem();
virtual void draw(int x, int y, const Graphics::Bitmap & where, const Font & font, int distance) const;
virtual int size(const Font & font) const;
virtual void setText(const LanguageString & t);
inline const LanguageString & getLanguageText() const {
return text;
}
virtual inline std::string getText() const { return text.get(); }
protected:
LanguageString text;
const ContextBox & parent;
};
class ContextBox: public Widget {
public:
ContextBox();
ContextBox(const ContextBox &);
virtual ~ContextBox();
//! copy
ContextBox &operator=(const ContextBox &);
//! Logic
virtual void act(const Font &);
//! Render
using Widget::render;
virtual void render(const Graphics::Bitmap &);
virtual void render(const Graphics::Bitmap &, const Font & font);
//! Next
virtual bool next(const Font &);
//! Previous
virtual bool previous(const Font &);
//! Adjust left
virtual void adjustLeft();
//! Adjust right
virtual void adjustRight();
//! open context box
virtual void open();
//! Close context box
virtual void close();
//! Set context list
virtual void setList(const std::vector<Util::ReferenceCount<ContextItem> > & list);
virtual void addItem(const Util::ReferenceCount<ContextItem> & item);
/*! Scroll or Normal */
enum ListType{
Normal,
Scroll,
};
virtual void setListType(const ListType &);
virtual void setListWrap(bool wrap);
virtual Graphics::Color getSelectedColor() const;
//! Get current index
virtual inline unsigned int getCurrentIndex(){
return this->list->getCurrentIndex();
}
//! Is active?
virtual inline bool isActive(){
return (this->fadeState != NotActive);
}
//!set fadespeed
virtual inline void setFadeSpeed(int speed){
this->fadeSpeed = speed;
this->board.setFadeSpeed(speed);
}
//!set fade alpha
virtual inline void setFadeAlpha(int alpha){
this->fadeAlpha = alpha;
}
virtual inline int getFadeAlpha() const {
return this->fadeAlpha;
}
//! Set to use only text on background
virtual inline void setRenderOnlyText(bool render){
this->renderOnlyText = render;
}
virtual inline PopupBox & getBoard(){
return board;
}
virtual inline const Gui::ListValues & getListValues() const {
return this->values;
}
virtual inline Gui::ListValues & getListValues(){
return this->values;
}
virtual void setListValues(const Gui::ListValues & values);
private:
void doFade();
void drawText(const Graphics::Bitmap &, const Font & font);
enum FadeState{
NotActive,
FadeIn,
Active,
FadeOut,
};
//! Current fade state
FadeState fadeState;
//! Context list
Util::ReferenceCount<ScrollListInterface> list;
//! Fade speed
int fadeSpeed;
//! Fade Aplha
int fadeAlpha;
//! Board
PopupBox board;
//! The centered position
int cursorCenter;
//! Current y coordinate to render text from
int cursorLocation;
//! scroll wait
int scrollWait;
//! Gradient for selected cursor
Effects::Gradient selectedGradient;
//! Render Text only
bool renderOnlyText;
/*! List Values */
Gui::ListValues values;
};
}
#endif
diff --git a/include/gui/coordinate.h b/include/r-tech1/gui/coordinate.h
similarity index 100%
rename from include/gui/coordinate.h
rename to include/r-tech1/gui/coordinate.h
diff --git a/include/gui/cutscene.h b/include/r-tech1/gui/cutscene.h
similarity index 97%
rename from include/gui/cutscene.h
rename to include/r-tech1/gui/cutscene.h
index aa754208..7ab56ba6 100644
--- a/include/gui/cutscene.h
+++ b/include/r-tech1/gui/cutscene.h
@@ -1,101 +1,101 @@
#ifndef util_gui_cutscene_h
#define util_gui_cutscene_h
#include "fadetool.h"
-#include "util/pointer.h"
+#include "r-tech1/pointer.h"
#include "animation.h"
-#include "util/file-system.h"
+#include "r-tech1/file-system.h"
#include <string>
#include <vector>
class Token;
namespace Graphics{
class Bitmap;
}
namespace Gui{
/*! Cut scenes or story boards */
class Scene{
public:
Scene(const Token *);
virtual ~Scene();
virtual void forward(int tickCount = 1);
virtual void reverse(int tickCount = 1);
virtual void act();
virtual void render(const Graphics::Bitmap &);
virtual void addAnimation(const Util::ReferenceCount<Gui::Animation> &);
virtual void reset();
virtual void setToEnd();
virtual bool done() const;
virtual inline void setEnd(int ticks){
this->endTicks = ticks;
}
virtual inline Gui::AnimationManager & getManager(){
return this->backgrounds;
}
protected:
void parseScene(const Token * token);
protected:
int ticks;
int endTicks;
Gui::AnimationManager backgrounds;
Gui::FadeTool fader;
};
class CutScene{
public:
CutScene();
CutScene(const Filesystem::AbsolutePath & path);
CutScene(const Token *);
virtual ~CutScene();
virtual void setName(const std::string &);
virtual inline const std::string & getName() const {
return this->name;
}
virtual void setResolution(int w, int h);
virtual void setScene(unsigned int scene);
virtual inline int getScene() const{
return this->current;
}
/*! Return current scene */
virtual Util::ReferenceCount<Scene> getCurrent();
/* play all scenes in order */
virtual void playAll();
/* plays the current scene which may consists of several animations */
virtual void playScene();
/* play a specific scene */
virtual void playScene(unsigned scene);
/* advance to the next scene */
virtual void next();
virtual bool hasMore();
protected:
virtual void load(const Token * token);
protected:
std::string name;
int width;
int height;
std::vector< Util::ReferenceCount<Scene> > scenes;
unsigned int current;
};
}
#endif
diff --git a/include/gui/fadetool.h b/include/r-tech1/gui/fadetool.h
similarity index 98%
rename from include/gui/fadetool.h
rename to include/r-tech1/gui/fadetool.h
index 545f6433..89348117 100644
--- a/include/gui/fadetool.h
+++ b/include/r-tech1/gui/fadetool.h
@@ -1,89 +1,89 @@
#ifndef gui_fadetool_h
#define gui_fadetool_h
-#include "util/graphics/bitmap.h"
+#include "r-tech1/graphics/bitmap.h"
/*! Fade utility */
namespace Graphics{
class Bitmap;
}
class Token;
namespace Gui{
class FadeTool{
public:
FadeTool();
virtual ~FadeTool();
enum State{
FadeIn,
FadeOut,
NoFade,
EndFade,
};
//! Read info from Token
void parseDefaults(const Token *);
// Fade state
void setState(const State &);
// update
void act();
// Fade to whatever state it is at
virtual void draw(const Graphics::Bitmap &);
inline const State & getState() const {
return currentState;
}
inline void setFadeInTime(const int time){
fadeInTime = time;
}
inline void setFadeOutTime(const int time){
fadeOutTime = time;
}
inline int getFadeInTime() const {
return fadeInTime;
}
inline int getFadeOutTime() const {
return fadeOutTime;
}
inline void setFadeInColor(Graphics::Color c){
fadeInColor = c;
}
inline Graphics::Color getFadeInColor() const {
return fadeInColor;
}
inline void setFadeOutColor(Graphics::Color c ){
fadeOutColor = c;
}
inline Graphics::Color getFadeOutColor() const {
return fadeOutColor;
}
protected:
//! Read fade from Token
void readFade(const Token *, const State &);
State currentState;
State lastState;
int fadeTime;
int fadeInTime;
int fadeOutTime;
Graphics::Color fadeInColor;
Graphics::Color fadeOutColor;
};
}
#endif
diff --git a/include/gui/lineedit.h b/include/r-tech1/gui/lineedit.h
similarity index 92%
rename from include/gui/lineedit.h
rename to include/r-tech1/gui/lineedit.h
index 98a2f395..bf0c9d7c 100644
--- a/include/gui/lineedit.h
+++ b/include/r-tech1/gui/lineedit.h
@@ -1,78 +1,78 @@
#ifndef paintown_gui_lineedit_h
#define paintown_gui_lineedit_h
#include <iostream>
#include <vector>
#include "widget.h"
#include "timer.h"
-#include "util/input/text-input.h"
+#include "r-tech1/input/text-input.h"
class Font;
class keys;
namespace Gui{
class LineEdit: public Widget{
public:
//! Constructor
LineEdit();
//! Destructor
virtual ~LineEdit();
//! Set textColor
void setTextColor(const Graphics::Color color);
//! Set textColor
void setCursorColor(const Graphics::Color color);
//! Update
void act(const Font &);
//! Draw
void draw(const Font &, const Graphics::Bitmap &);
//! Render
using Gui::Widget::render;
void render(const Graphics::Bitmap &);
virtual void toggleEnabled();
virtual void setFocused(bool enabled);
virtual void addHook(int key, void (*callback)(void *), void * arg);
virtual bool didChanged(unsigned long long &);
virtual inline const std::string getText() const {
return this->input.getText();
}
virtual inline void setText(const std::string & text){
this->input.setText(text);
}
virtual inline void clear(){
this->input.clearInput();
}
virtual inline void setBlinkRate(int rate){
this->blinkRate = rate;
}
protected:
void renderCursor(int x, int y, const Font &, const Graphics::Bitmap &);
Graphics::Color textColor;
Graphics::Color cursorColor;
TextInput input;
int blinkRate;
int cursorTime;
bool changed;
};
}
#endif
diff --git a/include/gui/list.h b/include/r-tech1/gui/list.h
similarity index 96%
rename from include/gui/list.h
rename to include/r-tech1/gui/list.h
index d524588e..69efb794 100644
--- a/include/gui/list.h
+++ b/include/r-tech1/gui/list.h
@@ -1,59 +1,59 @@
#ifndef _gui_list_h
#define _gui_list_h
#include "widget.h"
-#include "util/pointer.h"
-#include "util/font.h"
+#include "r-tech1/pointer.h"
+#include "r-tech1/font.h"
namespace Gui{
class ListItem{
public:
ListItem();
virtual ~ListItem();
virtual bool operator==(const ListItem &) = 0;
virtual bool equals(Util::ReferenceCount<ListItem>) = 0;
virtual int compareTo(Util::ReferenceCount<ListItem>) = 0;
virtual void act() = 0;
virtual void draw(const Font &, const Graphics::Bitmap &) = 0;
};
class ListInterface : public Gui::Widget{
public:
ListInterface();
virtual ~ListInterface();
virtual void act(const Font &) = 0;
virtual void draw(const Font &, const Graphics::Bitmap &) = 0;
virtual void add(const Util::ReferenceCount<ListItem>) = 0;
virtual void add(const std::vector< Util::ReferenceCount<ListItem> > &) = 0;
virtual void remove(const Util::ReferenceCount<ListItem>) = 0;
virtual void replace(const std::vector< Util::ReferenceCount<ListItem> > &) = 0;
virtual void clear() = 0;
virtual const std::vector< Util::ReferenceCount<ListItem> > & getList() const = 0;
private:
void render(const Graphics::Bitmap &);
void render(const Graphics::Bitmap &, const Font &);
};
class SimpleList : public ListInterface{
public:
SimpleList();
virtual ~SimpleList();
void act(const Font &);
void draw(const Font &, const Graphics::Bitmap &);
void add(const Util::ReferenceCount<ListItem>);
void add(const std::vector< Util::ReferenceCount<ListItem> > &);
void remove(const Util::ReferenceCount<ListItem>);
void replace(const std::vector< Util::ReferenceCount<ListItem> > &);
void clear();
const std::vector< Util::ReferenceCount<ListItem> > & getList() const;
protected:
std::vector< Util::ReferenceCount<ListItem> > list;
};
}
#endif
diff --git a/include/gui/popup-box.h b/include/r-tech1/gui/popup-box.h
similarity index 73%
rename from include/gui/popup-box.h
rename to include/r-tech1/gui/popup-box.h
index 009cbc4e..50d069d3 100644
--- a/include/gui/popup-box.h
+++ b/include/r-tech1/gui/popup-box.h
@@ -1,76 +1,76 @@
#ifndef _paintown_gui_popup_box_h
#define _paintown_gui_popup_box_h
#include <string>
#include <vector>
#include "widget.h"
#include "box.h"
-#include "util/graphics/gradient.h"
+#include "r-tech1/graphics/gradient.h"
namespace Gui{
class PopupBox : public Widget {
public:
PopupBox();
PopupBox(const PopupBox &);
virtual ~PopupBox();
//! copy
PopupBox &operator=(const PopupBox &);
//! Logic
virtual void act(const Font &);
//! Render
using Widget::render;
virtual void render(const Graphics::Bitmap &);
//! Open box
- virtual void open();
- //! Close box
- virtual void close();
+ virtual void open();
+ //! Close box
+ virtual void close();
//! Is active?
- virtual inline bool isActive(){
- return (this->fadeState != Closed);
- }
+ virtual inline bool isActive(){
+ return (this->fadeState != Closed);
+ }
virtual inline bool isOpen(){
return this->fadeState == Open ||
this->fadeState == FadeIn;
}
//!set fadespeed
virtual inline void setFadeSpeed(int speed){
this->fadeSpeed = speed;
}
//! Get current box coordinates
virtual inline const Coordinate & getArea(){
return this->board.location;
}
//! Get current box transformations
virtual inline const Gui::Transformations & getTransforms(){
- return this->board.transforms;
- }
+ return this->board.transforms;
+ }
private:
-
- void doFade();
-
- enum FadeState{
- Closed,
- FadeIn,
- Open,
- FadeOut,
- };
+
+ void doFade();
+
+ enum FadeState{
+ Closed,
+ FadeIn,
+ Open,
+ FadeOut,
+ };
//! Current fade state
- FadeState fadeState;
+ FadeState fadeState;
//! Fade speed
- int fadeSpeed;
-
- //! Board
- Box board;
+ int fadeSpeed;
+
+ //! Board
+ Box board;
};
}
#endif
diff --git a/include/gui/rectarea.h b/include/r-tech1/gui/rectarea.h
similarity index 100%
rename from include/gui/rectarea.h
rename to include/r-tech1/gui/rectarea.h
diff --git a/include/gui/scroll-list.h b/include/r-tech1/gui/scroll-list.h
similarity index 100%
rename from include/gui/scroll-list.h
rename to include/r-tech1/gui/scroll-list.h
diff --git a/include/gui/select-list.h b/include/r-tech1/gui/select-list.h
similarity index 99%
rename from include/gui/select-list.h
rename to include/r-tech1/gui/select-list.h
index d57e614e..e5c2049f 100644
--- a/include/gui/select-list.h
+++ b/include/r-tech1/gui/select-list.h
@@ -1,305 +1,305 @@
#ifndef _gui_select_list_h
#define _gui_select_list_h
#include <string>
#include <vector>
#include "coordinate.h"
-#include "util/pointer.h"
+#include "r-tech1/pointer.h"
class Font;
namespace Gui{
/*! Select Item pure virtual interface */
class SelectItem{
public:
SelectItem();
virtual ~SelectItem();
virtual void draw(int x, int y, int width, int height, const Graphics::Bitmap &, const Font &) const = 0;
virtual bool isEmpty() const = 0;
};
/*! Select List Interface */
class SelectListInterface{
public:
SelectListInterface();
virtual ~SelectListInterface();
//! Logic
virtual void act() = 0;
//! Render
virtual void render(const Graphics::Bitmap &, const Font &) const = 0;
//! Add item
virtual void addItem(const Util::ReferenceCount<SelectItem> &) = 0;
//! Add vector of items
virtual void addItems(const std::vector<Util::ReferenceCount<SelectItem> > &) = 0;
//! Get vector of items
virtual const std::vector<Util::ReferenceCount<SelectItem> > & getItems() const = 0;
//! Get specific item
virtual const Util::ReferenceCount<SelectItem> getItem(unsigned int index) const = 0;
//! Get specific item
virtual const Util::ReferenceCount<SelectItem> getItemByCursor(unsigned int index) const = 0;
virtual void clearItems() = 0;
virtual void setCellDimensions(int width, int height) = 0;
virtual void setCellSpacing(int x, int y) = 0;
virtual void setCellMargins(int x, int y) = 0;
virtual void setStartingOffset(int x, int y) = 0;
virtual void setCursors(int total) = 0;
virtual int totalCursors() const = 0;
enum CursorState{
Disabled,
Active,
Done,
Invalid,
};
/* Get the location in pixels of an item where it would be drawn */
virtual void getDrawLocation(const Util::ReferenceCount<SelectItem> & item, int * x, int * y) const = 0;
virtual void setCurrentIndex(unsigned int cursor, unsigned int location) = 0;
virtual unsigned int getCurrentIndex(unsigned int cursor) const = 0;
virtual void setCurrentState(unsigned int cursor, const CursorState &) = 0;
virtual const CursorState getCurrentState(unsigned int cursor) const = 0;
virtual bool up(unsigned int cursor) = 0;
virtual bool down(unsigned int cursor) = 0;
virtual bool left(unsigned int cursor) = 0;
virtual bool right(unsigned int cursor) = 0;
//! Has more low/high
virtual bool hasMoreLow() const = 0;
virtual bool hasMoreHigh() const = 0;
//! Get dimensions
virtual int getWidth() = 0;
virtual int getHeight() = 0;
//! Access Empty
virtual inline void setAccessEmpty(bool access){
this->accessEmpty = access;
}
//! Get Occupy empty
virtual inline bool getAccessEmpty() const {
return this->accessEmpty;
}
//! Draw Empty
virtual inline void setDrawEmpty(bool draw){
this->drawEmpty = draw;
}
//! Get Draw empty
virtual inline bool getDrawEmpty() const {
return this->drawEmpty;
}
//! Set wrap
virtual inline void setWrap(bool wrap){
this->allowWrap = wrap;
}
//! Get wrap
virtual inline bool getWrap() const {
return this->allowWrap;
}
protected:
//! Can occupy empty cells/spaces
bool accessEmpty;
//! Can draw empty cells
bool drawEmpty;
//! Is wrappable
bool allowWrap;
};
/*! Cursor handler */
class Cursor{
public:
Cursor(unsigned int index, const SelectListInterface::CursorState &);
~Cursor();
Cursor(const Cursor &);
const Cursor & operator=(const Cursor &);
void setIndex(unsigned int index);
unsigned int getIndex() const;
void increment();
void decrement();
void setState(const SelectListInterface::CursorState &);
const SelectListInterface::CursorState & getState() const;
private:
unsigned int index;
SelectListInterface::CursorState state;
};
/*! Simple list */
class SimpleSelect: public SelectListInterface {
public:
SimpleSelect();
virtual ~SimpleSelect();
virtual void act();
virtual void render(const Graphics::Bitmap &, const Font &) const;
virtual void addItem(const Util::ReferenceCount<SelectItem> &);
virtual void addItems(const std::vector<Util::ReferenceCount<SelectItem> > &);
virtual const std::vector<Util::ReferenceCount<SelectItem> > & getItems() const;
virtual const Util::ReferenceCount<SelectItem> getItem(unsigned int index) const;
virtual const Util::ReferenceCount<SelectItem> getItemByCursor(unsigned int cursor) const;
virtual void clearItems();
virtual void setCellDimensions(int width, int height);
virtual void setCellSpacing(int x, int y);
virtual void setCellMargins(int x, int y);
virtual void setStartingOffset(int x, int y);
virtual void setCursors(int total);
virtual int totalCursors() const;
virtual void setCurrentIndex(unsigned int cursor, unsigned int location);
virtual unsigned int getCurrentIndex(unsigned int cursor) const;
virtual void setCurrentState(unsigned int cursor, const SelectListInterface::CursorState &);
virtual const SelectListInterface::CursorState getCurrentState(unsigned int cursor) const;
virtual void getDrawLocation(const Util::ReferenceCount<SelectItem> & item, int * x, int * y) const;
virtual bool up(unsigned int cursor);
virtual bool down(unsigned int cursor);
virtual bool left(unsigned int cursor);
virtual bool right(unsigned int cursor);
virtual bool hasMoreLow() const;
virtual bool hasMoreHigh() const;
virtual int getWidth();
virtual int getHeight();
virtual void setViewable(unsigned int viewable){
this->viewable = viewable;
}
virtual unsigned int getViewable() const {
return this->viewable;
}
enum Layout {
Vertical,
Horizontal,
};
virtual void setLayout(const Layout & layout){
this->layout = layout;
}
virtual const Layout & getLayout() const {
return this->layout;
}
virtual void setScrollOffset(int offset){
this->scrollOffset = offset;
}
virtual int getScrollOffset() const {
return this->scrollOffset;
}
protected:
bool checkCursor(unsigned int cursor) const;
void calculateLeft(unsigned int cursor);
void calculateRight(unsigned int cursor);
Layout layout;
unsigned int viewable;
unsigned int currentTop;
int scrollOffset;
int cellWidth, cellHeight;
int cellSpacingX, cellSpacingY;
int cellMarginX, cellMarginY;
int startOffsetX, startOffsetY;
std::vector<Cursor> cursors;
std::vector<Util::ReferenceCount<SelectItem> > items;
};
/*! Select Grid */
class GridSelect: public SelectListInterface {
public:
GridSelect();
virtual ~GridSelect();
virtual void act();
virtual void render(const Graphics::Bitmap &, const Font &) const;
virtual void addItem(const Util::ReferenceCount<SelectItem> &);
virtual void addItems(const std::vector<Util::ReferenceCount<SelectItem> > &);
virtual const std::vector<Util::ReferenceCount<SelectItem> > & getItems() const;
virtual const Util::ReferenceCount<SelectItem> getItem(unsigned int index) const;
virtual const Util::ReferenceCount<SelectItem> getItemByCursor(unsigned int cursor) const;
virtual void clearItems();
virtual void setCellDimensions(int width, int height);
virtual void setCellSpacing(int x, int y);
virtual void setCellMargins(int x, int y);
virtual void setStartingOffset(int x, int y);
virtual void setCursors(int total);
virtual int totalCursors() const;
virtual void setCurrentIndex(unsigned int cursor, unsigned int location);
virtual unsigned int getCurrentIndex(unsigned int cursor) const;
virtual void setCurrentState(unsigned int cursor, const SelectListInterface::CursorState &);
virtual const SelectListInterface::CursorState getCurrentState(unsigned int cursor) const;
virtual void getDrawLocation(const Util::ReferenceCount<SelectItem> & item, int * x, int * y) const;
virtual bool up(unsigned int cursor);
virtual bool down(unsigned int cursor);
virtual bool left(unsigned int cursor);
virtual bool right(unsigned int cursor);
virtual bool hasMoreLow() const;
virtual bool hasMoreHigh() const;
virtual int getWidth();
virtual int getHeight();
enum Layout {
Static,
InfiniteHorizontal,
InfiniteVertical,
};
virtual void setLayout(const Layout & layout){
this->layout = layout;
}
virtual const Layout & getLayout() const {
return this->layout;
}
virtual void setGridSize(int x, int y){
this->gridX = x;
this->gridY = y;
}
virtual const int getGridX() const {
return this->gridX;
}
virtual const int getGridY() const {
return this->gridY;
}
protected:
bool moveUp(unsigned int cursor);
bool moveDown(unsigned int cursor);
bool moveLeft(unsigned int cursor);
bool moveRight(unsigned int cursor);
bool checkCursor(unsigned int cursor) const;
Layout layout;
int gridX, gridY;
int cellWidth, cellHeight;
int cellSpacingX, cellSpacingY;
int cellMarginX, cellMarginY;
int startOffsetX, startOffsetY;
unsigned int offset;
std::vector<Cursor> cursors;
std::vector<Util::ReferenceCount<SelectItem> > items;
};
}
#endif
diff --git a/include/gui/tab-container.h b/include/r-tech1/gui/tab-container.h
similarity index 96%
rename from include/gui/tab-container.h
rename to include/r-tech1/gui/tab-container.h
index e1469aa2..bbad3aec 100644
--- a/include/gui/tab-container.h
+++ b/include/r-tech1/gui/tab-container.h
@@ -1,134 +1,134 @@
#ifndef _gui_tab_container_h
#define _gui_tab_container_h
#include <string>
#include <vector>
#include <exception>
#include "widget.h"
-#include "util/file-system.h"
-#include "util/pointer.h"
-#include "util/graphics/gradient.h"
+#include "r-tech1/file-system.h"
+#include "r-tech1/pointer.h"
+#include "r-tech1/graphics/gradient.h"
namespace Gui{
class TabItem{
public:
TabItem();
TabItem(const std::string &);
virtual ~TabItem();
virtual void inspectBody(const Graphics::Bitmap &);
virtual void act(const Font &) = 0;
virtual void draw(const Font &, const Graphics::Bitmap &) = 0;
virtual inline void setName(const std::string & name) {
this->name = name;
}
virtual inline const std::string & getName() const {
return this->name;
}
virtual inline bool isActive() const {
return this->active;
}
virtual inline void toggleActive() {
this->active = !this->active;
}
protected:
bool active;
std::string name;
};
class DummyTab: public TabItem{
public:
DummyTab(const std::string &);
virtual ~DummyTab();
virtual void act(const Font &);
virtual void draw(const Font &, const Graphics::Bitmap &);
};
class TabContainer: public Widget {
public:
TabContainer();
TabContainer(const TabContainer &);
virtual ~TabContainer();
// copy
TabContainer & operator=(const TabContainer &);
// Logic
virtual void act(const Font &);
// Render
using Widget::render;
virtual void render(const Graphics::Bitmap &);
virtual void draw(const Font &, const Graphics::Bitmap &);
// Add
virtual void add(Util::ReferenceCount<TabItem> tab);
// Remove
virtual Util::ReferenceCount<TabItem> remove(unsigned int tab);
void removeCurrent();
// Set size of Content Body Area
virtual void setBodySize(int width, int height);
// Next
virtual void next();
// Previous
virtual void previous();
// Go to specific tab
virtual void gotoTab(unsigned int index);
// Go to specific tab by name
virtual void gotoTabByName(const std::string &);
// Get the Content Body Area
virtual inline const Graphics::Bitmap & getBody() const {
return this->body;
}
-
+
// Empty
virtual inline bool empty() const {
return this->tabs.empty();
}
// Get current tab
virtual inline Util::ReferenceCount<TabItem> getCurrent() {
return this->tabs[current];
}
class NoSuchTab: public std::exception{
public:
NoSuchTab(const std::string &) throw();
NoSuchTab(unsigned int index) throw();
virtual ~NoSuchTab() throw();
virtual const char* what() const throw();
private:
std::string name;
};
virtual unsigned int findTab(const std::string &);
virtual Util::ReferenceCount<TabItem> getTab(unsigned int index);
virtual Util::ReferenceCount<TabItem> getByName(const std::string &);
-
+
protected:
virtual void drawTabs(const Font &, const Graphics::Bitmap &);
std::vector< Util::ReferenceCount<TabItem> > tabs;
unsigned int current;
// Body defaults to 640x480
Graphics::Bitmap body;
/*! Gradient for active selection */
Effects::Gradient * activeColor;
};
}
#endif
diff --git a/include/gui/tabbed-box.h b/include/r-tech1/gui/tabbed-box.h
similarity index 100%
rename from include/gui/tabbed-box.h
rename to include/r-tech1/gui/tabbed-box.h
diff --git a/include/gui/timer.h b/include/r-tech1/gui/timer.h
similarity index 100%
rename from include/gui/timer.h
rename to include/r-tech1/gui/timer.h
diff --git a/include/gui/widget.h b/include/r-tech1/gui/widget.h
similarity index 93%
rename from include/gui/widget.h
rename to include/r-tech1/gui/widget.h
index 230b8f0d..8e9c6d85 100644
--- a/include/gui/widget.h
+++ b/include/r-tech1/gui/widget.h
@@ -1,86 +1,86 @@
#ifndef _paintown_gui_widget_h
#define _paintown_gui_widget_h
#include "rectarea.h"
#include "coordinate.h"
-#include "util/graphics/bitmap.h"
-#include "util/pointer.h"
+#include "r-tech1/graphics/bitmap.h"
+#include "r-tech1/pointer.h"
namespace Graphics{
class Bitmap;
}
class Token;
class Font;
namespace Gui{
struct ColorInfo{
ColorInfo();
Graphics::Color body;
int bodyAlpha;
Graphics::Color border;
int borderAlpha;
};
/*! Trasformations for widgets
* Eventually this could be expanded and used as something to perform changes on widgets but for now it remains to be just a place holder
* ************************
* radius - rounded corners
*/
class Transformations{
public:
Transformations();
Transformations(const Transformations &);
virtual ~Transformations();
Transformations & operator=(const Transformations &);
virtual inline void setRadius(double radius){
- this->radius = radius;
+ this->radius = radius;
}
virtual inline double getRadius() const{
- return this->radius;
+ return this->radius;
}
private:
double radius;
};
class Widget{
public:
Widget();
Widget( const Widget &);
virtual ~Widget();
// copy
Widget &operator=( const Widget &);
void setCoordinates(const Token * token);
void setColors(const Token * token);
void setTransforms(const Token * token);
//! New position data
Coordinate location;
//! Colors
ColorInfo colors;
//! Transformations
Transformations transforms;
// Logic
virtual void act(const Font &)=0;
// Render
virtual void render(const Graphics::Bitmap &) = 0;
/* default behavior is just to call render() */
virtual void render(const Graphics::Bitmap &, const Font &);
// draw box
static void drawBox(int radius, int x1, int y1, int x2, int y2, const Gui::ColorInfo &, const Graphics::Bitmap &);
protected:
Util::ReferenceCount<Graphics::Bitmap> checkWorkArea(const Graphics::Bitmap & parent);
};
}
#endif
diff --git a/include/init.h b/include/r-tech1/init.h
similarity index 100%
rename from include/init.h
rename to include/r-tech1/init.h
diff --git a/include/input/allegro5/joystick.h b/include/r-tech1/input/allegro5/joystick.h
similarity index 92%
rename from include/input/allegro5/joystick.h
rename to include/r-tech1/input/allegro5/joystick.h
index ec8c47f1..9e1a95d3 100644
--- a/include/input/allegro5/joystick.h
+++ b/include/r-tech1/input/allegro5/joystick.h
@@ -1,36 +1,36 @@
#ifndef _paintown_allegro5_joystick_h
#define _paintown_allegro5_joystick_h
-#include "../joystick.h"
-#include "util/pointer.h"
+#include "r-tech1/input/joystick.h"
+#include "r-tech1/pointer.h"
#include <string>
struct ALLEGRO_EVENT_QUEUE;
class ButtonMapping;
class Allegro5Joystick: public Joystick {
public:
virtual void poll();
virtual int getDeviceId() const;
virtual std::string getName() const;
virtual Key getKey(int button);
virtual int getButton(Key key);
virtual std::map<int, std::map<int, double> > getCurrentAxisValues() const;
virtual ~Allegro5Joystick();
friend class Joystick;
protected:
void axis(int stick, int axis, float position);
void buttonDown(int button);
void buttonUp(int button);
Allegro5Joystick(int id);
int id;
ALLEGRO_EVENT_QUEUE * queue;
Util::ReferenceCount<ButtonMapping> buttons;
};
#endif
diff --git a/include/input/input-manager.h b/include/r-tech1/input/input-manager.h
similarity index 98%
rename from include/input/input-manager.h
rename to include/r-tech1/input/input-manager.h
index a3f52d7b..a68c3f6c 100644
--- a/include/input/input-manager.h
+++ b/include/r-tech1/input/input-manager.h
@@ -1,316 +1,316 @@
#ifndef _paintown_input_manager
#define _paintown_input_manager
#include <vector>
#include <algorithm>
#include "input.h"
#include "input-map.h"
#include "input-source.h"
-#include "util/funcs.h"
-#include "util/pointer.h"
-#include "util/events.h"
+#include "r-tech1/funcs.h"
+#include "r-tech1/pointer.h"
+#include "r-tech1/events.h"
#include "keyboard.h"
#include "joystick.h"
-#include "util/exceptions/exception.h"
+#include "r-tech1/exceptions/exception.h"
class Configuration;
class InputSource;
template <class Output>
class InputHandler{
public:
InputHandler(){
}
virtual ~InputHandler(){
}
virtual void press(const Output & out, Keyboard::unicode_t unicode) = 0;
virtual void release(const Output & out, Keyboard::unicode_t unicode) = 0;
};
/* handles keyboard/joystick/whatever input during the game */
class InputManager{
public:
/* main has one instance of this and thats it.
* should the janitor have the reference instead?
*/
friend int paintown_main(int, char**);
friend int main(int, char **);
/* returns true if any input device is activated (keys pressed, joystick button */
static bool anyInput();
// static std::vector<Input::PaintownInput> getInput(const Configuration & configuration, const int facing);
static void poll();
/*
static void enableBufferInput();
static void disableBufferInput();
*/
static void waitForKeys(int key1, int key2, const InputSource & source);
static void waitForKeys(int key1, const InputSource & source);
static int readKey();
static void waitForClear();
static void deferResizeEvents(bool defer);
static const std::map<int, Util::ReferenceCount<Joystick> > & getJoysticks();
/*
template <class X>
static void observeKeyboard(InputMap<X> & input){
manager->keyboard.addObserver(InputMap<X>::observeKey, &input);
}
template <class X>
static void unObserveKeyboard(InputMap<X> & input){
manager->keyboard.removeObserver(InputMap<X>::observeKey, &input);
}
*/
static std::vector<Keyboard::unicode_t> readText(){
return manager->keyboard.readText();
}
template <typename X>
static std::vector<Keyboard::unicode_t> readText(InputMap<X> & input, typename InputMap<X>::Output & output){
return manager->_readText(input, output);
}
#if 0
template <typename X>
static typename InputMap<X>::Output getMap(InputMap<X> & input){
if (manager){
return manager->_getMap(input);
}
/* just crash hard.. who cares */
throw Exception::Base(__FILE__, __LINE__);
/* make the compiler happy about returning something */
return *(typename InputMap<X>::Output*)1;
}
#endif
template <typename X>
static typename std::vector<typename InputMap<X>::InputEvent> getEvents(InputMap<X> & input, const InputSource & source){
return manager->_getEvents(input, source);
}
template <typename X>
static void handleEvents(InputMap<X> & input, const InputSource & source, InputHandler<X> & handler){
typename std::vector<typename InputMap<X>::InputEvent> events = getEvents(input, source);
for (typename std::vector<typename InputMap<X>::InputEvent>::iterator it = events.begin(); it != events.end(); it++){
const typename InputMap<X>::InputEvent & event = *it;
if (event.enabled){
handler.press(event.out, event.unicode);
} else {
handler.release(event.out, event.unicode);
}
}
}
template <typename X>
static bool pressed(InputMap<X> & input, const InputSource & source, X out){
if (manager){
return manager->_pressed(input, source, out);
}
return false;
}
/* wait for a key to be released
* really this waits for all inputs that would result in `out'
* being generated to stop.
*/
template <typename X>
static void waitForRelease(InputMap<X> & input, const InputSource & source, X out){
while (InputManager::pressed(input, source, out)){
Util::rest(1);
InputManager::poll();
}
}
template <typename X>
static void waitForPress(InputMap<X> & input, const InputSource & source, X out){
while (!InputManager::pressed(input, source, out)){
Util::rest(1);
InputManager::poll();
}
}
template <typename X>
static void captureInput(InputMap<X> & input){
manager->_captureInput(input);
}
template <typename X>
static void releaseInput(InputMap<X> & input){
manager->_releaseInput(input);
}
protected:
InputManager();
virtual ~InputManager();
virtual bool _anyInput();
virtual int _readKey();
// virtual std::vector<Input::PaintownInput> _getInput(const Configuration & configuration, const int facing);
template <typename X>
void _captureInput(InputMap<X> & input){
capture = (void*) &input;
}
template <typename X>
void _releaseInput(InputMap<X> & input){
if (capture == (void*) &input){
capture = 0;
}
}
template <typename X>
std::vector<Keyboard::unicode_t> _readText(InputMap<X> & input, typename InputMap<X>::Output & output){
std::vector<Keyboard::unicode_t> text;
std::vector<Keyboard::KeyData> all = keyboard.readData();
for (std::vector<Keyboard::KeyData>::iterator it = all.begin(); it != all.end(); it++){
const Keyboard::KeyData & data = *it;
KeyState<X> * state = input.getState(data.key);
if (state != NULL && output[state->out]){
text.push_back(data.unicode);
}
}
return text;
}
void removeDuplicates(std::vector<int> & storage){
std::vector<int> output;
int last = -1;
for (std::vector<int>::iterator it = storage.begin(); it != storage.end(); it++){
if (*it != last){
output.push_back(*it);
last = *it;
}
}
storage = output;
}
template <typename X>
typename std::vector<typename InputMap<X>::InputEvent> _getEvents(InputMap<X> & input, const InputSource & source){
/* FIXME: get events from the source */
std::vector<typename InputMap<X>::InputEvent> events;
if (capture != NULL && capture != &input){
return events;
}
if (source.useKeyboard()){
const std::vector<typename Keyboard::KeyData> & buffer = keyboard.getBufferedKeys();
for (std::vector<Keyboard::KeyData>::const_iterator it = buffer.begin(); it != buffer.end(); it++){
const Keyboard::KeyData & data = *it;
Util::ReferenceCount<KeyState<X> > state = input.getState(data.key);
if (state != NULL){
events.push_back(typename InputMap<X>::InputEvent(state->out, data.unicode, data.enabled));
}
}
}
for (std::vector<int>::const_iterator it = source.getJoystick().begin(); it != source.getJoystick().end(); it++){
int config = *it;
if (config >= 0 && config < (int) joysticks.size()){
Util::ReferenceCount<Joystick> joystick = joysticks[config];
if (joystick != NULL){
const std::vector<typename Joystick::Event> & joystickEvents = joystick->getEvents();
for (std::vector<Joystick::Event>::const_iterator it = joystickEvents.begin(); it != joystickEvents.end(); it++){
Joystick::Event event = *it;
Util::ReferenceCount<JoystickState<X> > state = input.getJoystickState(event.key);
if (state != NULL){
events.push_back(typename InputMap<X>::InputEvent(state->out, -1, event.enabled));
}
}
}
}
}
return events;
}
#if 0
template <typename X>
typename InputMap<X>::Output _getMap(InputMap<X> & input){
typename InputMap<X>::Output output;
if (capture != 0 && capture != &input){
return output;
}
std::vector<int> all_keys;
keyboard.readKeys(all_keys);
keyboard.readBufferedKeys(all_keys);
// all_keys.insert(all_keys.end(), bufferedKeys.begin(), bufferedKeys.end());
// all_keys.insert(all_keys.end(), keyboard.currentKeys().begin(), keyboard.currentKeys.end());
std::sort(all_keys.begin(), all_keys.end());
removeDuplicates(all_keys);
// std::unique(all_keys.begin(), all_keys.end());
// bufferedKeys.clear();
input.read(all_keys, &output);
/*
if (joystick != NULL){
JoystickInput all_joystick = joystick->readAll();
input.read(all_joystick, &output);
}
*/
/* just bumps an internal counter */
input.update();
return output;
}
#endif
template <typename X>
bool _pressed(InputMap<X> & input, const InputSource & source, X result){
/* FIXME: use the input source, luke */
if (capture != 0 && capture != &input){
return false;
}
std::vector<int> all_keys;
keyboard.readKeys(all_keys);
// all_keys.insert(all_keys.end(), bufferedKeys.begin(), bufferedKeys.end());
std::sort(all_keys.begin(), all_keys.end());
removeDuplicates(all_keys);
// bufferedKeys.clear();
bool out = false;
out = input.pressed(all_keys, result);
/*
if (joystick != NULL){
JoystickInput all_joystick = joystick->readAll();
out |= input.pressed(all_joystick, result);
}
*/
return out;
}
virtual void _poll();
protected:
void installJoysticks();
void checkJoysticks();
private:
static InputManager * manager;
void * capture;
std::map<int, Util::ReferenceCount<Joystick> > joysticks;
Keyboard keyboard;
Util::EventManager eventManager;
// std::vector<int> bufferedKeys;
// bool bufferKeys;
};
#endif
diff --git a/include/input/input-map.h b/include/r-tech1/input/input-map.h
similarity index 99%
rename from include/input/input-map.h
rename to include/r-tech1/input/input-map.h
index 1e34b253..7218ecfb 100644
--- a/include/input/input-map.h
+++ b/include/r-tech1/input/input-map.h
@@ -1,318 +1,318 @@
#ifndef _paintown_input_map_h
#define _paintown_input_map_h
#include <map>
#include <vector>
#include "joystick.h"
#include "keyboard.h"
-#include "util/pointer.h"
+#include "r-tech1/pointer.h"
#include <iostream>
template <typename X>
struct KeyState{
KeyState(unsigned int delay, bool block, X out, unsigned int last_read):
delay(delay),
block(block),
out(out),
pressed(false),
last_read(0),
seen(0){
}
unsigned int delay;
bool block;
X out;
bool pressed;
unsigned int last_read;
unsigned int seen;
};
/* cant typedef a template'd struct so we have to copy/paste the definition
*/
template <typename X>
struct JoystickState{
JoystickState(unsigned int delay, bool block, X out, unsigned int last_read):
delay(delay),
block(block),
out(out),
pressed(false),
last_read(0),
seen(0){
}
unsigned int delay;
bool block;
X out;
bool pressed;
unsigned int last_read;
unsigned int seen;
};
/* maps a raw input device (keyboard, joystick, etc.) to some user-defined type
* the template parameter, X, is that user-defined type
*/
template <typename X>
class InputMap{
public:
typedef std::map<X, bool> Output;
struct InputEvent{
InputEvent(const X & out, Keyboard::unicode_t unicode, bool enabled):
out(out),
unicode(unicode),
enabled(enabled){
}
InputEvent(const InputEvent & input):
out(input.out),
unicode(input.unicode),
enabled(input.enabled){
}
InputEvent(){
}
bool operator[](const X & is) const {
return this->out == is;
}
X out;
Keyboard::unicode_t unicode;
bool enabled;
};
InputMap():
last_read(0){
}
InputMap(const InputMap & copy){
copyMap(copy);
}
InputMap & operator=(const InputMap & copy){
copyMap(copy);
return *this;
}
void copyMap(const InputMap & copy){
key_states.clear();
for (typename std::map<Keyboard::KeyType, Util::ReferenceCount<KeyState<X> > >::const_iterator it = copy.key_states.begin(); it != copy.key_states.end(); it++){
if (it->second != NULL){
key_states[(*it).first] = Util::ReferenceCount<KeyState<X> >(new KeyState<X>(*(*it).second));
}
}
joy_states.clear();
for (typename std::map<typename Joystick::Key, Util::ReferenceCount<JoystickState<X> > >::const_iterator it = copy.joy_states.begin(); it != copy.joy_states.end(); it++){
if (it->second != NULL){
joy_states[(*it).first] = Util::ReferenceCount<JoystickState<X> >(new JoystickState<X>(*(*it).second));
}
}
last_read = copy.last_read;
}
virtual ~InputMap(){
/* map will clear itself, reference count will delete all objects */
}
/* key: the keyboard key to recognize, something like KEY_A
* delay: time before successive keys are recognized (if held down)
* block: if true then the key must be released before it will
* be recognized again. false allows repetition.
* out: user defined value to set if this key is pressed
*/
void set(Keyboard::KeyType key, int delay, bool block, X out){
key_states[key] = Util::ReferenceCount<KeyState<X> >(new KeyState<X>(delay, block, out, last_read));
}
void set(Keyboard::KeyType key, X out){
set(key, 0, false, out);
}
/* change an existing key */
void update(Keyboard::KeyType key, int delay, bool block, X out){
if (key_states[key] != 0){
key_states[key]->delay = delay;
key_states[key]->block = block;
key_states[key]->out = out;
}
}
/* mostly the same stuff but for joysticks.
*/
void set(typename Joystick::Key key, int delay, bool block, X out){
joy_states[key] = Util::ReferenceCount<JoystickState<X> >(new JoystickState<X>(delay, block, out, last_read));
}
void set(typename Joystick::Key key, X out){
set(key, 0, false, out);
}
static std::vector<X> getAllPressed(const Output & output){
std::vector<X> out;
for (typename Output::const_iterator it = output.begin(); it != output.end(); it++){
if ((*it).second){
out.push_back((*it).first);
}
}
return out;
}
/*
static void observeKey(const Keyboard::KeyData & data, void * self){
InputMap<X> * me = (InputMap<X>*) self;
KeyState<X> * state = state = getState(data.key);
if (state != NULL){
events.push_back(InputEvent(state->out, data.unicode, data.enabled));
}
}
*/
bool pressed(const std::vector<int> & keys, X out){
for (std::vector<int>::const_iterator it = keys.begin(); it != keys.end(); it++){
Keyboard::KeyType key = *it;
Util::ReferenceCount<KeyState<X> > state = key_states[key];
if (state != NULL){
if (state->out == out){
return true;
}
}
}
return false;
}
virtual Util::ReferenceCount<KeyState<X> > getState(int key){
return key_states[key];
}
virtual Util::ReferenceCount<JoystickState<X> > getJoystickState(Joystick::Key key){
return joy_states[key];
}
void read(const std::vector<int> & keys, Output * output){
for (std::vector<int>::const_iterator it = keys.begin(); it != keys.end(); it++){
Keyboard::KeyType key = *it;
Util::ReferenceCount<KeyState<X> > state = getState(key);
if (state != NULL){
bool use = false;
// Global::debug(0) << "read " << key << " last read is " << state->last_read << " my last read is " << last_read << std::endl;
if (state->block){
if (last_read - state->last_read > 1){
use = true;
}
} else if (last_read - state->last_read > 1 || state->seen >= state->delay){
use = true;
state->seen = 0;
} else {
state->seen += 1;
}
state->last_read = last_read;
// state->last_read = last_read;
(*output)[state->out] = use;
}
}
}
const std::map<Keyboard::KeyType, Util::ReferenceCount<KeyState<X> > > & getKeyStates() const {
return key_states;
}
/* called by the input manager when the map is read */
void update(){
last_read += 1;
}
void read(const JoystickInput & joystick, Output * output){
#define do_joy(field, key) if (joystick.field){\
Util::ReferenceCount<JoystickState<X> > state = joy_states[Joystick::key];\
doJoyState(state, output);\
}
do_joy(down, Down);
do_joy(up, Up);
do_joy(left, Left);
do_joy(right, Right);
do_joy(button1, Button1);
do_joy(button2, Button2);
do_joy(button3, Button3);
do_joy(button4, Button4);
do_joy(button5, Button5);
do_joy(button6, Button6);
do_joy(quit, Quit);
do_joy(start, Start);
/*
if (joystick.up){
JoystickState<X> * state = joy_states[Joystick::Up];
doJoyState(state);
}
if (joystick.down){
JoystickState<X> * state = joy_states[Joystick::Down];
doJoyState(state);
}
*/
#undef do_joy
}
bool pressed(const JoystickInput & joystick, X out){
#define do_joy(field, key) if (joystick.field){\
Util::ReferenceCount<JoystickState<X> > state = joy_states[Joystick::key];\
if (state != 0 && state->out == out){\
return true;\
}\
}
do_joy(down, Down);
do_joy(up, Up);
do_joy(left, Left);
do_joy(right, Right);
do_joy(button1, Button1);
do_joy(button2, Button2);
do_joy(button3, Button3);
do_joy(button4, Button4);
do_joy(button5, Button5);
do_joy(button6, Button6);
do_joy(quit, Quit);
do_joy(start, Start);
#undef do_joy
return false;
}
protected:
void doJoyState(JoystickState<X> * state, Output * output){
if (state != NULL){
bool use = false;
if (state->block){
if (last_read - state->last_read > 1){
use = true;
}
} else if (last_read - state->last_read > 1 || state->seen >= state->delay){
use = true;
state->seen = 0;
} else {
state->seen += 1;
}
state->last_read = last_read;
// state->last_read = last_read;
(*output)[state->out] = use;
}
}
private:
std::map<Keyboard::KeyType, Util::ReferenceCount<KeyState<X> > > key_states;
std::map<typename Joystick::Key, Util::ReferenceCount<JoystickState<X> > > joy_states;
unsigned int last_read;
};
#endif
diff --git a/include/input/input-source.h b/include/r-tech1/input/input-source.h
similarity index 100%
rename from include/input/input-source.h
rename to include/r-tech1/input/input-source.h
diff --git a/include/input/input.h b/include/r-tech1/input/input.h
similarity index 100%
rename from include/input/input.h
rename to include/r-tech1/input/input.h
diff --git a/include/input/joystick.h b/include/r-tech1/input/joystick.h
similarity index 100%
rename from include/input/joystick.h
rename to include/r-tech1/input/joystick.h
diff --git a/include/input/keyboard.h b/include/r-tech1/input/keyboard.h
similarity index 100%
rename from include/input/keyboard.h
rename to include/r-tech1/input/keyboard.h
diff --git a/include/input/linux_joystick.h b/include/r-tech1/input/linux_joystick.h
similarity index 100%
rename from include/input/linux_joystick.h
rename to include/r-tech1/input/linux_joystick.h
diff --git a/include/input/text-input.h b/include/r-tech1/input/text-input.h
similarity index 100%
rename from include/input/text-input.h
rename to include/r-tech1/input/text-input.h
diff --git a/include/language-string.h b/include/r-tech1/language-string.h
similarity index 100%
rename from include/language-string.h
rename to include/r-tech1/language-string.h
diff --git a/include/loading.h b/include/r-tech1/loading.h
similarity index 100%
rename from include/loading.h
rename to include/r-tech1/loading.h
diff --git a/include/main.h b/include/r-tech1/main.h
similarity index 100%
rename from include/main.h
rename to include/r-tech1/main.h
diff --git a/include/memory.h b/include/r-tech1/memory.h
similarity index 100%
rename from include/memory.h
rename to include/r-tech1/memory.h
diff --git a/include/menu/action_speed.h b/include/r-tech1/menu/action_speed.h
similarity index 100%
rename from include/menu/action_speed.h
rename to include/r-tech1/menu/action_speed.h
diff --git a/include/menu/actionfactory.h b/include/r-tech1/menu/actionfactory.h
similarity index 100%
rename from include/menu/actionfactory.h
rename to include/r-tech1/menu/actionfactory.h
diff --git a/include/menu/font-info.h b/include/r-tech1/menu/font-info.h
similarity index 77%
rename from include/menu/font-info.h
rename to include/r-tech1/menu/font-info.h
index 9a120aea..6727a61c 100644
--- a/include/menu/font-info.h
+++ b/include/r-tech1/menu/font-info.h
@@ -1,170 +1,170 @@
#ifndef _paintown_font_info_h
#define _paintown_font_info_h
#include <string>
-#include "util/file-system.h"
-#include "util/font.h"
+#include "r-tech1/file-system.h"
+#include "r-tech1/font.h"
class Font;
namespace Menu{
/*
* class FontInfo
* class RelativeFontInfo
* class AbsoluteFontInfo
*/
class AbsoluteFontInfo;
class RelativeFontInfo;
class FontInfo {
public:
- FontInfo();
- virtual ~FontInfo();
-
+ FontInfo();
+ virtual ~FontInfo();
+
/*
- inline void set(const Filesystem::RelativePath & font, int width, int height){
- this->font = font;
- this->width = width;
- this->height = height;
- }
+ inline void set(const Filesystem::RelativePath & font, int width, int height){
+ this->font = font;
+ this->width = width;
+ this->height = height;
+ }
*/
-
- virtual const Font & get() const = 0;
- virtual const Font & get(const Font & next) const = 0;
+
+ virtual const Font & get() const = 0;
+ virtual const Font & get(const Font & next) const = 0;
virtual const FontInfo & get(const FontInfo & next) const = 0;
virtual bool operator==(const FontInfo & who) const = 0;
virtual bool operator==(const AbsoluteFontInfo & who) const = 0;
virtual bool operator==(const RelativeFontInfo & who) const = 0;
-
+
/*
- inline void setFont(const Filesystem::RelativePath & font){
- this->font = font;
- }
+ inline void setFont(const Filesystem::RelativePath & font){
+ this->font = font;
+ }
*/
virtual std::string getName() const = 0;
- // virtual const Filesystem::RelativePath getFont(const FontInfo & next) const;
-
+ // virtual const Filesystem::RelativePath getFont(const FontInfo & next) const;
+
/*
- inline void setWidth(int width){
- this->width = width;
- }
+ inline void setWidth(int width){
+ this->width = width;
+ }
*/
- virtual const int getWidth(const FontInfo & next) const = 0;
-
+ virtual const int getWidth(const FontInfo & next) const = 0;
+
/*
- inline void setHeight(int height){
- this->height = height;
- }
+ inline void setHeight(int height){
+ this->height = height;
+ }
*/
- virtual const int getHeight(const FontInfo & next) const = 0;
-
- virtual const bool empty() const = 0;
+ virtual const int getHeight(const FontInfo & next) const = 0;
+
+ virtual const bool empty() const = 0;
};
template <class Type>
class PathFontInfo: public FontInfo {
public:
PathFontInfo(const Type & path, int width, int height):
path(path),
width(width),
height(height){
}
virtual const Font & get() const {
return Font::getFont(path, width, height);
}
virtual const Font & get(const Font & next) const {
return get();
}
virtual const FontInfo & get(const FontInfo & next) const {
return *this;
}
virtual std::string getName() const {
return path.getFilename().path();
}
-
+
virtual const int getWidth(const FontInfo & next) const {
return width;
}
virtual const int getHeight(const FontInfo & next) const {
return height;
}
-
+
virtual const bool empty() const {
return path.path().empty();
}
protected:
Type path;
int width;
int height;
};
class RelativeFontInfo: public PathFontInfo<Filesystem::RelativePath> {
public:
RelativeFontInfo(const Filesystem::RelativePath & path, int width, int height):
PathFontInfo<Filesystem::RelativePath>(path, width, height){
}
using FontInfo::operator==;
virtual bool operator==(const FontInfo & who) const;
virtual bool operator==(const AbsoluteFontInfo & who) const;
virtual bool operator==(const RelativeFontInfo & who) const;
};
class AbsoluteFontInfo: public PathFontInfo<Filesystem::AbsolutePath> {
public:
AbsoluteFontInfo(const Filesystem::AbsolutePath & path, int width, int height):
PathFontInfo<Filesystem::AbsolutePath>(path, width, height){
}
using FontInfo::operator==;
virtual bool operator==(const FontInfo & who) const;
virtual bool operator==(const AbsoluteFontInfo & who) const;
virtual bool operator==(const RelativeFontInfo & who) const;
};
/*
class RelativeFontInfo: public FontInfo {
public:
RelativeFontInfo();
RelativeFontInfo(const Filesystem::RelativePath & font, int width, int height);
virtual const bool empty() const;
private:
Filesystem::RelativePath font;
int width;
int height;
};
class AbsoluteFontInfo: public FontInfo {
public:
AbsoluteFontInfo(const Filesystem::AbsolutePath & font, int width, int height);
using FontInfo::get;
virtual const Font & get() const;
virtual const Font & get(const Font & next) const;
virtual std::string getName() const;
protected:
Filesystem::AbsolutePath font;
int width;
int height;
};
*/
}
#endif
diff --git a/include/menu/menu-exception.h b/include/r-tech1/menu/menu-exception.h
similarity index 100%
rename from include/menu/menu-exception.h
rename to include/r-tech1/menu/menu-exception.h
diff --git a/include/menu/menu.h b/include/r-tech1/menu/menu.h
similarity index 100%
rename from include/menu/menu.h
rename to include/r-tech1/menu/menu.h
diff --git a/include/menu/menu_action.h b/include/r-tech1/menu/menu_action.h
similarity index 100%
rename from include/menu/menu_action.h
rename to include/r-tech1/menu/menu_action.h
diff --git a/include/menu/menu_option.h b/include/r-tech1/menu/menu_option.h
similarity index 100%
rename from include/menu/menu_option.h
rename to include/r-tech1/menu/menu_option.h
diff --git a/include/menu/optionfactory.h b/include/r-tech1/menu/optionfactory.h
similarity index 100%
rename from include/menu/optionfactory.h
rename to include/r-tech1/menu/optionfactory.h
diff --git a/include/menu/options.h b/include/r-tech1/menu/options.h
similarity index 100%
rename from include/menu/options.h
rename to include/r-tech1/menu/options.h
diff --git a/include/message-queue.h b/include/r-tech1/message-queue.h
similarity index 100%
rename from include/message-queue.h
rename to include/r-tech1/message-queue.h
diff --git a/include/messages.h b/include/r-tech1/messages.h
similarity index 100%
rename from include/messages.h
rename to include/r-tech1/messages.h
diff --git a/include/nacl/network-system.h b/include/r-tech1/nacl/network-system.h
similarity index 100%
rename from include/nacl/network-system.h
rename to include/r-tech1/nacl/network-system.h
diff --git a/include/network/chat.h b/include/r-tech1/network/chat.h
similarity index 100%
rename from include/network/chat.h
rename to include/r-tech1/network/chat.h
diff --git a/include/network/irc-client.h b/include/r-tech1/network/irc-client.h
similarity index 100%
rename from include/network/irc-client.h
rename to include/r-tech1/network/irc-client.h
diff --git a/include/network/irc.h b/include/r-tech1/network/irc.h
similarity index 100%
rename from include/network/irc.h
rename to include/r-tech1/network/irc.h
diff --git a/include/network/network.h b/include/r-tech1/network/network.h
similarity index 100%
rename from include/network/network.h
rename to include/r-tech1/network/network.h
diff --git a/include/parameter.h b/include/r-tech1/parameter.h
similarity index 100%
rename from include/parameter.h
rename to include/r-tech1/parameter.h
diff --git a/include/pointer.h b/include/r-tech1/pointer.h
similarity index 100%
rename from include/pointer.h
rename to include/r-tech1/pointer.h
diff --git a/include/reader.h b/include/r-tech1/reader.h
similarity index 100%
rename from include/reader.h
rename to include/r-tech1/reader.h
diff --git a/include/regex.h b/include/r-tech1/regex.h
similarity index 100%
rename from include/regex.h
rename to include/r-tech1/regex.h
diff --git a/include/resource.h b/include/r-tech1/resource.h
similarity index 100%
rename from include/resource.h
rename to include/r-tech1/resource.h
diff --git a/include/scale.h b/include/r-tech1/scale.h
similarity index 100%
rename from include/scale.h
rename to include/r-tech1/scale.h
diff --git a/include/scale2x.h b/include/r-tech1/scale2x.h
similarity index 100%
rename from include/scale2x.h
rename to include/r-tech1/scale2x.h
diff --git a/include/sound/allegro5/sound.h b/include/r-tech1/sound/allegro5/sound.h
similarity index 100%
rename from include/sound/allegro5/sound.h
rename to include/r-tech1/sound/allegro5/sound.h
diff --git a/include/sound/audio.h b/include/r-tech1/sound/audio.h
similarity index 100%
rename from include/sound/audio.h
rename to include/r-tech1/sound/audio.h
diff --git a/include/sound/music-exception.h b/include/r-tech1/sound/music-exception.h
similarity index 100%
rename from include/sound/music-exception.h
rename to include/r-tech1/sound/music-exception.h
diff --git a/include/sound/music-player.h b/include/r-tech1/sound/music-player.h
similarity index 100%
rename from include/sound/music-player.h
rename to include/r-tech1/sound/music-player.h
diff --git a/include/sound/music-renderer.h b/include/r-tech1/sound/music-renderer.h
similarity index 100%
rename from include/sound/music-renderer.h
rename to include/r-tech1/sound/music-renderer.h
diff --git a/include/sound/music.h b/include/r-tech1/sound/music.h
similarity index 100%
rename from include/sound/music.h
rename to include/r-tech1/sound/music.h
diff --git a/include/sound/sound.h b/include/r-tech1/sound/sound.h
similarity index 91%
rename from include/sound/sound.h
rename to include/r-tech1/sound/sound.h
index 363e0f6a..e7cc098e 100644
--- a/include/sound/sound.h
+++ b/include/r-tech1/sound/sound.h
@@ -1,84 +1,78 @@
#ifndef _paintown_sound_h
#define _paintown_sound_h
#include <string>
-#include "util/exceptions/load_exception.h"
+#include "r-tech1/exceptions/load_exception.h"
-#ifdef USE_SDL
-#include "sdl/sound.h"
-#endif
-#ifdef USE_ALLEGRO
-#include "allegro/sound.h"
-#endif
#ifdef USE_ALLEGRO5
#include "allegro5/sound.h"
#endif
struct SAMPLE;
namespace Storage{
class File;
}
/* a sound! */
class Sound{
public:
Sound();
/* create from wav file (riff header + pcm) */
Sound(const char * data, int length);
/* load from abstract file */
Sound(Storage::File & file);
/* load from path */
Sound(const std::string & path);
Sound(const Sound & copy);
/* do any global initialization necessary */
static void initialize();
/* cleanup */
static void uninitialize();
Sound & operator=( const Sound & rhs );
void play();
void play(double volume, int pan);
void playLoop();
void stop();
void setVolume(double volume);
virtual ~Sound();
/* global frequency to use */
// static const int FREQUENCY = 22050;
struct SoundInfo{
SoundInfo():
frequency(44100),
channels(2),
format(0){
}
int frequency;
int channels;
/* format is mostly for SDL */
int format;
};
static SoundInfo Info;
protected:
void loadFromMemory(const char * data, int length);
/* scale to the configuration sound level */
static double scale(double in);
void destroy();
// SAMPLE * my_sound;
SoundData data;
/* reference counting */
int * own;
};
#endif
diff --git a/include/system.h b/include/r-tech1/system.h
similarity index 100%
rename from include/system.h
rename to include/r-tech1/system.h
diff --git a/include/thread.h b/include/r-tech1/thread.h
similarity index 100%
rename from include/thread.h
rename to include/r-tech1/thread.h
diff --git a/include/timedifference.h b/include/r-tech1/timedifference.h
similarity index 100%
rename from include/timedifference.h
rename to include/r-tech1/timedifference.h
diff --git a/include/timer.h b/include/r-tech1/timer.h
similarity index 100%
rename from include/timer.h
rename to include/r-tech1/timer.h
diff --git a/include/token.h b/include/r-tech1/token.h
similarity index 100%
rename from include/token.h
rename to include/r-tech1/token.h
diff --git a/include/token_exception.h b/include/r-tech1/token_exception.h
similarity index 100%
rename from include/token_exception.h
rename to include/r-tech1/token_exception.h
diff --git a/include/tokenreader.h b/include/r-tech1/tokenreader.h
similarity index 100%
rename from include/tokenreader.h
rename to include/r-tech1/tokenreader.h
diff --git a/include/utf.h b/include/r-tech1/utf.h
similarity index 100%
rename from include/utf.h
rename to include/r-tech1/utf.h
diff --git a/include/version.h b/include/r-tech1/version.h
similarity index 100%
rename from include/version.h
rename to include/r-tech1/version.h
diff --git a/include/xenon/xenon.h b/include/r-tech1/xenon/xenon.h
similarity index 100%
rename from include/xenon/xenon.h
rename to include/r-tech1/xenon/xenon.h
diff --git a/scons/helpers.py b/scons/helpers.py
new file mode 100644
index 00000000..25f0a6af
--- /dev/null
+++ b/scons/helpers.py
@@ -0,0 +1,39 @@
+def read_cmake_list(name):
+ """
+ Read a cmake files list and return a dictionary with each cmake variable
+ matched to a list of filenames.
+
+ This makes it easy to add/remove files, as only the cmake list needs to be
+ modified and scons will automatically pick up the changes.
+ """
+ lists = {}
+ current = []
+ reading = False
+ for line in open(name):
+ if line.startswith("set("):
+ current = []
+ name = line[4:].strip()
+ lists[name] = current
+ reading = True
+ else:
+ if reading:
+ # Stop reading files once we hit a line like 'file.cpp)'
+ if line.strip("\t\r\n").endswith(")"):
+ reading = False
+ path = line.strip("( )\t\r\n")
+ if path:
+ current.append(path)
+ return lists
+
+def findFile(name):
+ return findDirectory(name)
+
+def findDirectory(name):
+ import os.path
+ where = '.'
+ # just try 5 directories
+ for i in xrange(0, 6):
+ if os.path.exists("%s/%s" % (where, name)):
+ return "%s/%s" % (where, name)
+ where = os.path.join(where, '..')
+ raise Exception("Could not find the %s directory" % name)
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 253cb405..430f6ccd 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,114 +1,104 @@
# -------------------------------------------------------
# util cmake build script for paintown.
# Written by: juvinious
# Modified by: kazzmir
# -------------------------------------------------------
# -------------------------------------------------------
# Source directories containing all the necessary .cpp files
# -------------------------------------------------------
set(UTIL_SRC
argument.cpp
configuration.cpp
network/network.cpp
network/chat.cpp
network/irc.cpp
token.cpp
resource.cpp
tokenreader.cpp
timedifference.cpp
debug.cpp
timer.cpp
init.cpp
utf.cpp
console.cpp
input/keyboard.cpp
loading.cpp
messages.cpp
graphics/bitmap.cpp
graphics/image.cpp
events.cpp
font.cpp
font_factory.cpp
graphics/fire.cpp
ftalleg.cpp
funcs.cpp
directory.cpp
file-system.cpp
graphics/gradient.cpp
ebox.cpp
regex.cpp
language-string.cpp
thread.cpp
input/input.cpp
input/text-input.cpp
input/input-manager.cpp
input/input-source.cpp
input/joystick.cpp
input/allegro5/joystick.cpp
-input/allegro/allegro-joystick.cpp
-input/sdl/joystick.cpp
-input/psp/joystick.cpp
-input/wii/joystick.cpp
-graphics/sdl/hqx.cpp
-graphics/sdl/xbr.cpp
xenon/xenon.cpp
lz4/lz4.c
system.cpp
version.cpp
compress.cpp
message-queue.cpp
input/linux_joystick.cpp
exceptions/load_exception.cpp
windows/funcs.cpp
windows/system.cpp
nacl/module.cpp
nacl/network-system.cpp
exceptions/exception.cpp
menu/actionfactory.cpp
menu/action_speed.cpp
menu/menu.cpp
menu/font-info.cpp
menu/menu_action.cpp
menu/menu_option.cpp
menu/options.cpp
menu/optionfactory.cpp
gui/animation.cpp
gui/box.cpp
gui/container.cpp
gui/context-box.cpp
gui/coordinate.cpp
gui/cutscene.cpp
gui/fadetool.cpp
gui/lineedit.cpp
gui/list.cpp
gui/rectarea.cpp
gui/popup-box.cpp
gui/scroll-list.cpp
gui/select-list.cpp
gui/tab-container.cpp
gui/tabbed-box.cpp
gui/timer.cpp
gui/widget.cpp
sound/sound.cpp
sound/audio.cpp
sound/music-player.cpp
sound/music-renderer.cpp
sound/music.cpp
../system/timer.cpp
-../system/sdl/timer.cpp
-../system/sdl/init.cpp
-../system/allegro/timer.cpp
-../system/allegro/init.cpp
../system/allegro5/timer.cpp
../system/allegro5/init.cpp)
# -------------------------------------------------------
# Include directory
# -------------------------------------------------------
#include_directories(include include/internal)
# -------------------------------------------------------
# module
# -------------------------------------------------------
add_library (util_module ${UTIL_SRC})
diff --git a/src/SConscript b/src/SConscript
index 6a90571d..b9e894cd 100644
--- a/src/SConscript
+++ b/src/SConscript
@@ -1,134 +1,61 @@
Import('env', 'options')
-import helpers
+from scons import helpers
import os.path
def tryKey(hashx, key, default):
try:
return hashx[key]
except KeyError:
return default
-def useSDL(options):
- return tryKey(options, 'sdl', False)
-
-def useAllegro(options):
- return tryKey(options, 'allegro', False)
-
def useNetwork(options):
return tryKey(options, 'networking', False)
def utilLibrary(env):
- modules = helpers.read_cmake_list(helpers.findFile('src/util/CMakeLists.txt'))
+ modules = helpers.read_cmake_list(helpers.findFile('src/CMakeLists.txt'))
source = []
for module in modules:
source.append(modules[module])
- return env.StaticLibrary('paintown-util', source)
+ return env.StaticLibrary('util', source)
def minizipLibrary(env):
- return env.SConscript('zip/SConscript', exports = ['env'])
+ return env.SConscript('libs/zip/SConscript', exports = ['env'])
def gmeLibrary(env):
use = env
- return SConscript('sound/gme/SConscript', exports = ['use'])
+ return SConscript('libs/gme/SConscript', exports = ['use'])
def lzmaLibrary7z(env):
use = env
- return SConscript('7z/SConscript', exports = ['use'])
+ return SConscript('libs/7z/SConscript', exports = ['use'])
def sflLibrary(env):
use = env
- return SConscript('sfl/SConscript', exports = ['use'])
+ return SConscript('libs/sfl/SConscript', exports = ['use'])
def pcreLibrary(env):
pcreEnv = env.Clone()
env = pcreEnv
- return env.SConscript('pcre/SConstruct', exports = ['env'])
+ return env.SConscript('libs/pcre/SConstruct', exports = ['env'])
def dumbLibrary(env):
dumbEnv = env.Clone()
env = dumbEnv
- return env.SConscript('sound/dumb/SConscript', exports = ['env'])
-
-def sdlImageLibrary(env):
- image = env.Clone()
- image.Append(CPPDEFINES = ['LOAD_PNG', 'LOAD_PCX', 'LOAD_GIF'])
- source = Split("""
-graphics/sdl/image/IMG.c
-graphics/sdl/image/IMG_jpg.c
-graphics/sdl/image/IMG_pnm.c
-graphics/sdl/image/IMG_xpm.c
-graphics/sdl/image/IMG_ImageIO.c
-graphics/sdl/image/IMG_lbm.c
-graphics/sdl/image/IMG_tga.c
-graphics/sdl/image/IMG_xv.c
-graphics/sdl/image/IMG_bmp.c
-graphics/sdl/image/IMG_pcx.c
-graphics/sdl/image/IMG_tif.c
-graphics/sdl/image/IMG_xxx.c
-graphics/sdl/image/IMG_gif.c
-graphics/sdl/image/IMG_png.c
-graphics/sdl/image/IMG_savepng.c
-graphics/sdl/image/IMG_xcf.c
-""")
-
- return image.StaticLibrary('image',source)
-
-def sdlMixerLibrary(env):
- use = env
- return SConscript('sound/sdl/mixer/SConscript', exports = ['use'])
-
-def sprigLibrary(env):
- sprig = env.Clone()
- source = Split("""
-graphics/sdl/sprig/SPG_extended.c
-graphics/sdl/sprig/SPG_misc.c
-graphics/sdl/sprig/SPG_polygon.c
-graphics/sdl/sprig/SPG_primitives.c
-graphics/sdl/sprig/SPG_rotation.c
-graphics/sdl/sprig/SPG_surface.c
-""")
-
- return sprig.StaticLibrary('sprig', source)
-
-def stretchLibrary(env):
- stretch = env.Clone()
- # FIXME: asm has some bug in it, try to fix it later
- stretch.Append(CPPDEFINES = ['SDL_STRETCH_DISABLE_ASM'])
- source = Split("""
-graphics/sdl/stretch/sdlstretch.c
-graphics/sdl/stretch/sdlstretchcode.c
-""")
-
- return stretch.StaticLibrary('stretch', source)
+ return env.SConscript('libs/dumb/SConscript', exports = ['env'])
def hawknlLibrary(env):
hawkEnv = env.Clone()
env = hawkEnv
# if isOSX():
# env.Append(CPPDEFINES = 'MACOSX')
- return env.SConscript('network/hawknl/SConscript', exports = ['env'])
-
-def alGifLibrary(env):
- gif = env.Clone()
- source = Split("""
-graphics/allegro/gif/algif.c
-graphics/allegro/gif/gif.c
-graphics/allegro/gif/lzw.c
-""")
- return gif.StaticLibrary('algif', source)
+ return env.SConscript('libs/hawknl/SConscript', exports = ['env'])
all = [utilLibrary(env), minizipLibrary(env), gmeLibrary(env), lzmaLibrary7z(env), sflLibrary(env), pcreLibrary(env), dumbLibrary(env)]
-if useSDL(options):
- all.extend([sdlImageLibrary(env), sprigLibrary(env), sdlMixerLibrary(env), stretchLibrary(env)])
-
-if useAllegro(options):
- all.append(alGifLibrary(env))
-
if useNetwork(options):
all.append(hawknlLibrary(env))
Return('all')
diff --git a/src/argument.cpp b/src/argument.cpp
index 2f0b4593..0385df00 100644
--- a/src/argument.cpp
+++ b/src/argument.cpp
@@ -1,21 +1,21 @@
-#include "argument.h"
+#include "r-tech1/argument.h"
#include <string.h>
using std::vector;
using std::string;
bool Argument::isArg(const string & what) const {
std::vector<std::string> match = keywords();
for (std::vector<std::string>::iterator it = match.begin(); it != match.end(); it++){
if (strcasecmp(it->c_str(), what.c_str()) == 0){
return true;
}
}
return false;
}
Argument::~Argument(){
}
ArgumentAction::~ArgumentAction(){
}
diff --git a/src/compress.cpp b/src/compress.cpp
index 76d387b0..63e2b069 100644
--- a/src/compress.cpp
+++ b/src/compress.cpp
@@ -1,33 +1,33 @@
#ifdef USE_ALLEGRO
#include <allegro.h>
#endif
-#include "compress.h"
-#include "memory.h"
-#include "debug.h"
+#include "r-tech1/compress.h"
+#include "r-tech1/memory.h"
+#include "r-tech1/debug.h"
namespace Compress{
void testCompression(unsigned char * input, int length){
#ifdef USE_ALLEGRO
unsigned char * data = new unsigned char[length*2];
PACKFILE_VTABLE table = Memory::makeTable();
Memory::memory memory(data, length*2);
PACKFILE * pack = pack_fopen_vtable(&table, &memory);
LZSS_PACK_DATA * lzss = create_lzss_pack_data();
int r = lzss_write(pack, lzss, length, input, 1);
if (r != 0){
// printf("lzss error %d: %s!\n", r, ustrerror(errno));
exit(-1);
}
free_lzss_pack_data(lzss);
pack_fclose(pack);
Global::debug(0) << "Compressed " << length << " to " << memory.getSize() << " ratio is " << ((double)memory.getSize() / length) << std::endl;
delete[] data;
#endif
}
}
diff --git a/src/configuration.cpp b/src/configuration.cpp
index b946e624..bd3a0074 100644
--- a/src/configuration.cpp
+++ b/src/configuration.cpp
@@ -1,1009 +1,1009 @@
-#include "configuration.h"
-#include "input/keyboard.h"
-#include "exceptions/load_exception.h"
-#include "tokenreader.h"
-#include "token.h"
-#include "file-system.h"
-#include "input/input.h"
-#include "debug.h"
+#include "r-tech1/configuration.h"
+#include "r-tech1/input/keyboard.h"
+#include "r-tech1/exceptions/load_exception.h"
+#include "r-tech1/tokenreader.h"
+#include "r-tech1/token.h"
+#include "r-tech1/file-system.h"
+#include "r-tech1/input/input.h"
+#include "r-tech1/debug.h"
#include <sstream>
#include <fstream>
#include <stdlib.h>
#include <string>
#include <map>
#ifdef USE_SDL
#if SDL_VERSION_ATLEAST(1, 3, 0)
static const std::string INPUT_TYPE = "SDL1.3";
#else
static const std::string INPUT_TYPE = "SDL";
#endif
#endif
#ifdef USE_ALLEGRO
static const std::string INPUT_TYPE = "Allegro";
#endif
#ifdef USE_ALLEGRO5
static const std::string INPUT_TYPE = "Allegro5";
#endif
bool Configuration::save = true;
Util::ReferenceCount<Token> Configuration::data;
/* text that appears in the config file */
#define define_config(n,str) static const char * config_##n = str
define_config(attack1, "attack1");
define_config(attack2, "attack2");
define_config(attack3, "attack3");
define_config(attack4, "attack4");
define_config(attack5, "attack5");
define_config(attack6, "attack6");
define_config(configuration, "configuration");
define_config(cooperative, "cooperative");
// define_config(current_game, "current-game");
define_config(down, "down");
define_config(free_for_all, "free-for-all");
define_config(fullscreen, "fullscreen");
define_config(game_speed, "game-speed");
define_config(invincible, "invincible");
define_config(jump, "jump");
define_config(quit, "quit");
define_config(keyboard_configuration, "keyboard-configuration");
define_config(input, "input");
define_config(joystick_configuration, "joystick-configuration");
define_config(left, "left");
define_config(lives, "lives");
define_config(menu_font, "menu-font");
define_config(menu_font_width, "menu-font-width");
define_config(menu_font_height, "menu-font-height");
define_config(npc_buddies, "npc-buddies");
define_config(number, "number");
define_config(play_mode, "play-mode");
define_config(right, "right");
define_config(screen_size, "screen-size");
define_config(sound, "sound");
define_config(music, "music");
define_config(up, "up");
define_config(quality_filter, "quality-filter");
define_config(fps, "frames-per-second");
define_config(language, "language");
define_config(mugen_motif, "mugen-motif");
/* version of the game: 3.3, 3.4, 4.24 */
define_config(version, "version");
#undef def_config
using namespace std;
static const int InvalidKey = 0;
static const Joystick::Key InvalidJoystick = Joystick::Invalid;
/* don't save the configuration while loading it */
class Disable{
public:
Disable(){
last = Configuration::getSave();
Configuration::disableSave();
}
~Disable(){
Configuration::setSave(last);
}
bool last;
};
/* FIXME: move this to some utils module */
static std::vector<std::string> split(std::string str, char splitter){
std::vector<std::string> strings;
size_t next = str.find(splitter);
while (next != std::string::npos){
strings.push_back(str.substr(0, next));
str = str.substr(next+1);
next = str.find(splitter);
}
if (str != ""){
strings.push_back(str);
}
return strings;
}
static std::string last(const vector<string> & what){
return what.at(what.size() - 1);
}
/* Create a token that contains the entire path.
* path = "foo/bar/baz"
* out = (foo (bar (baz)))
*/
static Token * createToken(const string & path){
vector<string> paths = split(path, '/');
Token * out = new Token();
Token * current = out;
for (vector<string>::iterator it = paths.begin(); it != paths.end(); it++){
current->addToken(new Token(*it, false));
if (paths.end() - it > 1){
Token * next = new Token();
current->addToken(next);
current = next;
}
}
return out;
}
/* Create a token with the given path and give it a value */
template <class Value>
static Token * createToken(const string & path, const Value & value){
Token * out = createToken(path);
*out << value;
return out;
}
template <class Value, class Value2>
static Token * createToken(const string & path, const Value & value, const Value2 & value2){
Token * out = createToken(path);
*out << value;
*out << value2;
return out;
}
/* remove a path if it exists */
static void removeToken(Token * data, const std::string & path){
Token * found = data->findToken(path);
/* See if the token already exists. If it does then remove it from its
* parent and add a new token to the parent with the updated value.
*/
if (found != NULL){
Token * parent = found->getParent();
parent->removeToken(found);
}
}
static void updateToken(Token * data, const std::string & path, Token * add){
if (data == NULL){
delete add;
}
Token * found = data->findToken(path);
/* See if the token already exists. If it does then remove it from its
* parent and add a new token to the parent with the updated value.
*/
if (found != NULL){
Token * parent = found->getParent();
parent->removeToken(found);
parent->addToken(add);
} else {
const vector<string> paths = split(path, '/');
Token * start = data;
for (unsigned int index = 1; index < paths.size() - 1; index++){
string where = paths[index];
Token * next = start->findToken(string("_/") + where);
if (next == NULL){
ostringstream out;
bool first = true;
for (int from = index; from < paths.size(); from++){
if (!first){
out << "/";
}
out << paths[from];
first = false;
}
/* If we run out of found paths then create a token with an empty
* value for the unfound paths we have so far and call updateToken
* again. This time the entire path will be there
* so the 'found = ...' logic will work.
*/
start->addToken(createToken(out.str(), string("")));
updateToken(data, path, add);
return;
} else {
start = next;
}
}
/* It probably shouldn't be possible to get here. If the entire
* path was there then the findToken() logic above should have worked.
*/
start->addToken(add);
}
}
template <class Value>
static void updateToken(Token * data, const string & path, const Value & value){
if (data == NULL){
return;
}
updateToken(data, path, createToken(last(split(path, '/')), value));
}
void Configuration::setProperty(const string & name, const string & value){
updateToken(getRawData(), string(config_configuration) + "/" + name, value);
saveConfiguration();
}
static Token * getPropertyX(Token * data, const std::string & path){
return data->findToken(string(config_configuration) + "/" + path);
}
template <class Out>
static Out getPropertyX(Token * data, const std::string & path, const Out & defaultValue){
if (data == NULL){
return defaultValue;
}
Out out;
if (data->match(string(config_configuration) + "/" + path, out)){
return out;
}
updateToken(data, string(config_configuration) + "/" + path, defaultValue);
return defaultValue;
}
void Configuration::setDefaultKeys(int config){
/* Set the keys token to an empty value */
ostringstream path;
path << config_input << "/" << config << "/keys";
setProperty(path.str(), createToken("keys"));
/* Call the get methods to reset the defaults */
int ignore;
ignore = getRight(config);
ignore = getLeft(config);
ignore = getUp(config);
ignore = getDown(config);
ignore = getAttack1(config);
ignore = getAttack2(config);
ignore = getAttack3(config);
ignore = getAttack4(config);
ignore = getAttack5(config);
ignore = getAttack6(config);
ignore = getJump(config);
}
/* hopefully this is only used right before setting all the values
* since the key mappings are bogus in here'
*/
Configuration::Configuration(){
}
Configuration::Configuration(const Configuration & config){
menuFont = config.menuFont;
}
Configuration & Configuration::operator=(const Configuration & config){
Disable disable;
setMenuFont(config.getMenuFont());
return *this;
}
-
+
Configuration::~Configuration(){
}
Util::ReferenceCount<Menu::FontInfo> Configuration::getMenuFont(){
return menuFont;
}
bool Configuration::hasMenuFont(){
return menuFont != NULL;
}
void Configuration::setMenuFont(const Util::ReferenceCount<Menu::FontInfo> & info){
menuFont = info;
saveConfiguration();
}
void Configuration::setMenuFontWidth(int x){
setProperty(config_menu_font_width, x);
saveConfiguration();
}
int Configuration::getMenuFontWidth(){
return getProperty(config_menu_font_width, 24);
}
void Configuration::setMenuFontHeight(int x){
setProperty(config_menu_font_height, x);
saveConfiguration();
}
int Configuration::getMenuFontHeight(){
return getProperty(config_menu_font_height, 24);
}
static string joystickKeyName(Joystick::Key key){
switch (key){
case Joystick::Up: return "up";
case Joystick::Down: return "down";
case Joystick::Left: return "left";
case Joystick::Right: return "right";
case Joystick::Button1: return "button1";
case Joystick::Button2: return "button2";
case Joystick::Button3: return "button3";
case Joystick::Button4: return "button4";
case Joystick::Button5: return "button5";
case Joystick::Button6: return "button6";
case Joystick::Start: return "start";
case Joystick::Quit: return "quit";
case Joystick::Invalid: return "invalid";
}
return "?";
}
static string removeQuotes(string input){
size_t find = input.find('"');
while (find != string::npos){
input.erase(find, 1);
}
return input;
}
static string joystickPath(Joystick::Key key, int config, const std::string & name){
ostringstream base;
base << config_configuration << "/" << config_input << "/" << INPUT_TYPE << "/";
base << "joystick" << "/" << config << "/";
base << removeQuotes(name) << "/" << joystickKeyName(key);
return base.str();
}
void Configuration::setCustomButton(Joystick::Key key, int config, const std::string & name, int button){
if (key != Joystick::Invalid){
std::string base = joystickPath(key, config, name);
removeToken(getRawData(), base);
updateToken(getRawData(), base + "/button", button);
saveConfiguration();
}
}
bool Configuration::getCustomButton(Joystick::Key key, int config, const std::string & name, int & button){
return getRawData()->match(joystickPath(key, config, name) + "/button", button);
}
bool Configuration::getCustomAxis(Joystick::Key key, int config, const std::string & name, int & stick, int & axis, double & low, double & high){
std::string base = joystickPath(key, config, name);
return getRawData()->match(base + "/stick", stick) &&
getRawData()->match(base + "/axis", axis) &&
getRawData()->match(base + "/low", low) &&
getRawData()->match(base + "/high", high);
}
void Configuration::setCustomAxis(Joystick::Key key, int config, const string & name, int stick, int axis, double low, double high){
if (key != Joystick::Invalid){
std::string base = joystickPath(key, config, name);
removeToken(getRawData(), base);
updateToken(getRawData(), base + "/stick", stick);
updateToken(getRawData(), base + "/axis", axis);
updateToken(getRawData(), base + "/low", low);
updateToken(getRawData(), base + "/high", high);
saveConfiguration();
}
}
void Configuration::setKey(int config, const string & name, int value){
if (value != InvalidKey){
ostringstream path;
path << config_configuration << "/" << config_input << "/" << INPUT_TYPE << "/" << config << "/keys/" << name;
updateToken(getRawData(), path.str(), value);
saveConfiguration();
}
}
void Configuration::setRight(int config, int i){
setKey(config, "right", i);
}
void Configuration::setLeft(int config, int i){
setKey(config, "left", i);
}
void Configuration::setUp(int config, int i){
setKey(config, "up", i);
}
void Configuration::setDown(int config, int i){
setKey(config, "down", i);
}
void Configuration::setAttack1(int config, int i){
setKey(config, "attack1", i);
}
void Configuration::setAttack2(int config, int i){
setKey(config, "attack2", i);
}
void Configuration::setAttack3(int config, int i){
setKey(config, "attack3", i);
}
void Configuration::setAttack4(int config, int i){
setKey(config, "attack4", i);
}
void Configuration::setAttack5(int config, int i){
setKey(config, "attack5", i);
}
void Configuration::setAttack6(int config, int i){
setKey(config, "attack6", i);
}
void Configuration::setJump(int config, int i){
setKey(config, "jump", i);
}
int Configuration::getKey(int config, const string & name, int defaultValue){
ostringstream path;
path << config_input << "/" << INPUT_TYPE << "/" << config << "/keys/" << name;
return getProperty(path.str(), defaultValue);
}
/* this nonsense is just to convert a regular integer into an enum */
/*
static Configuration::JoystickInput intToJoystick(int a){
switch (a){
case Joystick::Up : return Joystick::Up;
case Joystick::Down : return Joystick::Down;
case Joystick::Left : return Joystick::Left;
case Joystick::Right : return Joystick::Right;
case Joystick::Button1 : return Joystick::Button1;
case Joystick::Button2 : return Joystick::Button2;
case Joystick::Button3 : return Joystick::Button3;
case Joystick::Button4 : return Joystick::Button4;
case Joystick::Button5 : return Joystick::Button5;
case Joystick::Button6 : return Joystick::Button6;
case Joystick::Start : return Joystick::Start;
case Joystick::Quit : return Joystick::Quit;
}
return Joystick::Invalid;
}
*/
/*
Configuration::JoystickInput Configuration::getJoystickKey(int config, const string & name, JoystickInput defaultValue){
ostringstream path;
path << config_input << "/" << config << "/joystick/" << name;
return intToJoystick(getProperty(path.str(), defaultValue));
}
*/
int Configuration::getRight(int config){
int normal = 0;
switch (config){
case 0: normal = Keyboard::Key_RIGHT; break;
case 1: normal = Keyboard::Key_L; break;
}
return getKey(config, "right", normal);
}
int Configuration::getLeft(int config){
int normal = 0;
switch (config){
case 0: normal = Keyboard::Key_LEFT; break;
case 1: normal = Keyboard::Key_J; break;
}
return getKey(config, "left", normal);
}
int Configuration::getUp(int config){
int normal = 0;
switch (config){
case 0: normal = Keyboard::Key_UP; break;
case 1: normal = Keyboard::Key_I; break;
}
return getKey(config, "up", normal);
}
int Configuration::getDown(int config){
int normal = 0;
switch (config){
case 0: normal = Keyboard::Key_DOWN; break;
case 1: normal = Keyboard::Key_COMMA; break;
}
return getKey(config, "down", normal);
}
int Configuration::getAttack1(int config){
int normal = 0;
switch (config){
case 0: normal = Keyboard::Key_A; break;
case 1: normal = Keyboard::Key_R; break;
}
return getKey(config, "attack1", normal);
}
int Configuration::getAttack2(int config){
int normal = 0;
switch (config){
case 0: normal = Keyboard::Key_S; break;
case 1: normal = Keyboard::Key_T; break;
}
return getKey(config, "attack2", normal);
}
int Configuration::getAttack3(int config){
int normal = 0;
switch (config){
case 0: normal = Keyboard::Key_D; break;
case 1: normal = Keyboard::Key_Y; break;
}
return getKey(config, "attack3", normal);
}
int Configuration::getAttack4(int config){
int normal = 0;
switch (config){
case 0: normal = Keyboard::Key_Z; break;
case 1: normal = Keyboard::Key_F; break;
}
return getKey(config, "attack4", normal);
}
int Configuration::getAttack5(int config){
int normal = 0;
switch (config){
case 0: normal = Keyboard::Key_X; break;
case 1: normal = Keyboard::Key_G; break;
}
return getKey(config, "attack5", normal);
}
int Configuration::getAttack6(int config){
int normal = 0;
switch (config){
case 0: normal = Keyboard::Key_C; break;
case 1: normal = Keyboard::Key_H; break;
}
return getKey(config, "attack6", normal);
}
int Configuration::getJump(int config){
int normal = 0;
switch (config){
case 0: normal = Keyboard::Key_SPACE; break;
case 1: normal = Keyboard::Key_B; break;
}
return getKey(config, "jump", normal);
}
/*
void Configuration::setJoystickKey(int config, const std::string & name, const Configuration::JoystickInput & what){
if (what != Joystick::Invalid){
ostringstream path;
path << config_configuration << "/" << config_input << "/" << config << "/joystick/" << name;
updateToken(data.raw(), path.str(), what);
saveConfiguration();
}
}
void Configuration::setJoystickRight(int config, Configuration::JoystickInput i){
setJoystickKey(config, "right", i);
}
void Configuration::setJoystickLeft(int config, Configuration::JoystickInput i){
setJoystickKey(config, "left", i);
}
void Configuration::setJoystickUp(int config, Configuration::JoystickInput i){
setJoystickKey(config, "up", i);
}
void Configuration::setJoystickDown(int config, Configuration::JoystickInput i){
setJoystickKey(config, "down", i);
}
void Configuration::setJoystickAttack1(int config, Configuration::JoystickInput i){
setJoystickKey(config, "attack1", i);
}
void Configuration::setJoystickAttack2(int config, Configuration::JoystickInput i){
setJoystickKey(config, "attack2", i);
}
void Configuration::setJoystickAttack3(int config, Configuration::JoystickInput i){
setJoystickKey(config, "attack3", i);
}
void Configuration::setJoystickAttack4(int config, Configuration::JoystickInput i){
setJoystickKey(config, "attack4", i);
}
void Configuration::setJoystickAttack5(int config, Configuration::JoystickInput i){
setJoystickKey(config, "attack5", i);
}
void Configuration::setJoystickAttack6(int config, Configuration::JoystickInput i){
setJoystickKey(config, "attack6", i);
}
void Configuration::setJoystickJump(int config, Configuration::JoystickInput i){
setJoystickKey(config, "jump", i);
}
void Configuration::setJoystickQuit(int config, Configuration::JoystickInput i){
setJoystickKey(config, "quit", i);
}
void Configuration::setJoystickStart(int config, Configuration::JoystickInput i){
setJoystickKey(config, "start", i);
}
Configuration::JoystickInput Configuration::getJoystickRight(int config){
return getJoystickKey(config, "right", Joystick::Right);
}
Configuration::JoystickInput Configuration::getJoystickLeft(int config){
return getJoystickKey(config, "left", Joystick::Left);
}
Configuration::JoystickInput Configuration::getJoystickUp(int config){
return getJoystickKey(config, "up", Joystick::Up);
}
Configuration::JoystickInput Configuration::getJoystickDown(int config){
return getJoystickKey(config, "down", Joystick::Down);
}
Configuration::JoystickInput Configuration::getJoystickAttack1(int config){
return getJoystickKey(config, "attack1", Joystick::Button1);
}
Configuration::JoystickInput Configuration::getJoystickAttack2(int config){
return getJoystickKey(config, "attack2", Joystick::Button2);
}
Configuration::JoystickInput Configuration::getJoystickAttack3(int config){
return getJoystickKey(config, "attack3", Joystick::Button3);
}
Configuration::JoystickInput Configuration::getJoystickAttack4(int config){
return getJoystickKey(config, "attack4", Joystick::Button4);
}
Configuration::JoystickInput Configuration::getJoystickAttack5(int config){
return getJoystickKey(config, "attack5", Joystick::Button5);
}
Configuration::JoystickInput Configuration::getJoystickAttack6(int config){
return getJoystickKey(config, "attack6", Joystick::Button6);
}
Configuration::JoystickInput Configuration::getJoystickJump(int config){
return getJoystickKey(config, "jump", Joystick::Button4);
}
Configuration::JoystickInput Configuration::getJoystickQuit(int config){
return getJoystickKey(config, "quit", Joystick::Quit);
}
Configuration::JoystickInput Configuration::getJoystickStart(int config){
return getJoystickKey(config, "start", Joystick::Start);
}
*/
/*
string Configuration::getCurrentGame(){
return getProperty(config_current_game, string(""));
}
/ * assumes the directory is readable and has a dir/dir.txt in it * /
void Configuration::setCurrentGame(const std::string & str){
setProperty(config_current_game, str);
saveConfiguration();
}
*/
void Configuration::disableSave(){
save = false;
}
void Configuration::setSave(bool what){
save = what;
}
bool Configuration::getSave(){
return save;
}
static Token * removeDuplicates(Token * token){
/* TODO */
return token;
}
Token * Configuration::getRawData(){
if (data == NULL){
loadConfigurations();
// data = new Token();
}
return data.raw();
}
void Configuration::loadConfigurations(){
data = new Token();
*data << config_configuration;
try{
Filesystem::AbsolutePath file = Storage::instance().configFile();
TokenReader tr;
Token * head = tr.readTokenFromFile(file.path());
if (*head != config_configuration){
throw LoadException(__FILE__, __LINE__, string("Config file ") + Storage::instance().configFile().path() + " does not use the configuration format" );
}
/* Store the entire configuration tree */
data = removeDuplicates(head->copy());
} catch (const LoadException & le){
Global::debug(0) << "Notice: Could not load configuration file " << Storage::instance().configFile().path() << ": " << le.getTrace() << endl;
} catch (const TokenException & t){
Global::debug(0) << "Notice: could not open configuration file '" << Storage::instance().configFile().path() << "': " << t.getTrace() << endl;
} catch (const Filesystem::NotFound & fail){
Global::debug(0) << "Notice: could not open configuration file '" << Storage::instance().configFile().path() << "': " << fail.getTrace() << endl;
}
}
void Configuration::saveConfiguration(){
if (!save){
return;
}
if (data != NULL){
ofstream out(Storage::instance().configFile().path().c_str(), ios::trunc | ios::out);
if (! out.bad()){
data->toString(out, string(""));
out << endl;
out.close();
}
}
}
Util::ReferenceCount<Menu::FontInfo> Configuration::menuFont;
bool Configuration::joystickEnabled = true;
int Configuration::getProperty(const std::string & path, int defaultValue){
return getPropertyX(getRawData(), path, defaultValue);
}
void Configuration::setProperty(const std::string & path, int value){
updateToken(getRawData(), string(config_configuration) + "/" + path, value);
saveConfiguration();
}
void Configuration::setProperty(const std::string & path, Token * value){
updateToken(getRawData(), string(config_configuration) + "/" + path, value);
saveConfiguration();
}
Token * Configuration::getProperty(const std::string & path){
return getPropertyX(getRawData(),path);
}
double Configuration::getProperty(const std::string & path, double defaultValue){
return getPropertyX(getRawData(), path, defaultValue);
}
void Configuration::setProperty(const std::string & path, double value){
updateToken(getRawData(), string(config_configuration) + "/" + path, value);
saveConfiguration();
}
bool Configuration::getProperty(const std::string & path, bool defaultValue){
return getPropertyX(getRawData(), path, defaultValue);
}
void Configuration::setProperty(const std::string & path, bool value){
updateToken(getRawData(), string(config_configuration) + "/" + path, value);
saveConfiguration();
}
std::string Configuration::getProperty(const std::string & path, const std::string & defaultValue){
return getPropertyX(getRawData(), path, defaultValue);
}
double Configuration::getGameSpeed(){
return getProperty(config_game_speed, 1.0);
}
void Configuration::setGameSpeed(double s){
setProperty(config_game_speed, s);
saveConfiguration();
}
bool Configuration::getInvincible(){
return getProperty(config_invincible, false);
}
void Configuration::setInvincible(bool i){
setProperty(config_invincible, i);
saveConfiguration();
}
bool Configuration::getFullscreen(){
/* Defaults for all configuration options */
#if defined(PS3) || defined(ANDROID) || defined(IPHONE)
return getProperty(config_fullscreen, true);
#else
return getProperty(config_fullscreen, false);
#endif
}
void Configuration::setFullscreen(bool f){
setProperty(config_fullscreen, f);
saveConfiguration();
}
int Configuration::getLives(){
return getProperty(config_lives, 4);
}
void Configuration::setLives(int l){
setProperty(config_lives, l);
saveConfiguration();
}
-
+
int Configuration::getNpcBuddies(){
return getProperty(config_npc_buddies, 1);
}
void Configuration::setNpcBuddies(int i){
setProperty(config_npc_buddies,i);
saveConfiguration();
}
Configuration::PlayMode Configuration::getPlayMode(){
string mode = getProperty("play-mode", string(config_cooperative));
if (mode == config_cooperative){
return Cooperative;
}
if (mode == config_free_for_all){
return FreeForAll;
}
return Cooperative;
}
void Configuration::setPlayMode(Configuration::PlayMode mode){
if (mode == Configuration::Cooperative){
setProperty("play-mode", string(config_cooperative));
} else if (mode == Configuration::FreeForAll){
setProperty("play-mode", string(config_free_for_all));
}
}
std::string Configuration::getLanguage(){
return getProperty("language", string());
}
void Configuration::setLanguage(const std::string & str){
setProperty("language", str);
saveConfiguration();
}
/* In case this is ever useful again */
/*
#ifdef MINPSPW
// default resolution for the psp is 480x272
int Configuration::screen_width = 480;
int Configuration::screen_height = 272;
#else
int Configuration::screen_width = 640;
int Configuration::screen_height = 480;
#endif
*/
#ifdef GCW0
static int DefaultWidth = 320;
static int DefaultHeight = 240;
#else
static int DefaultWidth = 640;
static int DefaultHeight = 480;
#endif
/* TODO: All the screen width/height stuff shares a lot of code. Refactor */
void Configuration::setScreenWidth(int i){
int width = DefaultWidth;
int height = DefaultHeight;
Token * screen = getPropertyX(getRawData(), config_screen_size);
if (screen != NULL){
try{
screen->view() >> width >> height;
} catch (const TokenException & fail){
}
}
width = i;
setProperty(config_screen_size, createToken(config_screen_size, width, height));
saveConfiguration();
}
int Configuration::getScreenWidth(){
int width = DefaultWidth;
int height = DefaultHeight;
Token * screen = getPropertyX(getRawData(), config_screen_size);
if (screen != NULL){
try{
screen->view() >> width >> height;
} catch (const TokenException & fail){
}
} else {
setProperty(config_screen_size, createToken(config_screen_size, width, height));
}
return width;
}
void Configuration::setScreenHeight(int i){
int width = DefaultWidth;
int height = DefaultHeight;
Token * screen = getPropertyX(getRawData(), config_screen_size);
if (screen != NULL){
try{
screen->view() >> width >> height;
} catch (const TokenException & fail){
}
}
height = i;
setProperty(config_screen_size, createToken(config_screen_size, width, height));
saveConfiguration();
}
int Configuration::getScreenHeight(){
int width = DefaultWidth;
int height = DefaultHeight;
Token * screen = getPropertyX(getRawData(), config_screen_size);
if (screen != NULL){
try{
screen->view() >> width >> height;
} catch (const TokenException & fail){
}
} else {
setProperty(config_screen_size, createToken(config_screen_size, width, height));
}
return height;
}
int Configuration::getSoundVolume(){
return getProperty(config_sound, 70);
}
void Configuration::setSoundVolume(int volume){
setProperty(config_sound, volume);
saveConfiguration();
}
int Configuration::getMusicVolume(){
return getProperty(config_music, 70);
}
void Configuration::setMusicVolume(int volume){
setProperty(config_music, volume);
saveConfiguration();
}
bool Configuration::isJoystickEnabled(){
return joystickEnabled;
}
void Configuration::setJoystickEnabled(bool enabled){
joystickEnabled = enabled;
saveConfiguration();
}
std::string Configuration::getQualityFilter(){
return getProperty(config_quality_filter, string("none"));
}
void Configuration::setQualityFilter(const std::string & filter){
setProperty(config_quality_filter, filter);
saveConfiguration();
}
int Configuration::getFps(){
return getProperty(config_fps, 50);
}
void Configuration::setFps(int what){
setProperty(config_fps, what);
saveConfiguration();
}
diff --git a/src/console.cpp b/src/console.cpp
index 3c866223..83e9b554 100644
--- a/src/console.cpp
+++ b/src/console.cpp
@@ -1,336 +1,336 @@
-#include "console.h"
-#include "graphics/bitmap.h"
-#include "font.h"
-#include "funcs.h"
-#include "file-system.h"
-#include "exceptions/exception.h"
-#include "input/input-manager.h"
-#include "input/input-map.h"
-#include "debug.h"
+#include "r-tech1/console.h"
+#include "r-tech1/graphics/bitmap.h"
+#include "r-tech1/font.h"
+#include "r-tech1/funcs.h"
+#include "r-tech1/file-system.h"
+#include "r-tech1/exceptions/exception.h"
+#include "r-tech1/input/input-manager.h"
+#include "r-tech1/input/input-map.h"
+#include "r-tech1/debug.h"
#include <string>
#include <sstream>
#include <string.h>
using namespace std;
namespace Console{
ConsoleEnd Console::endl;
static void doProcess(void * self){
Console * console = (Console*) self;
console->activate();
}
static void doToggle(void * self){
Console * console = (Console*) self;
console->toggle();
}
static void doPreviousHistory(void * self){
Console * console = (Console*) self;
console->previousHistory();
}
static void doNextHistory(void * self){
Console * console = (Console*) self;
console->nextHistory();
}
static void doTabComplete(void * self){
Console * console = (Console*) self;
console->tabComplete();
}
static void doPageUp(void * self){
Console * console = (Console*) self;
console->pageUp();
}
static void doPageDown(void * self){
Console * console = (Console*) self;
console->pageDown();
}
static void doFontIncrease(void * self){
Console * console = (Console*) self;
console->fontIncrease();
}
static void doFontDecrease(void * self){
Console * console = (Console*) self;
console->fontDecrease();
}
Console::Console(const int maxHeight, const Filesystem::RelativePath & font):
state(Closed),
maxHeight(maxHeight),
height(0),
font(font),
textHeight(15),
textWidth(15),
offset(0),
historyIndex(0),
pagePosition(-1){
textInput.addBlockingHandle(Keyboard::Key_TILDE, doToggle, this);
textInput.addBlockingHandle(Keyboard::Key_ENTER, doProcess, this);
textInput.addBlockingHandle(Keyboard::Key_UP, doPreviousHistory, this);
textInput.addBlockingHandle(Keyboard::Key_DOWN, doNextHistory, this);
textInput.addBlockingHandle(Keyboard::Key_TAB, doTabComplete, this);
textInput.addBlockingHandle(Keyboard::Key_PGUP, doPageUp, this);
textInput.addBlockingHandle(Keyboard::Key_PGDN, doPageDown, this);
textInput.addBlockingHandle(Keyboard::Key_EQUALS, doFontIncrease, this);
textInput.addBlockingHandle(Keyboard::Key_MINUS, doFontDecrease, this);
}
Console::~Console(){
textInput.disable();
}
/* attempt to complete the current text to a command */
void Console::tabComplete(){
string text = textInput.getText();
for (map<string, Util::ReferenceCount<Command> >::iterator it = commands.begin(); it != commands.end(); it++){
string what = it->first;
if (what.find(text) == 0){
Global::debug(0) << "Auto complete '" << what << "'" << std::endl;
textInput.setText(what);
return;
}
}
}
void Console::addCommand(const std::string & name, const Util::ReferenceCount<Command> & command){
if (command == NULL){
return;
}
if (commands[name] != 0){
Global::debug(0) << "Warning: duplicate console command for '" << name << "'" << std::endl;
}
commands[name] = command;
}
void Console::addAlias(const std::string & alias, const std::string & name){
addCommand(alias, commands[name]);
}
void Console::fontIncrease(){
textWidth += 1;
textHeight += 1;
}
void Console::fontDecrease(){
if (textWidth > 2){
textWidth -= 1;
}
if (textHeight > 2){
textHeight -= 1;
}
}
void Console::previousHistory(){
if (historyIndex < history.size()){
textInput.setText(history[historyIndex]);
historyIndex += 1;
}
}
void Console::nextHistory(){
if (historyIndex > 0){
historyIndex -= 1;
textInput.setText(history[historyIndex]);
} else {
textInput.setText(string());
}
}
static const int PAGE_MOVEMENT = 3;
void Console::pageUp(){
if (pagePosition == -1){
pagePosition = lines.size();
}
pagePosition -= PAGE_MOVEMENT;
if (pagePosition < PAGE_MOVEMENT){
pagePosition = PAGE_MOVEMENT;
}
}
void Console::pageDown(){
if (pagePosition != -1){
pagePosition += PAGE_MOVEMENT;
}
if (pagePosition >= (int) lines.size()){
pagePosition = -1;
}
}
void Console::act(){
double speed = 10.0;
switch (state){
case Closed : {
break;
}
case Open : {
break;
}
case Closing : {
int distance = height;
height -= (int)((double)distance / speed + 1.0);
if (height <= 0){
height = 0;
state = Closed;
}
break;
}
case Opening : {
int distance = maxHeight - height;
height += (int)((double)distance / speed + 1.0);
if (height >= maxHeight){
height = maxHeight;
state = Open;
}
break;
}
}
}
/*
static bool isChar(char c){
const char * letters = "abcdefghijklmnopqrstuvwxyz ,.";
return strchr(letters, c) != NULL;
}
*/
void Console::activate(){
if (textInput.getText() != ""){
process(textInput.getText());
}
textInput.clearInput();
}
bool Console::isActive() const {
return state == Open || state == Opening;
}
/* console input */
bool Console::doInput() {
if (state == Closed || state == Closing){
return false;
}
textInput.doInput();
return true;
}
void Console::draw(const Graphics::Bitmap & work){
int x = 3;
/* if we can show something */
if (height > 0){
Graphics::Bitmap::transBlender(0, 0, 0, 160);
work.translucent().rectangleFill(0, 0, work.getWidth(), height, Graphics::makeColor(200,0,0));
work.translucent().horizontalLine(0, height, work.getWidth(), Graphics::makeColor(200, 200, 200));
const Font & font = Font::getFont(getFont(), textWidth, textHeight);
int start = height - font.getHeight() * 2;
Graphics::Color white = Graphics::makeColor(255, 255, 255);
int position = 0;
if (pagePosition != -1){
position = lines.size() - pagePosition;
}
for (std::vector<std::string>::reverse_iterator i = lines.rbegin() + position; i != lines.rend() && start > 0; ++i){
std::string str = *i;
font.printf(x, start, white, work, str, 0);
start -= font.getHeight();
}
if (position != 0){
for (int x0 = 0; x0 < 5; x0++){
work.circleFill(x + x0 * 5, height - font.getHeight() - 2, 1, white);
}
}
font.printf(x, height - font.getHeight(), white, work, "> " + textInput.getText() + "|", 0);
}
}
void Console::toggle(){
switch (state){
case Open:
case Opening: {
state = Closing;
textInput.disable();
break;
}
case Closed:
case Closing: {
state = Opening;
textInput.enable();
break;
}
}
}
static vector<string> split(string str, char splitter){
vector<string> strings;
size_t next = str.find(splitter);
while (next != string::npos){
strings.push_back(str.substr(0, next));
str = str.substr(next+1);
next = str.find(splitter);
}
if (str != ""){
strings.push_back(str);
}
return strings;
}
/* do something with a command */
void Console::process(const string & command){
/* reset history index */
historyIndex = 0;
/* don't duplicate history */
if (history.size() == 0 || (history.size() > 0 && !(command == history[1]))){
history.push_front(command);
}
string start = command;
if (command.find(' ') != string::npos){
start = command.substr(0, command.find(' '));
}
const map<string, Util::ReferenceCount<Command> > & commandSet = commands;
if (commandSet.find(start) != commandSet.end()){
map<string, Util::ReferenceCount<Command> >::const_iterator found = commandSet.find(start);
addLine(found->second->act(command));
} else {
addLine("Unknown command '" + start + "'");
}
}
void Console::addLine(const std::string & line){
vector<string> each = split(line, '\n');
for (vector<string>::iterator it = each.begin(); it != each.end(); it++){
lines.push_back(*it);
}
}
Console & Console::operator<<(const ConsoleEnd & e){
return *this;
}
void Console::clear(){
lines.clear();
}
vector<Util::ReferenceCount<Command> > Console::getCommands() const {
vector<Util::ReferenceCount<Command> > out;
for (map<std::string, Util::ReferenceCount<Command> >::const_iterator it = commands.begin(); it != commands.end(); it++){
Util::ReferenceCount<Command> command = it->second;
if (command != NULL){
out.push_back(command);
}
}
return out;
}
}
diff --git a/src/debug.cpp b/src/debug.cpp
index dc628eef..17dc26ef 100644
--- a/src/debug.cpp
+++ b/src/debug.cpp
@@ -1,431 +1,431 @@
-#include "debug.h"
-#include "system.h"
+#include "r-tech1/debug.h"
+#include "r-tech1/system.h"
#include <iostream>
#include <fstream>
#include <string>
#include <stdio.h>
#ifdef ANDROID
#include <android/log.h>
#define ANDROID_LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, "paintown", __VA_ARGS__)
#endif
#ifdef NETWORK_DEBUG
#include <sys/socket.h>
#include <sys/types.h>
#include <string.h>
#include <arpa/inet.h>
#endif
using namespace std;
static int global_debug_level = 0;
namespace Global{
#ifdef ANDROID
android_ostream::android_ostream(bool enabled):
enabled(enabled){
}
android_ostream & operator<<(android_ostream & stream, const std::string & input){
stream.buffer << input;
return stream;
}
android_ostream & operator<<(android_ostream & stream, const char * input){
stream.buffer << input;
return stream;
}
android_ostream & operator<<(android_ostream & stream, const char input){
stream.buffer << input;
return stream;
}
android_ostream & operator<<(android_ostream & stream, const double input){
stream.buffer << input;
return stream;
}
android_ostream & operator<<(android_ostream & stream, const int input){
stream.buffer << input;
return stream;
}
android_ostream & operator<<(android_ostream & stream, const short int input){
stream.buffer << input;
return stream;
}
android_ostream & operator<<(android_ostream & stream, const short unsigned int input){
stream.buffer << input;
return stream;
}
android_ostream & operator<<(android_ostream & stream, const unsigned int input){
stream.buffer << input;
return stream;
}
android_ostream & operator<<(android_ostream & stream, const bool input){
stream.buffer << input;
return stream;
}
android_ostream & operator<<(android_ostream & stream, const long int input){
stream.buffer << input;
return stream;
}
android_ostream & operator<<(android_ostream & stream, const unsigned long int input){
stream.buffer << input;
return stream;
}
android_ostream & operator<<(android_ostream & stream, const void * input){
stream.buffer << input;
return stream;
}
android_ostream & operator<<(android_ostream & stream, std::ostream & (*f)(std::ostream &)){
if (stream.enabled){
ANDROID_LOGV("%s\n", stream.buffer.str().c_str());
}
stream.buffer.str("");
stream.buffer.rdbuf()->pubseekoff(0, ios_base::end, ios_base::out);
stream.buffer.clear();
return stream;
}
android_ostream android_ostream::stream;
static android_ostream nullcout(false);
#elif defined(WII) && defined(DEBUG)
wii_ostream::wii_ostream(bool enabled):
enabled(enabled){
}
wii_ostream & operator<<(wii_ostream & stream, const std::string & input){
stream.buffer << input;
return stream;
}
wii_ostream & operator<<(wii_ostream & stream, const char * input){
stream.buffer << input;
return stream;
}
wii_ostream & operator<<(wii_ostream & stream, const char input){
stream.buffer << input;
return stream;
}
wii_ostream & operator<<(wii_ostream & stream, const double input){
stream.buffer << input;
return stream;
}
wii_ostream & operator<<(wii_ostream & stream, const int input){
stream.buffer << input;
return stream;
}
wii_ostream & operator<<(wii_ostream & stream, uint64_t input){
stream.buffer << input;
return stream;
}
wii_ostream & operator<<(wii_ostream & stream, const short int input){
stream.buffer << input;
return stream;
}
wii_ostream & operator<<(wii_ostream & stream, const short unsigned int input){
stream.buffer << input;
return stream;
}
wii_ostream & operator<<(wii_ostream & stream, const unsigned int input){
stream.buffer << input;
return stream;
}
wii_ostream & operator<<(wii_ostream & stream, const bool input){
stream.buffer << input;
return stream;
}
wii_ostream & operator<<(wii_ostream & stream, const long int input){
stream.buffer << input;
return stream;
}
wii_ostream & operator<<(wii_ostream & stream, const unsigned long int input){
stream.buffer << input;
return stream;
}
wii_ostream & operator<<(wii_ostream & stream, const void * input){
stream.buffer << input;
return stream;
}
wii_ostream & operator<<(wii_ostream & stream, std::ostream & (*f)(std::ostream &)){
if (stream.enabled){
printf("%s\n", stream.buffer.str().c_str());
}
stream.buffer.str("");
stream.buffer.rdbuf()->pubseekoff(0, ios_base::end, ios_base::out);
stream.buffer.clear();
return stream;
}
wii_ostream wii_ostream::stream;
static wii_ostream nullcout(false);
#elif defined(NETWORK_DEBUG)
network_ostream::network_ostream(const std::string & host, int port, bool enabled):
host(host),
port(port),
enabled(enabled){
}
network_ostream & operator<<(network_ostream & stream, const std::string & input){
stream.buffer << input;
return stream;
}
network_ostream & operator<<(network_ostream & stream, const char * input){
stream.buffer << input;
return stream;
}
network_ostream & operator<<(network_ostream & stream, const char input){
stream.buffer << input;
return stream;
}
network_ostream & operator<<(network_ostream & stream, const double input){
stream.buffer << input;
return stream;
}
network_ostream & operator<<(network_ostream & stream, const int input){
stream.buffer << input;
return stream;
}
network_ostream & operator<<(network_ostream & stream, uint64_t input){
stream.buffer << input;
return stream;
}
network_ostream & operator<<(network_ostream & stream, const short int input){
stream.buffer << input;
return stream;
}
network_ostream & operator<<(network_ostream & stream, const short unsigned int input){
stream.buffer << input;
return stream;
}
network_ostream & operator<<(network_ostream & stream, const unsigned int input){
stream.buffer << input;
return stream;
}
network_ostream & operator<<(network_ostream & stream, const bool input){
stream.buffer << input;
return stream;
}
network_ostream & operator<<(network_ostream & stream, const long int input){
stream.buffer << input;
return stream;
}
#ifndef PS3
network_ostream & operator<<(network_ostream & stream, const unsigned long int input){
stream.buffer << input;
return stream;
}
#endif
network_ostream & operator<<(network_ostream & stream, const void * input){
stream.buffer << input;
return stream;
}
static void sendString(const std::string & host, int port, const std::string & data){
int gateway = socket(PF_INET, SOCK_STREAM, 0);
struct sockaddr_in address;
address.sin_family = AF_INET;
address.sin_port = htons(port);
address.sin_addr.s_addr = inet_addr(host.c_str());
memset(address.sin_zero, '\0', sizeof(address.sin_zero));
connect(gateway, (struct sockaddr*) &address, sizeof(address));
send(gateway, data.c_str(), data.size(), 0);
send(gateway, "\n", 1, 0);
close(gateway);
}
network_ostream & operator<<(network_ostream & stream, std::ostream & (*f)(std::ostream &)){
if (stream.enabled){
sendString(stream.host, stream.port, stream.buffer.str());
// printf("%s\n", stream.buffer.str().c_str());
}
stream.buffer.str("");
stream.buffer.rdbuf()->pubseekoff(0, ios_base::end, ios_base::out);
stream.buffer.clear();
return stream;
}
/* IP address and port are arbitrary */
network_ostream network_ostream::stream("192.168.1.100", 5670);
static network_ostream nullcout("", 0, false);
#else
class nullstreambuf_t: public std::streambuf {
public:
nullstreambuf_t():std::streambuf(){
}
};
static nullstreambuf_t nullstreambuf;
class nullcout_t: public std::ostream {
public:
nullcout_t():std::ostream(&nullstreambuf){
}
};
static nullcout_t nullcout;
#endif
#ifdef ANDROID
static stream_type & defaultStream(){
return android_ostream::stream;
}
static stream_type & getStream(){
return defaultStream();
}
void logToFile(){
}
void closeLog(){
}
#elif defined(WII) && defined(DEBUG)
static stream_type & defaultStream(){
return wii_ostream::stream;
}
static stream_type & getStream(){
return defaultStream();
}
void logToFile(){
}
void closeLog(){
}
#elif defined(NETWORK_DEBUG)
static stream_type & defaultStream(){
return network_ostream::stream;
}
static stream_type & getStream(){
return defaultStream();
}
void logToFile(){
}
void closeLog(){
}
#else
static stream_type & defaultStream(){
return std::cout;
}
static std::ofstream log;
static bool useFile = false;
static stream_type & fileStream(){
static bool init = false;
if (!init){
log.open("paintown.log");
init = true;
}
return log;
}
static void closeFileStream(){
log.close();
}
static stream_type & getStream(){
if (useFile){
return fileStream();
} else {
return defaultStream();
}
}
void logToFile(){
useFile = true;
}
void closeLog(){
closeFileStream();
}
#endif
}
Global::stream_type & Global::debug(int i, const string & context){
if (global_debug_level >= i){
Global::stream_type & out = getStream();
out << "[" << i << ":" << context << "] ";
return out;
}
return nullcout;
}
void Global::setDebug(int i){
global_debug_level = i;
}
int Global::getDebug(){
return global_debug_level;
}
std::string Global::defaultDebugContext = "default";
void Global::setDefaultDebugContext(const std::string & context){
defaultDebugContext = context;
}
static std::string now(){
time_t t = time(NULL);
tm * timeData;
timeData = localtime(&t);
uint64_t millis = System::currentMilliseconds() % 1000;
if (timeData != NULL){
char buffer[200];
strftime(buffer, sizeof(buffer), "%F %I:%M:%S", timeData);
std::ostringstream out;
out << buffer << "." << millis;
strftime(buffer, sizeof(buffer), " %p", timeData);
out << buffer;
return out.str();
// return std::string(buffer);
}
return std::string();
}
std::string Global::debug_context(const char * file, int line){
std::ostringstream out;
out << file << ":" << line << " " << now();
return out.str();
}
diff --git a/src/directory.cpp b/src/directory.cpp
index 5de64ec3..be06ac65 100644
--- a/src/directory.cpp
+++ b/src/directory.cpp
@@ -1,331 +1,331 @@
-#include "file-system.h"
-#include "debug.h"
-#include "thread.h"
+#include "r-tech1/file-system.h"
+#include "r-tech1/debug.h"
+#include "r-tech1/thread.h"
#include <string>
#include <vector>
#include <map>
#ifndef USE_ALLEGRO
-#include "sfl/sfl.h"
-#include "sfl/sfldir.h"
+#include "libs/sfl/sfl.h"
+#include "libs/sfl/sfldir.h"
#endif
using std::string;
using std::vector;
using std::map;
namespace Storage{
Directory::Directory(){
}
Directory::~Directory(){
}
/* Used to signal .. in a path */
class UpDirectory: public std::exception {
public:
UpDirectory(Path::AbsolutePath path):
path(path){
}
virtual ~UpDirectory() throw () {
}
Path::AbsolutePath path;
};
class Traverser{
public:
Traverser(){
}
virtual void traverseFile(Directory & directory, const string & file) = 0;
virtual void traverseDirectory(Directory & directory, const string & path) = 0;
virtual ~Traverser(){
}
};
/* FIXME: this shares a lot of code with findFiles */
vector<Path::AbsolutePath> Directory::findDirectories(const Path::AbsolutePath & dataPath, const std::string & find, bool caseInsensitive){
Util::Thread::ScopedLock scoped(lock);
vector<Path::AbsolutePath> out;
class FindDirectory: public Traverser {
public:
FindDirectory():
failed(false){
}
bool failed;
Util::ReferenceCount<Directory> last;
virtual void traverseFile(Directory & directory, const string & file){
if (directory.directories[file] != NULL){
last = directory.directories[file];
}
}
virtual void traverseDirectory(Directory & directory, const string & path){
if (directory.directories[path] != NULL){
last = directory.directories[path];
} else {
failed = true;
}
}
};
FindDirectory lastDirectory;
traverse(dataPath, lastDirectory);
if (lastDirectory.failed || lastDirectory.last == NULL){
return out;
}
Global::debug(1) << "Search in " << dataPath.path() << " for " << find << std::endl;
vector<string> names = lastDirectory.last->directoryNames();
#ifndef USE_ALLEGRO
for (vector<string>::iterator it = names.begin(); it != names.end(); it++){
Global::debug(1) << "Check if " << *it << " matches " << find << std::endl;
if (file_matches(it->c_str(), find.c_str())){
out.push_back(dataPath.join(Path::RelativePath(*it)));
}
}
#endif
return out;
}
vector<Path::AbsolutePath> Directory::findFiles(const Path::AbsolutePath & dataPath, const std::string & find, bool caseInsensitive){
Util::Thread::ScopedLock scoped(lock);
vector<Path::AbsolutePath> out;
class FindDirectory: public Traverser {
public:
FindDirectory():
failed(false){
}
bool failed;
Util::ReferenceCount<Directory> last;
virtual void traverseFile(Directory & directory, const string & file){
if (directory.directories[file] != NULL){
last = directory.directories[file];
}
}
virtual void traverseDirectory(Directory & directory, const string & path){
if (directory.directories[path] != NULL){
last = directory.directories[path];
} else {
failed = true;
}
}
};
FindDirectory lastDirectory;
traverse(dataPath, lastDirectory);
if (lastDirectory.failed || lastDirectory.last == NULL){
return out;
}
Global::debug(1) << "Search in " << dataPath.path() << " for " << find << std::endl;
vector<string> names = lastDirectory.last->filenames();
#ifndef USE_ALLEGRO
for (vector<string>::iterator it = names.begin(); it != names.end(); it++){
Global::debug(1) << "Check if " << *it << " matches " << find << std::endl;
if (file_matches(it->c_str(), find.c_str())){
out.push_back(dataPath.join(Path::RelativePath(*it)));
}
}
#endif
return out;
}
vector<std::string> Directory::directoryNames() const {
Util::Thread::ScopedLock scoped(lock);
vector<string> out;
for (map<string, Util::ReferenceCount<Directory> >::const_iterator it = directories.begin(); it != directories.end(); it++){
if (it->second != NULL){
out.push_back(it->first);
}
}
return out;
}
vector<string> Directory::filenames() const {
Util::Thread::ScopedLock scoped(lock);
vector<string> out;
for (map<string, Util::ReferenceCount<Descriptor> >::const_iterator it = files.begin(); it != files.end(); it++){
if (it->second != NULL){
out.push_back(it->first);
}
}
for (map<string, Util::ReferenceCount<Directory> >::const_iterator it = directories.begin(); it != directories.end(); it++){
if (it->second != NULL){
out.push_back(it->first);
}
}
return out;
}
void Directory::doTraverse(const Path::AbsolutePath & path, Traverser & traverser){
if (path.isFile()){
traverser.traverseFile(*this, path.path());
} else {
string name = path.firstDirectory();
if (name == "."){
try{
return doTraverse(path.removeFirstDirectory(), traverser);
} catch (const UpDirectory & up){
return doTraverse(up.path, traverser);
}
} else if (name == ".."){
throw UpDirectory(path.removeFirstDirectory());
}
traverser.traverseDirectory(*this, path.firstDirectory());
Util::ReferenceCount<Directory> directory = directories[path.firstDirectory()];
if (directory != NULL){
try{
return directory->doTraverse(path.removeFirstDirectory(), traverser);
} catch (const UpDirectory & up){
return doTraverse(up.path, traverser);
}
}
}
}
void Directory::traverse(const Path::AbsolutePath & path, Traverser & traverser){
Path::AbsolutePath use = path;
/* The path might contain .. paths that would go out of this directory
* so just ignore those paths and use the rest of the path.
*/
while (true){
try{
return doTraverse(use, traverser);
} catch (const UpDirectory & up){
use = up.path;
}
}
}
bool Directory::exists(const Path::AbsolutePath & path){
Util::Thread::ScopedLock scoped(lock);
class FindIt: public Traverser {
public:
FindIt():
found(false){
}
virtual void traverseFile(Directory & directory, const string & file){
if (directory.files[file] != NULL){
found = true;
} else if (directory.directories[file] != NULL){
found = true;
} else {
found = false;
}
}
virtual void traverseDirectory(Directory & directory, const string & path){
}
bool found;
};
FindIt find;
traverse(path, find);
return find.found;
}
bool Directory::isDirectory(const Path::AbsolutePath & path){
Util::Thread::ScopedLock scoped(lock);
class FindIt: public Traverser {
public:
FindIt():
found(false){
}
virtual void traverseFile(Directory & directory, const string & file){
if (directory.files[file] != NULL){
found = false;
} else if (directory.directories[file] != NULL){
found = true;
} else {
found = false;
}
}
virtual void traverseDirectory(Directory & directory, const string & path){
}
bool found;
};
FindIt find;
traverse(path, find);
return find.found;
}
/* Might return NULL if the path can't be found */
Util::ReferenceCount<Descriptor> Directory::lookup(const Path::AbsolutePath & path){
Util::Thread::ScopedLock scoped(lock);
class FindIt: public Traverser {
public:
virtual void traverseFile(Directory & directory, const string & file){
found = directory.files[file];
}
virtual void traverseDirectory(Directory & directory, const string & path){
}
Util::ReferenceCount<Descriptor> found;
};
FindIt find;
traverse(path, find);
return find.found;
}
void Directory::addFile(const Path::AbsolutePath & path, const Util::ReferenceCount<Descriptor> & file){
Util::Thread::ScopedLock scoped(lock);
class AddPath: public Traverser {
public:
AddPath(const Util::ReferenceCount<Descriptor> & file):
file(file){
}
const Util::ReferenceCount<Descriptor> & file;
virtual void traverseFile(Directory & directory, const string & path){
directory.files[path] = file;
}
virtual void traverseDirectory(Directory & directory, const string & path){
if (directory.directories[path] == NULL){
directory.directories[path] = Util::ReferenceCount<Directory>(new Directory());
}
}
};
Global::debug(1) << "Add file " << path.path() << std::endl;
AddPath adder(file);
traverse(path, adder);
}
void Directory::removeFile(const Path::AbsolutePath & path){
addFile(path, Util::ReferenceCount<Descriptor>(NULL));
}
}
diff --git a/src/ebox.cpp b/src/ebox.cpp
index 8246ebb1..38db8578 100644
--- a/src/ebox.cpp
+++ b/src/ebox.cpp
@@ -1,713 +1,713 @@
/* ebox version 3:
* by Jon Rafkind
*/
-#include "ebox.h"
+#include "r-tech1/ebox.h"
#include <stdio.h>
-#include "funcs.h"
-#include "graphics/bitmap.h"
+#include "r-tech1/funcs.h"
+#include "r-tech1/graphics/bitmap.h"
#include <iostream>
using namespace std;
// extern "C" void rest( int i );
// using namespace Ebox2;
#ifndef debug
// #define debug printf("File: %s Line: %d\n", __FILE__, __LINE__ );
#define debug std::cout<<"File: "<<__FILE__<<" Line: "<<__LINE__<<std::endl;
#endif
// #define MIN_SIZE 8
const int MIN_SIZE = 8;
/* copy constructor but with a pointer */
EQuad::EQuad( EQuad * const head ):
width( head->width ),
height( head->height ),
full( head->full ),
min_x( head->min_x ),
min_y( head->min_y ),
parent( NULL ),
num_quads( head->num_quads ){
- for ( int q = 0; q < 4; q++ )
- quads[q] = NULL;
+ for ( int q = 0; q < 4; q++ )
+ quads[q] = NULL;
- for ( int i = 0; i < head->numQuads(); i++ ){
- // EQuad * tmp = head->getQuad( i );
- quads[i] = new EQuad( head->getQuad( i ) );
- quads[i]->parent = this;
- }
+ for ( int i = 0; i < head->numQuads(); i++ ){
+ // EQuad * tmp = head->getQuad( i );
+ quads[i] = new EQuad( head->getQuad( i ) );
+ quads[i]->parent = this;
+ }
}
EQuad::EQuad( int w, int h, EQuad * _parent ):
width( w ),
height( h ),
min_x( 0 ),
min_y( 0 ),
parent( _parent ),
num_quads( 0 ){
- full = true;
- for ( int i = 0; i < 4; i++ )
- quads[i] = NULL;
+ full = true;
+ for ( int i = 0; i < 4; i++ )
+ quads[i] = NULL;
}
EQuad::EQuad( const Graphics::Bitmap * who, int min_size, Graphics::Color mask_pixel, int _min_x, int _min_y, EQuad * _parent ):
width( who->getWidth() ),
height( who->getHeight() ),
full( false ),
min_x( _min_x ),
min_y( _min_y ),
parent( _parent ){
Graphics::Bitmap * b1, * b2, * b3, * b4;
- EQuad * quad1, * quad2, * quad3, * quad4;
- quad1 = quad2 = quad3 = quad4 = NULL;
-
- if ( width > min_size && height > min_size ){
-
-
- int w = who->getWidth() >> 1;
- int h = who->getHeight() >> 1;
-
- // b1 = create_sub_Bitmap( who, 0, 0, w, h );
- b1 = new Graphics::Bitmap( *who, 0, 0, w, h );
- quad1 = new EQuad( b1, min_size, mask_pixel, 0, 0, this );
- // destroy_Bitmap( b1 );
- delete b1;
-
- // b2 = create_sub_Bitmap( who, w, 0, w, h );
- b2 = new Graphics::Bitmap( *who, w, 0, w, h );
- quad2 = new EQuad( b2, min_size, mask_pixel, w, 0, this );
- delete b2;
- // destroy_Bitmap( b2 );
-
-
- // b3 = create_sub_Bitmap( who, 0, h, w, h );
- b3 = new Graphics::Bitmap( *who, 0, h, w, h );
- quad3 = new EQuad( b3, min_size, mask_pixel, 0, h, this );
- delete b3;
- // destroy_Bitmap( b3 );
-
- // b4 = create_sub_Bitmap( who, w, h, w, h );
- b4 = new Graphics::Bitmap( *who, w, h, w, h );
- quad4 = new EQuad( b4, min_size, mask_pixel, w, h, this );
- delete b4;
- // destroy_Bitmap( b4 );
-
- if ( quad1->empty() ){
- delete quad1;
- quad1 = NULL;
- }
- if ( quad2->empty() ){
- delete quad2;
- quad2 = NULL;
- }
- if ( quad3->empty() ){
- delete quad3;
- quad3 = NULL;
- }
- if ( quad4->empty() ){
- delete quad4;
- quad4 = NULL;
- }
-
- if ( quad1 && quad2 && quad3 && quad4 )
- if ( quad1->full && quad2->full && quad3->full && quad4->full ){
- delete quad1;
- delete quad2;
- delete quad3;
- delete quad4;
- quad1 = NULL;
- quad2 = NULL;
- quad3 = NULL;
- quad4 = NULL;
- full = true;
- }
-
- checkQuad( quad1 );
- checkQuad( quad2 );
- checkQuad( quad3 );
- checkQuad( quad4 );
-
- } else {
- // printf("Size X:%d Y:%d\n", width, height );
- int total = 0;
- int denom = who->getWidth() * who->getHeight();
+ EQuad * quad1, * quad2, * quad3, * quad4;
+ quad1 = quad2 = quad3 = quad4 = NULL;
+
+ if ( width > min_size && height > min_size ){
+
+
+ int w = who->getWidth() >> 1;
+ int h = who->getHeight() >> 1;
+
+ // b1 = create_sub_Bitmap( who, 0, 0, w, h );
+ b1 = new Graphics::Bitmap( *who, 0, 0, w, h );
+ quad1 = new EQuad( b1, min_size, mask_pixel, 0, 0, this );
+ // destroy_Bitmap( b1 );
+ delete b1;
+
+ // b2 = create_sub_Bitmap( who, w, 0, w, h );
+ b2 = new Graphics::Bitmap( *who, w, 0, w, h );
+ quad2 = new EQuad( b2, min_size, mask_pixel, w, 0, this );
+ delete b2;
+ // destroy_Bitmap( b2 );
+
+
+ // b3 = create_sub_Bitmap( who, 0, h, w, h );
+ b3 = new Graphics::Bitmap( *who, 0, h, w, h );
+ quad3 = new EQuad( b3, min_size, mask_pixel, 0, h, this );
+ delete b3;
+ // destroy_Bitmap( b3 );
+
+ // b4 = create_sub_Bitmap( who, w, h, w, h );
+ b4 = new Graphics::Bitmap( *who, w, h, w, h );
+ quad4 = new EQuad( b4, min_size, mask_pixel, w, h, this );
+ delete b4;
+ // destroy_Bitmap( b4 );
+
+ if ( quad1->empty() ){
+ delete quad1;
+ quad1 = NULL;
+ }
+ if ( quad2->empty() ){
+ delete quad2;
+ quad2 = NULL;
+ }
+ if ( quad3->empty() ){
+ delete quad3;
+ quad3 = NULL;
+ }
+ if ( quad4->empty() ){
+ delete quad4;
+ quad4 = NULL;
+ }
+
+ if ( quad1 && quad2 && quad3 && quad4 )
+ if ( quad1->full && quad2->full && quad3->full && quad4->full ){
+ delete quad1;
+ delete quad2;
+ delete quad3;
+ delete quad4;
+ quad1 = NULL;
+ quad2 = NULL;
+ quad3 = NULL;
+ quad4 = NULL;
+ full = true;
+ }
+
+ checkQuad( quad1 );
+ checkQuad( quad2 );
+ checkQuad( quad3 );
+ checkQuad( quad4 );
+
+ } else {
+ // printf("Size X:%d Y:%d\n", width, height );
+ int total = 0;
+ int denom = who->getWidth() * who->getHeight();
/* empty sprite? */
if (denom < 1){
denom = 1;
}
int width = who->getWidth();
int height = who->getHeight();
for (int x = 0; x < width; x++){
for (int y = 0; y < height; y++){
// int pixel = _getpixel16( who, x, y );
Graphics::Color pixel = who->getPixel(x, y);
if (pixel != mask_pixel){
++total;
}
if ( total * 100 / denom > 50 ){
/* we're done already,
* stop counting pixels
*/
goto short_circuit;
}
}
}
- /* johnny 5 alive! */
- short_circuit:
+ /* johnny 5 alive! */
+ short_circuit:
- if ( total * 100 / denom > 50 ){
- full = true;
- }
- }
+ if ( total * 100 / denom > 50 ){
+ full = true;
+ }
+ }
- for ( int i = 0; i < 4; i++ )
- quads[i] = NULL;
+ for ( int i = 0; i < 4; i++ )
+ quads[i] = NULL;
- int i = 0;
- if ( quad1 ) quads[i++] = quad1;
- if ( quad2 ) quads[i++] = quad2;
- if ( quad3 ) quads[i++] = quad3;
- if ( quad4 ) quads[i++] = quad4;
-
- num_quads = numQuads();
+ int i = 0;
+ if ( quad1 ) quads[i++] = quad1;
+ if ( quad2 ) quads[i++] = quad2;
+ if ( quad3 ) quads[i++] = quad3;
+ if ( quad4 ) quads[i++] = quad4;
+
+ num_quads = numQuads();
}
-
+
bool EQuad::addQuad( EQuad * who ){
- int n = numQuads();
- if ( n < 4 ){
- quads[n] = who;
- full = false;
- return true;
- } else return false;
-}
-
+ int n = numQuads();
+ if ( n < 4 ){
+ quads[n] = who;
+ full = false;
+ return true;
+ } else return false;
+}
+
void EQuad::checkQuad( EQuad *& q ){
if ( q != NULL ){
while ( q->numQuads() == 1 ){
EQuad * const newquad = q->getQuad();
q->detach( newquad );
int x = q->getMinX();
int y = q->getMinY();
delete q;
q = newquad;
newquad->setMinX( newquad->getMinX() + x );
newquad->setMinY( newquad->getMinY() + y );
q->parent = this;
}
}
}
int EQuad::totalQuads(){
if ( full ) return 1;
int total = 0;
for ( int i = 0; i < numQuads(); i++ )
if ( quads[i] )
total += quads[i]->totalQuads();
/*
if ( quad1 ) total += quad1->totalQuads();
if ( quad2 ) total += quad2->totalQuads();
if ( quad3 ) total += quad3->totalQuads();
if ( quad4 ) total += quad4->totalQuads();
*/
return total;
}
-
+
void EQuad::setMinX( int x ){
min_x = x;
}
void EQuad::setMinY( int y ){
min_y = y;
}
/*
int EQuad::numQuads() const{
- int total = 0;
- / *
- if ( quad1 ) ++total;
- if ( quad2 ) ++total;
- if ( quad3 ) ++total;
- if ( quad4 ) ++total;
- * /
- for ( total = 0; total < 4 && quads[total] != NULL; total++ );
+ int total = 0;
+ / *
+ if ( quad1 ) ++total;
+ if ( quad2 ) ++total;
+ if ( quad3 ) ++total;
+ if ( quad4 ) ++total;
+ * /
+ for ( total = 0; total < 4 && quads[total] != NULL; total++ );
- return total;
+ return total;
}
*/
EQuad * EQuad::getQuad() const {
- return quads[0];
- /*
- if ( quad1 ) return quad1;
- if ( quad2 ) return quad2;
- if ( quad3 ) return quad3;
- if ( quad4 ) return quad4;
- return NULL;
- */
+ return quads[0];
+ /*
+ if ( quad1 ) return quad1;
+ if ( quad2 ) return quad2;
+ if ( quad3 ) return quad3;
+ if ( quad4 ) return quad4;
+ return NULL;
+ */
}
EQuad * EQuad::getQuad( int x ) const {
- return quads[x];
+ return quads[x];
}
void EQuad::detach( EQuad * const who ){
- // printf("Detach %p\n", who );
- /*
- if ( who == quad1 ) quad1 = NULL;
- if ( who == quad2 ) quad2 = NULL;
- if ( who == quad3 ) quad3 = NULL;
- if ( who == quad4 ) quad4 = NULL;
- */
- for ( int i = 0; i < numQuads(); i++ )
- if ( who == quads[i] )
- quads[i] = NULL;
-
- EQuad * tmp[ 4 ];
- int begin = 0;
- for ( int i = 0; i < 4; i++ )
- if ( quads[i] ){
- tmp[begin++] = quads[i];
- quads[i] = NULL;
- }
+ // printf("Detach %p\n", who );
+ /*
+ if ( who == quad1 ) quad1 = NULL;
+ if ( who == quad2 ) quad2 = NULL;
+ if ( who == quad3 ) quad3 = NULL;
+ if ( who == quad4 ) quad4 = NULL;
+ */
+ for ( int i = 0; i < numQuads(); i++ )
+ if ( who == quads[i] )
+ quads[i] = NULL;
+
+ EQuad * tmp[ 4 ];
+ int begin = 0;
+ for ( int i = 0; i < 4; i++ )
+ if ( quads[i] ){
+ tmp[begin++] = quads[i];
+ quads[i] = NULL;
+ }
- for ( int q = 0; q < begin; q++ )
- quads[q] = tmp[q];
+ for ( int q = 0; q < begin; q++ )
+ quads[q] = tmp[q];
}
int EQuad::calcSize(){
- int total = sizeof(*this);
- for ( int q = 0; q < numQuads(); q++ ){
- total += quads[q]->calcSize();
- }
- return total;
+ int total = sizeof(*this);
+ for ( int q = 0; q < numQuads(); q++ ){
+ total += quads[q]->calcSize();
+ }
+ return total;
}
bool EQuad::empty(){
if (numQuads() == 0) return !full;
return false;
}
void EQuad::draw(const Graphics::Bitmap & work, int x, int y, Graphics::Color color, bool flippedX){
int mx = x + getX1(flippedX);
int my = y + getY1(false);
int mx2 = mx + getWidth();
int my2 = my + getHeight();
for (int i = 0; i < numQuads(); i++){
quads[i]->draw(work, mx, my, color, flippedX);
}
if (full){
work.rectangle(mx, my, mx2, my2, color);
}
}
void EQuad::draw( const Graphics::Bitmap & work, int x, int y, Graphics::Color color, EQuad * who ){
bool cy = false;
for ( int i = 0; i < numQuads(); i++ )
if ( who == quads[i] )
cy = true;
int mx = x + getMinX();
int my = y + getMinY();
if (cy){
who->draw(work, mx, my, color);
} else {
for ( int i = 0; i < numQuads(); i++ )
quads[i]->draw( work, mx, my, color, who );
}
}
static bool boxCollide( int zx1, int zy1, int zx2, int zy2, int zx3, int zy3, int zx4, int zy4 ){
if ( zx1 < zx3 && zx1 < zx4 &&
zx2 < zx3 && zx2 < zx4 ) return false;
if ( zx1 > zx3 && zx1 > zx4 &&
zx2 > zx3 && zx2 > zx4 ) return false;
if ( zy1 < zy3 && zy1 < zy4 &&
zy2 < zy3 && zy2 < zy4 ) return false;
if ( zy1 > zy3 && zy1 > zy4 &&
zy2 > zy3 && zy2 > zy4 ) return false;
return true;
}
/* sure this could be simplified, but thats no fun :p */
int EQuad::getX1(bool xflipped){
if (parent){
if (xflipped){
/* x1 = getMinX()
* x2 = getMinX() + getWidth()
* When flipping x2 always becomes the new x1
* x is the starting location, x'' is final
*
* 1. translate so that axis is the origin
* x' = x - axis
* 2. reflect over axis
* fx = -x
* 3. translate back
* x'' = fx + axis
* 4. simplify
* x'' = -(x - axis) + axis
* x'' = 2*axis - x
*
* axis = parent->getWidth() / 2
*/
return parent->getWidth() - (getMinX() + getWidth());
} else {
return getMinX();
}
} else {
return getMinX();
}
}
int EQuad::getFullX1(bool xflipped){
if (parent){
if (xflipped){
return parent->getFullX1(xflipped) + parent->getWidth() - (getMinX() + getWidth());
} else {
return parent->getFullX1(xflipped) + getMinX();
}
} else {
return getMinX();
}
}
int EQuad::getY1( bool yflipped ){
if (parent){
if (yflipped){
return parent->getHeight() - (getMinY() + getHeight());
} else {
return getMinY();
}
} else {
return getMinY();
}
}
int EQuad::getFullY1( bool yflipped ){
if (parent){
if (yflipped){
return parent->getFullY1( yflipped ) - (parent->getHeight() + getMinY() + getHeight());
} else {
return parent->getFullY1( yflipped ) + getMinY();
}
} else {
return getMinY();
}
}
void EQuad::gather( int mx, int my, int x1, int y1, int x2, int y2, vector< EQuad * > & collides, bool xflipped, bool yflipped ){
- /*
- int rx = mx + getX1();
- int ry = my + getY1();
- */
- int rx = mx;
- int ry = my;
+ /*
+ int rx = mx + getX1();
+ int ry = my + getY1();
+ */
+ int rx = mx;
+ int ry = my;
- int rx2 = rx + getWidth();
- int ry2 = ry + getHeight();
+ int rx2 = rx + getWidth();
+ int ry2 = ry + getHeight();
- if ( ! boxCollide( rx, ry, rx2, ry2, x1, y1, x2, y2 ) ){
- return;
- }
+ if ( ! boxCollide( rx, ry, rx2, ry2, x1, y1, x2, y2 ) ){
+ return;
+ }
- for ( int i = 0; i < numQuads(); i++ ){
- quads[i]->gather( rx + quads[i]->getX1( xflipped ), ry + quads[i]->getY1( yflipped ), x1, y1, x2, y2, collides, xflipped, yflipped );
- }
-
- if ( full ){
- collides.push_back( this );
- }
+ for ( int i = 0; i < numQuads(); i++ ){
+ quads[i]->gather( rx + quads[i]->getX1( xflipped ), ry + quads[i]->getY1( yflipped ), x1, y1, x2, y2, collides, xflipped, yflipped );
+ }
+
+ if ( full ){
+ collides.push_back( this );
+ }
}
bool EQuad::collide( int mx, int my, int x1, int y1, int x2, int y2, EQuad ** last, bool xflipped, bool yflipped ){
- /*
- int rx = mx + getMinX();
- int ry = my + getMinY();
+ /*
+ int rx = mx + getMinX();
+ int ry = my + getMinY();
- if ( parent ){
- if ( xflipped ){
- rx = mx + parent->getWidth() - (getMinX()+getWidth());
- }
- if ( yflipped ){
- ry = my + parent->getHeight() - (getMinY()+getHeight());
- }
- }
- */
+ if ( parent ){
+ if ( xflipped ){
+ rx = mx + parent->getWidth() - (getMinX()+getWidth());
+ }
+ if ( yflipped ){
+ ry = my + parent->getHeight() - (getMinY()+getHeight());
+ }
+ }
+ */
- int rx = mx + getX1(xflipped);
- int ry = my + getY1(yflipped);
+ int rx = mx + getX1(xflipped);
+ int ry = my + getY1(yflipped);
- int rx2 = rx + getWidth();
- int ry2 = ry + getHeight();
+ int rx2 = rx + getWidth();
+ int ry2 = ry + getHeight();
- // rect( screen, rx, ry, rx2, ry2, makecol(255,255,0) );
+ // rect( screen, rx, ry, rx2, ry2, makecol(255,255,0) );
- bool cy = boxCollide( rx, ry, rx2, ry2, x1, y1, x2, y2 );
- if ( !cy ) return false;
+ bool cy = boxCollide( rx, ry, rx2, ry2, x1, y1, x2, y2 );
+ if ( !cy ) return false;
- for ( int i = 0; i < numQuads(); i++ )
- if ( quads[i]->collide( rx, ry, x1, y1, x2, y2, last ) )
- return true;
+ for ( int i = 0; i < numQuads(); i++ )
+ if ( quads[i]->collide( rx, ry, x1, y1, x2, y2, last ) )
+ return true;
- if ( !full ) return false;
- if ( cy ) *last = this;
- return cy;
+ if ( !full ) return false;
+ if ( cy ) *last = this;
+ return cy;
- return false;
+ return false;
}
EQuad::~EQuad(){
- /*
- if ( quad1 ) delete quad1;
- if ( quad2 ) delete quad2;
- if ( quad3 ) delete quad3;
- if ( quad4 ) delete quad4;
- */
+ /*
+ if ( quad1 ) delete quad1;
+ if ( quad2 ) delete quad2;
+ if ( quad3 ) delete quad3;
+ if ( quad4 ) delete quad4;
+ */
- for ( int q = 0; q < 4; q++ )
- if ( quads[q] != NULL )
- delete quads[q];
+ for ( int q = 0; q < 4; q++ )
+ if ( quads[q] != NULL )
+ delete quads[q];
}
long long ECollide::totalTime = 0;
void ECollide::initECollide( const Graphics::Bitmap * who, Graphics::Color mask_pixel ){
- /*
- TimeDifference dif;
- dif.startTime();
- */
- head_quad = new EQuad( who, MIN_SIZE, mask_pixel, 0, 0, NULL );
- last_collide = NULL;
+ /*
+ TimeDifference dif;
+ dif.startTime();
+ */
+ head_quad = new EQuad( who, MIN_SIZE, mask_pixel, 0, 0, NULL );
+ last_collide = NULL;
- /*
- dif.endTime();
- totalTime += dif.getTime();
- cout<<"Total time taken: "<< totalTime / 1000 <<" ms" <<endl;
- */
+ /*
+ dif.endTime();
+ totalTime += dif.getTime();
+ cout<<"Total time taken: "<< totalTime / 1000 <<" ms" <<endl;
+ */
}
ECollide::ECollide( const Graphics::Bitmap * who, Graphics::Color mask_pixel ){
- initECollide( who, mask_pixel );
- /*
- head_quad = new EQuad( who, MIN_SIZE, mask_pixel, 0, 0, NULL );
- last_collide = NULL;
- */
+ initECollide( who, mask_pixel );
+ /*
+ head_quad = new EQuad( who, MIN_SIZE, mask_pixel, 0, 0, NULL );
+ last_collide = NULL;
+ */
}
ECollide::ECollide( const Graphics::Bitmap & who, Graphics::Color mask_pixel ){
- initECollide( &who, mask_pixel );
+ initECollide( &who, mask_pixel );
- /*
- head_quad = new EQuad( &who, MIN_SIZE, mask_pixel, 0, 0, NULL );
- last_collide = NULL;
- */
+ /*
+ head_quad = new EQuad( &who, MIN_SIZE, mask_pixel, 0, 0, NULL );
+ last_collide = NULL;
+ */
}
#if 0
ECollide::ECollide( BITMAP * who, int mask_pixel ){
- Bitmap tmp( who );
- initECollide( &tmp, mask_pixel );
+ Bitmap tmp( who );
+ initECollide( &tmp, mask_pixel );
- /*
- head_quad = new EQuad( &tmp, MIN_SIZE, mask_pixel, 0, 0, NULL );
- last_collide = NULL;
- */
+ /*
+ head_quad = new EQuad( &tmp, MIN_SIZE, mask_pixel, 0, 0, NULL );
+ last_collide = NULL;
+ */
}
#endif
ECollide::ECollide( int width, int height ){
- last_collide = NULL;
- head_quad = new EQuad( width, height, NULL );
+ last_collide = NULL;
+ head_quad = new EQuad( width, height, NULL );
}
ECollide::ECollide( const ECollide * e ){
- initQuad( e->head_quad );
- /*
- last_collide = NULL;
- head_quad = new EQuad( e->head_quad );
- */
+ initQuad( e->head_quad );
+ /*
+ last_collide = NULL;
+ head_quad = new EQuad( e->head_quad );
+ */
}
ECollide::ECollide( const ECollide & e ){
- initQuad( e.head_quad );
- /*
- last_collide = NULL;
- head_quad = new EQuad( e.head_quad );
- */
+ initQuad( e.head_quad );
+ /*
+ last_collide = NULL;
+ head_quad = new EQuad( e.head_quad );
+ */
}
ECollide::ECollide( EQuad * const head ){
- initQuad( head );
- /*
- last_collide = NULL;
- head_quad = new EQuad( head );
- */
+ initQuad( head );
+ /*
+ last_collide = NULL;
+ head_quad = new EQuad( head );
+ */
}
void ECollide::initQuad( EQuad * const head ){
- last_collide = NULL;
- head_quad = new EQuad( head );
+ last_collide = NULL;
+ head_quad = new EQuad( head );
}
ECollide * ECollide::copy(){
- return new ECollide( head_quad );
+ return new ECollide( head_quad );
}
-
+
int ECollide::getMinHeight(){
- return head_quad->getMinY();
+ return head_quad->getMinY();
}
int ECollide::getMaxHeight(){
- return head_quad->getMinY() + head_quad->getHeight();
+ return head_quad->getMinY() + head_quad->getHeight();
}
int ECollide::getMinWidth(){
- return head_quad->getMinX();
+ return head_quad->getMinX();
}
-
+
int ECollide::getMaxWidth(){
- return head_quad->getMinX() + head_quad->getWidth();
+ return head_quad->getMinX() + head_quad->getWidth();
}
int ECollide::calcSize(){
- int total = sizeof(*this);
- if ( head_quad )
- total += head_quad->calcSize();
- return total;
+ int total = sizeof(*this);
+ if ( head_quad )
+ total += head_quad->calcSize();
+ return total;
}
-
+
bool ECollide::collide( int mx, int my, int x1, int y1, int x2, int y2, bool xflipped, bool yflipped ){
- last_collide = NULL;
- return head_quad->collide(mx,my,x1,y1,x2,y2, &last_collide, xflipped, yflipped );
+ last_collide = NULL;
+ return head_quad->collide(mx,my,x1,y1,x2,y2, &last_collide, xflipped, yflipped );
}
bool ECollide::collide( int mx, int my, int x1, int y1, int x2, int y2, EQuad ** last, bool xflipped, bool yflipped ){
- return head_quad->collide(mx,my,x1,y1,x2,y2, last, xflipped, yflipped );
+ return head_quad->collide(mx,my,x1,y1,x2,y2, last, xflipped, yflipped );
}
void ECollide::gather( int mx, int my, int x1, int y1, int x2, int y2, vector< EQuad * > & e, bool xflipped, bool yflipped ){
- return head_quad->gather( mx, my, x1, y1, x2, y2, e, xflipped, yflipped );
+ return head_quad->gather( mx, my, x1, y1, x2, y2, e, xflipped, yflipped );
}
-
+
bool ECollide::Collision( int mx, int my, int ax, int ay, bool xflipped, bool ylfipped ){
- return collide( mx, my, ax, ay, ax, ay );
+ return collide( mx, my, ax, ay, ax, ay );
}
bool ECollide::Collision( int mx, int my, int x1, int y1, int x2, int y2, bool xflipped, bool yflipped ){
- return collide( mx, my, x1, y1, x2, y2 );
+ return collide( mx, my, x1, y1, x2, y2 );
}
bool ECollide::Collision( ECollide * col, int mx, int my, int ax, int ay, bool my_xflipped, bool my_yflipped, bool him_xflipped, bool him_yflipped ){
- if ( !col ) return false;
-
- int x1 = mx > ax ? mx : ax;
- int y1 = my > ay ? my : ay;
- int x2 = (mx+getWidth()) < (ax+col->getWidth()) ? (mx+getWidth()) : (ax+col->getWidth());
- int y2 = (my+getHeight()) < (ay+col->getHeight()) ? (my+getHeight()) : (ay+col->getHeight());
-
- if ( x1 > x2 ) return false;
- if ( y1 > y2 ) return false;
-
- vector< EQuad * > collides1;
- gather( mx, my, x1, y1, x2, y2, collides1, my_xflipped, my_yflipped );
- vector< EQuad * > collides2;
- col->gather( ax, ay, x1, y1, x2, y2, collides2, him_xflipped, him_yflipped );
- for ( vector< EQuad * >::iterator it = collides1.begin(); it != collides1.end(); it++ ){
- EQuad * e = *it;
- int px1 = mx + e->getFullX1( my_xflipped );
- int py1 = my + e->getFullY1( my_yflipped );
- int px2 = px1 + e->getWidth();
- int py2 = py1 + e->getHeight();
-
- // Bitmap::Screen->rectangle( px1, py1, px2, py2, Bitmap::makeColor( 128, 128, 255 ) );
-
- for ( vector< EQuad * >::iterator it2 = collides2.begin(); it2 != collides2.end(); it2++ ){
- EQuad * e2 = *it2;
- int zx1 = ax + e2->getFullX1( him_xflipped );
- int zy1 = ay + e2->getFullY1( him_yflipped );
-
- // printf( "Test %d,%d,%d,%d against %d,%d,%d,%d\n", px1, py1, px2, py2, zx1, zy1, zx1 + e2->getWidth(), zy1 + e2->getHeight() );
-
- // Bitmap::Screen->rectangle( zx1, zy1, zx1 + e2->getWidth(), zy1 + e2->getHeight(), Bitmap::makeColor( Util::rnd( 255 ), 255, 255 ) );
-
- // if ( e2->collide( zx1, zy1, px1, py1, px2, py2, &last_collide, him_xflipped, him_yflipped ) ){
- if ( boxCollide( px1, py1, px2, py2, zx1, zy1, zx1 + e2->getWidth(), zy1 + e2->getHeight() ) ){
- // Bitmap::Screen->rectangle( zx1, zy1, zx1 + e2->getWidth(), zy1 + e2->getHeight(), Bitmap::makeColor( 255, 255, 0 ) );
- // cout << "Collided!" << endl;
- // rest( 1000 );
- return true;
- }
- }
- }
+ if ( !col ) return false;
+
+ int x1 = mx > ax ? mx : ax;
+ int y1 = my > ay ? my : ay;
+ int x2 = (mx+getWidth()) < (ax+col->getWidth()) ? (mx+getWidth()) : (ax+col->getWidth());
+ int y2 = (my+getHeight()) < (ay+col->getHeight()) ? (my+getHeight()) : (ay+col->getHeight());
+
+ if ( x1 > x2 ) return false;
+ if ( y1 > y2 ) return false;
+
+ vector< EQuad * > collides1;
+ gather( mx, my, x1, y1, x2, y2, collides1, my_xflipped, my_yflipped );
+ vector< EQuad * > collides2;
+ col->gather( ax, ay, x1, y1, x2, y2, collides2, him_xflipped, him_yflipped );
+ for ( vector< EQuad * >::iterator it = collides1.begin(); it != collides1.end(); it++ ){
+ EQuad * e = *it;
+ int px1 = mx + e->getFullX1( my_xflipped );
+ int py1 = my + e->getFullY1( my_yflipped );
+ int px2 = px1 + e->getWidth();
+ int py2 = py1 + e->getHeight();
+
+ // Bitmap::Screen->rectangle( px1, py1, px2, py2, Bitmap::makeColor( 128, 128, 255 ) );
+
+ for ( vector< EQuad * >::iterator it2 = collides2.begin(); it2 != collides2.end(); it2++ ){
+ EQuad * e2 = *it2;
+ int zx1 = ax + e2->getFullX1( him_xflipped );
+ int zy1 = ay + e2->getFullY1( him_yflipped );
+
+ // printf( "Test %d,%d,%d,%d against %d,%d,%d,%d\n", px1, py1, px2, py2, zx1, zy1, zx1 + e2->getWidth(), zy1 + e2->getHeight() );
+
+ // Bitmap::Screen->rectangle( zx1, zy1, zx1 + e2->getWidth(), zy1 + e2->getHeight(), Bitmap::makeColor( Util::rnd( 255 ), 255, 255 ) );
+
+ // if ( e2->collide( zx1, zy1, px1, py1, px2, py2, &last_collide, him_xflipped, him_yflipped ) ){
+ if ( boxCollide( px1, py1, px2, py2, zx1, zy1, zx1 + e2->getWidth(), zy1 + e2->getHeight() ) ){
+ // Bitmap::Screen->rectangle( zx1, zy1, zx1 + e2->getWidth(), zy1 + e2->getHeight(), Bitmap::makeColor( 255, 255, 0 ) );
+ // cout << "Collided!" << endl;
+ // rest( 1000 );
+ return true;
+ }
+ }
+ }
- // rest( 100 );
+ // rest( 100 );
- return false;
+ return false;
- /*
- return ( collide(mx,my,x1,y1,x2,y2,my_xflipped,my_yflipped) && col->collide(ax,ay,x1,y1,x2,y2,him_xflipped,him_yflipped) );
- */
+ /*
+ return ( collide(mx,my,x1,y1,x2,y2,my_xflipped,my_yflipped) && col->collide(ax,ay,x1,y1,x2,y2,him_xflipped,him_yflipped) );
+ */
}
/*
int ECollide::getWidth() const{
- return head_quad->getWidth();
+ return head_quad->getWidth();
}
int ECollide::getHeight() const{
- return head_quad->getHeight();
+ return head_quad->getHeight();
}
*/
-
+
void ECollide::draw( const Graphics::Bitmap & work, int x, int y, Graphics::Color color, bool flipped ){
- head_quad->draw( work, x, y, color, flipped );
+ head_quad->draw( work, x, y, color, flipped );
}
-
+
int ECollide::numQuads() const{
- return head_quad->totalQuads();
+ return head_quad->totalQuads();
}
-
+
void ECollide::draw( const Graphics::Bitmap & work, int x, int y, Graphics::Color color, EQuad * who ){
- if ( head_quad == who )
- head_quad->draw( work, x, y, color );
- else head_quad->draw( work, x, y, color, who );
+ if ( head_quad == who )
+ head_quad->draw( work, x, y, color );
+ else head_quad->draw( work, x, y, color, who );
}
EQuad * ECollide::getLast(){
- return last_collide;
+ return last_collide;
}
ECollide::~ECollide(){
- delete head_quad;
+ delete head_quad;
}
diff --git a/src/events.cpp b/src/events.cpp
index bfeb14e2..9048b705 100644
--- a/src/events.cpp
+++ b/src/events.cpp
@@ -1,634 +1,634 @@
#ifdef USE_SDL
#include <SDL.h>
#endif
#ifdef USE_ALLEGRO5
#include <allegro5/allegro.h>
#endif
#include <vector>
#include <map>
-#include "graphics/bitmap.h"
-#include "events.h"
-#include "exceptions/shutdown_exception.h"
-#include "configuration.h"
-#include "debug.h"
-#include "funcs.h"
-#include "thread.h"
-#include "init.h"
-#include "parameter.h"
-#include "input/keyboard.h"
-#include "input/joystick.h"
-#include "input/input-manager.h"
-#include "input/input-source.h"
-
-#include "system.h"
+#include "r-tech1/graphics/bitmap.h"
+#include "r-tech1/events.h"
+#include "r-tech1/exceptions/shutdown_exception.h"
+#include "r-tech1/configuration.h"
+#include "r-tech1/debug.h"
+#include "r-tech1/funcs.h"
+#include "r-tech1/thread.h"
+#include "r-tech1/init.h"
+#include "r-tech1/parameter.h"
+#include "r-tech1/input/keyboard.h"
+#include "r-tech1/input/joystick.h"
+#include "r-tech1/input/input-manager.h"
+#include "r-tech1/input/input-source.h"
+
+#include "r-tech1/system.h"
using std::map;
namespace Util{
int do_shutdown = 0;
bool shutdown(){
return do_shutdown > 0;
}
EventManager::EventManager():
bufferKeys(false),
deferResize(false){
resize.enable = false;
#ifdef USE_ALLEGRO5
queue = al_create_event_queue();
if (al_is_keyboard_installed()){
al_register_event_source(queue, al_get_keyboard_event_source());
}
if (al_is_joystick_installed()){
al_register_event_source(queue, al_get_joystick_event_source());
}
if (Graphics::the_display != NULL){
al_register_event_source(queue, al_get_display_event_source(Graphics::the_display));
}
#endif
}
#ifdef USE_SDL
static void handleKeyDown(Keyboard & keyboard, const SDL_Event & event){
keyboard.press(event.key.keysym.sym, event.key.keysym.unicode);
}
static void handleKeyUp(Keyboard & keyboard, const SDL_Event & event){
keyboard.release(event.key.keysym.sym);
}
static void handleJoystickButtonUp(map<int, ReferenceCount<Joystick> > joysticks, const SDL_Event & event){
int device = event.jbutton.which;
int button = event.jbutton.button;
ReferenceCount<Joystick> joystick = joysticks[device];
if (joystick != NULL){
joystick->releaseButton(button);
}
}
static void handleJoystickHat(map<int, ReferenceCount<Joystick> > joysticks, const SDL_Event & event){
int device = event.jhat.which;
int motion = event.jhat.value;
ReferenceCount<Joystick> joystick = joysticks[device];
if (joystick != NULL){
joystick->hatMotion(motion);
}
#if 0
/* should up/down control left/right -- flip these values? */
#if WII
const int axis_up_down = 0;
const int axis_left_right = 1;
const int up = 1;
const int down = -1;
const int left = -1;
const int right = 1;
#else
const int axis_up_down = 1;
const int axis_left_right = 0;
const int up = -1;
const int down = 1;
const int left = -1;
const int right = 1;
#endif
switch (motion){
case SDL_HAT_CENTERED: break;
case SDL_HAT_UP: joystick->axisMotion(axis_up_down, up); break;
case SDL_HAT_DOWN: joystick->axisMotion(axis_up_down, down); break;
case SDL_HAT_RIGHT: joystick->axisMotion(axis_left_right, right); break;
case SDL_HAT_LEFT: joystick->axisMotion(axis_left_right, left); break;
default: break;
}
#endif
}
static void handleJoystickButtonDown(map<int, ReferenceCount<Joystick> > joysticks, const SDL_Event & event){
int device = event.jbutton.which;
int button = event.jbutton.button;
ReferenceCount<Joystick> joystick = joysticks[device];
if (joystick != NULL){
joystick->pressButton(button);
}
}
static void handleJoystickAxis(map<int, ReferenceCount<Joystick> > joysticks, const SDL_Event & event){
int device = event.jaxis.which;
int axis = event.jaxis.axis;
int value = event.jaxis.value;
ReferenceCount<Joystick> joystick = joysticks[device];
if (joystick != NULL){
joystick->axisMotion(axis, value);
}
}
void EventManager::runSDL(Keyboard & keyboard, map<int, ReferenceCount<Joystick> > joysticks){
keyboard.poll();
for (map<int, ReferenceCount<Joystick> >::iterator it = joysticks.begin(); it != joysticks.end(); it++){
ReferenceCount<Joystick> joystick = it->second;
if (joystick != NULL){
joystick->poll();
}
}
SDL_Event event;
/* FIXME: android gets into an infinite loop while reading events */
#ifdef ANDROID
// int good = SDL_PollEvent(&event);
// for (int check = 0; check < 10 && good; check++, good = SDL_PollEvent(&event)){
// if (SDL_PollEvent(&event) == 1){
while (SDL_PollEvent(&event) == 1){
#else
while (SDL_PollEvent(&event) == 1){
#endif
switch (event.type){
case SDL_QUIT : {
dispatch(CloseWindow);
break;
}
case SDL_KEYDOWN : {
handleKeyDown(keyboard, event);
// dispatch(Key, event.key.keysym.sym);
break;
}
case SDL_KEYUP : {
handleKeyUp(keyboard, event);
break;
}
case SDL_JOYBUTTONDOWN: {
handleJoystickButtonDown(joysticks, event);
break;
}
case SDL_JOYHATMOTION : {
handleJoystickHat(joysticks, event);
break;
}
case SDL_JOYBUTTONUP: {
handleJoystickButtonUp(joysticks, event);
break;
}
case SDL_JOYAXISMOTION: {
handleJoystickAxis(joysticks, event);
break;
}
case SDL_VIDEORESIZE : {
int width = event.resize.w;
int height = event.resize.h;
/* to keep the perspective correct
* 640/480 = 1.33333
*/
/*
double ratio = (double) 640 / (double) 480;
if (width > height){
height = (int)((double) width / ratio);
} else {
width = (int)((double) height * ratio);
}
*/
dispatch(ResizeScreen, width, height);
break;
}
default : {
break;
}
}
}
}
#endif
#ifdef USE_ALLEGRO
void EventManager::runAllegro(Keyboard & keyboard, map<int, ReferenceCount<Joystick> > joystick){
keyboard.poll();
}
#endif
#ifdef USE_ALLEGRO5
static void handleKeyDown(Keyboard & keyboard, const ALLEGRO_EVENT & event){
keyboard.press(event.keyboard.keycode, event.keyboard.unichar);
}
static void handleKeyUp(Keyboard & keyboard, const ALLEGRO_EVENT & event){
keyboard.release(event.keyboard.keycode);
}
static void handleResize(const ALLEGRO_EVENT & event){
double width = event.display.width;
double height = event.display.height;
/*
if (width < 640){
width = 640;
}
if (height < 480){
height = 480;
}
*/
/* to keep the perspective correct
* 640/480 = 1.33333
*/
/*
double ratio = (double) 640 / (double) 480;
if (width > height){
height = width / ratio;
} else {
width = height * ratio;
}
*/
ALLEGRO_DISPLAY * display = event.display.source;
al_acknowledge_resize(display);
Configuration::setScreenWidth((int) width);
Configuration::setScreenHeight((int) height);
al_resize_display(display, (int) width, (int) height);
Graphics::getScreenBuffer()->clear();
/*
ALLEGRO_TRANSFORM transformation;
al_identity_transform(&transformation);
// al_scale_transform(&transformation, (double) al_get_display_width(display) / (double) GFX_X, (double) al_get_display_height(display) / (double) GFX_Y);
al_scale_transform(&transformation, (double) width / (double) GFX_X, (double) height / (double) GFX_Y);
al_set_target_bitmap(Graphics::getScreenBuffer()->getData()->getBitmap());
al_use_transform(&transformation);
*/
}
void EventManager::runAllegro5(Keyboard & keyboard, const map<int, ReferenceCount<Joystick> > & joysticks){
keyboard.poll();
for (map<int, ReferenceCount<Joystick> >::const_iterator it = joysticks.begin(); it != joysticks.end(); it++){
ReferenceCount<Joystick> joystick = it->second;
if (joystick != NULL){
joystick->poll();
}
}
ALLEGRO_EVENT event;
while (al_get_next_event(queue, &event)){
switch (event.type){
/*
case ALLEGRO_EVENT_KEY_DOWN: {
Global::debug(0) << "Key down " << event.keyboard.keycode << std::endl;
handleKeyDown(keyboard, event);
break;
}
*/
case ALLEGRO_EVENT_DISPLAY_RESIZE: {
handleResize(event);
break;
}
case ALLEGRO_EVENT_DISPLAY_CLOSE: {
throw ShutdownException();
break;
}
case ALLEGRO_EVENT_KEY_UP: {
handleKeyUp(keyboard, event);
break;
}
case ALLEGRO_EVENT_KEY_CHAR : {
// Global::debug(0) << "Key char " << event.keyboard.keycode << " unicode " << event.keyboard.unichar << std::endl;
bool ok = true;
if (event.keyboard.repeat){
ok = Keyboard::getRepeatState();
}
if (ok){
handleKeyDown(keyboard, event);
}
break;
}
case ALLEGRO_EVENT_JOYSTICK_CONFIGURATION: {
/* FIXME: tell input manager to reconfigure joysticks */
// al_reconfigure_joysticks();
break;
}
}
}
/*
if (joystick){
joystick->poll();
}
SDL_Event event;
while (SDL_PollEvent(&event) == 1){
switch (event.type){
case SDL_QUIT : {
dispatch(CloseWindow);
break;
}
case SDL_KEYDOWN : {
handleKeyDown(keyboard, event);
// dispatch(Key, event.key.keysym.sym);
break;
}
case SDL_KEYUP : {
handleKeyUp(keyboard, event);
break;
}
case SDL_JOYBUTTONDOWN: {
if (joystick != NULL){
handleJoystickButtonDown(joystick, event);
}
break;
}
case SDL_JOYHATMOTION : {
if (joystick != NULL){
handleJoystickHat(joystick, event);
}
break;
}
case SDL_JOYBUTTONUP: {
if (joystick != NULL){
handleJoystickButtonUp(joystick, event);
}
break;
}
case SDL_JOYAXISMOTION: {
if (joystick != NULL){
handleJoystickAxis(joystick, event);
}
break;
}
case SDL_VIDEORESIZE : {
int width = event.resize.w;
int height = event.resize.h;
/ * to keep the perspective correct
* 640/480 = 1.33333
* /
if (width > height){
height = (int)((double) width / 1.3333333333);
} else {
width = (int)((double) height * 1.3333333333);
}
dispatch(ResizeScreen, width, height);
break;
}
default : {
break;
}
}
}
*/
}
#endif
void EventManager::run(Keyboard & keyboard, std::map<int, ReferenceCount<Joystick> > joysticks){
#ifdef USE_SDL
runSDL(keyboard, joysticks);
#elif USE_ALLEGRO
runAllegro(keyboard, joysticks);
#elif USE_ALLEGRO5
runAllegro5(keyboard, joysticks);
#endif
}
/* kill the program if the user requests */
void EventManager::waitForThread(WaitThread & thread){
// Keyboard dummy;
while (!thread.isRunning()){
try{
/* input manager will run the event manager */
InputManager::poll();
// run(dummy);
} catch (const ShutdownException & death){
thread.kill();
throw death;
}
Util::rest(10);
}
}
EventManager::~EventManager(){
#ifdef USE_ALLEGRO5
al_destroy_event_queue(queue);
#endif
}
void EventManager::enableKeyBuffer(){
bufferKeys = true;
}
void EventManager::disableKeyBuffer(){
bufferKeys = false;
}
void EventManager::dispatch(Event type, int arg1){
switch (type){
case Key : {
if (bufferKeys){
keys.push_back(KeyType(arg1));
}
break;
}
default : {
break;
}
}
}
void EventManager::dispatch(Event type, int arg1, int arg2){
switch (type){
case ResizeScreen : {
if (deferResize){
resize.type = ResizeScreen;
resize.width = arg1;
resize.height = arg2;
resize.enable = true;
} else {
Global::debug(1) << "Resizing screen to " << arg1 << ", " << arg2 << std::endl;
if (Graphics::setGraphicsMode(0, arg1, arg2) == 0){
Configuration::setScreenWidth(arg1);
Configuration::setScreenHeight(arg2);
}
}
break;
}
default: break;
}
}
void EventManager::dispatch(Event type){
switch (type){
case CloseWindow : {
throw ShutdownException();
}
default : break;
}
}
void EventManager::deferResizeEvents(bool defer){
deferResize = defer;
if (!deferResize && resize.enable){
dispatch(resize.type, resize.width, resize.height);
resize.enable = false;
}
}
class LoopDone: public std::exception {
public:
LoopDone(){
}
~LoopDone() throw () {
}
};
Logic::~Logic(){
}
Draw::Draw():
frames(0),
second_counter(Global::second_counter),
fps(0){
}
void Draw::drawFirst(const Graphics::Bitmap & screen){
draw(screen);
}
Draw::~Draw(){
}
double Draw::getFps() const {
return fps;
}
void Draw::updateFrames(){
if (second_counter != Global::second_counter){
int difference = Global::second_counter - second_counter;
double alpha = 0.2;
/* unlikely, but just in case */
if (difference == 0){
difference = 1;
}
fps = (alpha * fps) + ((1 - alpha) * (double) frames / difference);
// fps[fps_index] = (double) frames / (double) difference;
// fps_index = (fps_index+1) % max_fps_index;
second_counter = Global::second_counter;
frames = 0;
}
frames += 1;
}
static void changeScreenMode(){
Configuration::setFullscreen(!Configuration::getFullscreen());
int gfx = (Configuration::getFullscreen() ? Global::FULLSCREEN : Global::WINDOWED);
Graphics::changeGraphicsMode(gfx, Graphics::Bitmap::getScreenWidth(), Graphics::Bitmap::getScreenHeight());
}
static void checkFullscreen(){
InputMap<int> input;
input.set(Keyboard::Key_F11, 0, true, 5);
std::vector<InputMap<int>::InputEvent> events = InputManager::getEvents(input, InputSource(true));
for (std::vector<InputMap<int>::InputEvent>::iterator it = events.begin(); it != events.end(); it++){
InputMap<int>::InputEvent event = *it;
if (!event.enabled){
continue;
}
if (event.out == 5){
changeScreenMode();
}
}
}
static void doStandardLoop(Logic & logic, Draw & draw){
if (Graphics::screenParameter.current() == NULL){
throw Exception::Base(__FILE__, __LINE__);
}
const Graphics::Bitmap & screen = *Graphics::screenParameter.current();
screen.clear();
draw.drawFirst(screen.aspectRatio(640, 480));
screen.BlitToScreen();
Global::speed_counter4 = 0;
double runCounter = 0;
try{
const int maxCount = 20;
int frameCount = 0;
uint64_t frameTime = 0;
int logicCount = 0;
uint64_t logicTime = 0;
while (!logic.done()){
if (Global::speed_counter4 > 0){
// Global::debug(0) << "Speed counter " << Global::speed_counter4 << std::endl;
runCounter += logic.ticks(Global::speed_counter4);
Global::speed_counter4 = 0;
bool need_draw = false;
while (runCounter >= 1.0){
need_draw = true;
InputManager::poll();
checkFullscreen();
runCounter -= 1;
logicCount += 1;
uint64_t now = System::currentMilliseconds();
logic.run();
uint64_t later = System::currentMilliseconds();
logicTime += (later - now);
if (logicCount >= maxCount){
// Global::debug(0) << "Logic average " << (logicTime / logicCount) << "ms" << std::endl;
logicCount = 0;
logicTime = 0;
}
if (shutdown()){
throw ShutdownException();
}
if (logic.done()){
/* quit the loop immediately */
throw LoopDone();
}
}
if (need_draw){
frameCount += 1;
draw.updateFrames();
uint64_t now = System::currentMilliseconds();
screen.clear();
draw.draw(screen.aspectRatio(640, 480));
screen.BlitToScreen();
uint64_t later = System::currentMilliseconds();
frameTime += (later - now);
if (frameCount >= maxCount){
// Global::debug(0) << "Draw average " << (frameTime / frameCount) << "ms" << std::endl;
frameCount = 0;
frameTime = 0;
}
}
}
while (Global::speed_counter4 == 0){
/* if the fps is limited then don't keep redrawing */
if (Global::rateLimit){
rest(1);
} else {
draw.updateFrames();
screen.clear();
draw.draw(screen.aspectRatio(640, 480));
screen.BlitToScreen();
}
}
}
} catch (const LoopDone & done){
}
}
void standardLoop(Logic & logic, Draw & draw){
/* if a screen already exists (because we have nested standardLoops) then
* leave this parameter alone, otherwise set a new parameter.
*/
/*
if (Parameter<Graphics::Bitmap*>::current() == NULL){
doStandardLoop(logic, draw);
} else {
doStandardLoop(logic, draw);
}
*/
doStandardLoop(logic, draw);
}
}
diff --git a/src/exceptions/exception.cpp b/src/exceptions/exception.cpp
index b7a5be5b..1467c93b 100644
--- a/src/exceptions/exception.cpp
+++ b/src/exceptions/exception.cpp
@@ -1,119 +1,119 @@
-#include "exception.h"
+#include "r-tech1/exceptions/exception.h"
#include <string>
#include <exception>
#include <sstream>
namespace Exception{
Base::Base(const std::string & file, int line):
file(file),
line(line),
nested(NULL){
}
Base::Base(const std::string & file, int line, const Base & nested):
file(file),
line(line),
nested(nested.copy()){
}
Base::~Base() throw (){
if (nested){
delete nested;
}
}
const std::string Base::getReason() const {
return "reason not given";
}
const std::string Base::getTrace() const {
std::ostringstream out;
out << file << ":" << line << " " << getReason();
if (nested != NULL){
out << "\n";
out << nested->getTrace();
}
return out.str();
}
Base::Base(const Base & copy):
file(copy.file),
line(copy.line),
nested(NULL){
if (copy.nested != NULL){
nested = copy.nested->copy();
}
}
void Base::set(const Base & him){
nested = him.copy();
}
Base * Base::copy() const {
return new Base(*this);
}
Return::Return(const std::string & file, int line):
Base(file, line){
}
Return::Return(const std::string & file, int line, const Base & nested):
Base(file, line, nested){
}
Return::~Return() throw(){
}
void Return::throwSelf() const {
throw *this;
}
Base * Return::copy() const {
return new Return(*this);
}
Quit::Quit(const std::string & file, int line):
Base(file, line){
}
Quit::Quit(const std::string & file, int line, const Base & nested):
Base(file, line, nested){
}
Quit::~Quit() throw(){
}
void Quit::throwSelf() const {
throw *this;
}
Base * Quit::copy() const {
return new Quit(*this);
}
FontException::FontException(const std::string & file, int line, const std::string & reason):
Base(file, line),
reason(reason){
}
FontException::FontException(const std::string & file, int line, const Base & nested, const std::string & reason):
Base(file, line, nested),
reason(reason){
}
FontException::~FontException() throw(){
}
const std::string FontException::getReason() const {
return reason;
}
void FontException::throwSelf() const {
throw *this;
}
Base * FontException::copy() const {
}
}
diff --git a/src/exceptions/load_exception.cpp b/src/exceptions/load_exception.cpp
index 8f79143d..535a2829 100644
--- a/src/exceptions/load_exception.cpp
+++ b/src/exceptions/load_exception.cpp
@@ -1,30 +1,30 @@
#include <string>
-#include "load_exception.h"
+#include "r-tech1/exceptions/load_exception.h"
using namespace std;
LoadException::LoadException(const string & file, int line, const string & reason):
Exception::Base(file, line),
reason(reason){
}
LoadException::LoadException(const std::string & file, int line, const Exception::Base & nested, const std::string & reason):
Exception::Base(file, line, nested),
reason(reason){
}
LoadException::~LoadException() throw (){
}
LoadException::LoadException(const LoadException & copy):
Exception::Base(copy),
reason(copy.reason){
}
Exception::Base * LoadException::copy() const {
return new LoadException(*this);
}
const std::string LoadException::getReason() const {
return reason;
}
diff --git a/src/file-system.cpp b/src/file-system.cpp
index 7ad04f90..100ddcf3 100644
--- a/src/file-system.cpp
+++ b/src/file-system.cpp
@@ -1,1895 +1,1895 @@
#ifdef USE_ALLEGRO
#include <allegro.h>
/* FIXME: replace with <winalleg.h> */
#ifdef _WIN32
#define BITMAP dummyBITMAP
#include <windows.h>
#undef BITMAP
#endif
#endif
#include <algorithm>
-#include "funcs.h"
-#include "file-system.h"
-#include "thread.h"
-#include "system.h"
-#include "utf.h"
+#include "r-tech1/funcs.h"
+#include "r-tech1/file-system.h"
+#include "r-tech1/thread.h"
+#include "r-tech1/system.h"
+#include "r-tech1/utf.h"
// #include "globals.h"
#include <dirent.h>
#include <sstream>
#include <exception>
#include <string>
#include <fstream>
#include <ostream>
-#include "token.h"
+#include "r-tech1/token.h"
-#include "zip/unzip.h"
-#include "zip/ioapi.h"
+#include "libs/zip/unzip.h"
+#include "libs/zip/ioapi.h"
-#include "7z/7zFile.h"
-#include "7z/7z.h"
-#include "7z/7zAlloc.h"
-#include "7z/7zCrc.h"
+#include "libs/7z/7zFile.h"
+#include "libs/7z/7z.h"
+#include "libs/7z/7zAlloc.h"
+#include "libs/7z/7zCrc.h"
#ifndef USE_ALLEGRO
/* some sfl symbols conflict with allegro */
-#include "sfl/sfl.h"
-#include "sfl/sfldir.h"
+#include "libs/sfl/sfl.h"
+#include "libs/sfl/sfldir.h"
#endif
#ifdef _WIN32
// #define _WIN32_IE 0x400
#include <shlobj.h>
#endif
using namespace std;
/* some filesystem access can only be done by one thread at a time. specifically, sfl
* has its own allocator that is meant to be used in a single-threaded manner.
* rather than try to add locks to sfl we just wrap all sfl calls with a lock.
*
* initialize() must be called to initialize this lock
*/
// Util::Thread::Lock lock;
namespace Path{
/* remove extra path separators (/) */
string sanitize(string path){
size_t double_slash = path.find("//");
while (double_slash != string::npos){
path.erase(double_slash, 1);
double_slash = path.find("//");
}
/* Remove /./ from paths because its redundant */
size_t useless = path.find("/./");
while (useless != string::npos){
path.erase(useless, 2);
useless = path.find("/./");
}
return path;
}
static string removeEndSlashes(string path){
size_t last = path.rfind("/");
while (path.size() > 0 && last == path.size() - 1){
path.erase(last, 1);
last = path.rfind("/");
}
return path;
}
static int invert(int c){
if (c == '\\'){
return '/';
}
return c;
}
std::string invertSlashes(string str){
transform(str.begin(), str.end(), str.begin(), invert);
return str;
}
const string & Path::path() const {
return mypath;
}
const string Path::getExtension() const {
size_t dot = mypath.rfind('.');
if (dot == string::npos){
return "";
} else {
return mypath.substr(dot + 1);
}
}
bool Path::isEmpty() const {
return mypath.empty();
}
Path::~Path(){
}
Path::Path(){
}
Path::Path(const std::string & path):
mypath(sanitize(invertSlashes(path))){
}
Path::Path(const Path & path):
mypath(sanitize(invertSlashes(path.path()))){
}
RelativePath::RelativePath(){
}
RelativePath::RelativePath(const std::string & path):
Path(path){
if (! path.empty() && path[0] == '/'){
ostringstream out;
out << "Relative path '" << path << "' cannot start with a /. Only absolute paths can start with /";
throw Storage::IllegalPath(__FILE__, __LINE__, out.str());
}
}
/* a/b/c/d -> b/c/d */
std::string stripFirstDir(const std::string & str){
if (str.find("/") != std::string::npos || str.find( "\\") != std::string::npos){
std::string temp = str;
size_t rem = temp.find("/");
if (rem != std::string::npos){
return str.substr(rem+1,str.size());
}
rem = temp.find("\\");
if( rem != std::string::npos ){
return str.substr(rem+1,str.size());
}
}
return str;
}
static vector<string> splitPath(string path){
vector<string> all;
if (path.size() > 0 && path[0] == '/'){
all.push_back("/");
}
size_t found = path.find('/');
while (found != string::npos){
if (found > 0){
all.push_back(path.substr(0, found));
}
path.erase(0, found + 1);
found = path.find('/');
}
if (path.size() != 0){
all.push_back(path);
}
return all;
}
static string joinPath(const vector<string> & paths){
ostringstream out;
bool first = true;
for (vector<string>::const_iterator it = paths.begin(); it != paths.end(); it++){
if (!first){
out << '/';
}
out << *it;
first = false;
}
return out.str();
}
/* a/b/c/d -> a/b/c
* a/b/c/d/ -> a/b/c
*/
static string dirname(string path){
vector<string> paths = splitPath(path);
if (paths.size() > 1){
paths.pop_back();
return joinPath(paths);
} else if (paths.size() == 1){
if (paths[0] == "/"){
return "/";
}
return ".";
} else {
return ".";
}
/*
while (path.size() > 0 && path[path.size() - 1] == '/'){
path.erase(path.size() - 1);
}
if (path.find("/") != string::npos ||
path.find("\\") != string::npos){
size_t rem = path.find_last_of("/");
if (rem != string::npos){
return path.substr(0, rem + 1);
}
rem = path.find_last_of("\\");
if (rem != string::npos){
return path.substr(0, rem + 1);
}
}
return "";
*/
}
RelativePath::RelativePath(const RelativePath & path):
Path(path){
}
RelativePath RelativePath::removeFirstDirectory() const {
return RelativePath(stripFirstDir(path()));
}
bool RelativePath::isFile() const {
vector<string> paths = splitPath(path());
return paths.size() == 1;
}
RelativePath RelativePath::firstDirectory() const {
vector<string> paths = splitPath(path());
if (paths.size() > 1){
return RelativePath(paths[0]);
}
return RelativePath();
}
RelativePath RelativePath::getDirectory() const {
return RelativePath(dirname(path()));
}
RelativePath RelativePath::getFilename() const {
return RelativePath(stripDir(path()));
}
bool RelativePath::operator<(const RelativePath & path) const {
return this->path() < path.path();
}
bool RelativePath::operator==(const RelativePath & path) const {
return this->path() == path.path();
}
bool RelativePath::operator!=(const RelativePath & path) const {
return !(*this == path);
}
RelativePath RelativePath::join(const RelativePath & him) const {
return RelativePath(path() + "/" + him.path());
}
RelativePath & RelativePath::operator=(const RelativePath & copy){
setPath(copy.path());
return *this;
}
AbsolutePath::AbsolutePath(){
}
AbsolutePath::AbsolutePath(const std::string & path):
Path(path){
}
AbsolutePath::AbsolutePath(const AbsolutePath & path):
Path(path){
}
AbsolutePath & AbsolutePath::operator=(const AbsolutePath & copy){
setPath(copy.path());
return *this;
}
AbsolutePath AbsolutePath::removeFirstDirectory() const {
return AbsolutePath(stripFirstDir(path()));
}
bool AbsolutePath::operator==(const AbsolutePath & path) const {
return removeEndSlashes(this->path()) == removeEndSlashes(path.path());
}
bool AbsolutePath::operator!=(const AbsolutePath & path) const {
return !(*this == path);
}
bool AbsolutePath::operator<(const AbsolutePath & path) const {
return this->path() < path.path();
}
string AbsolutePath::firstDirectory() const {
vector<string> paths = splitPath(path());
if (paths.size() > 1){
return paths[0];
}
return removeEndSlashes(path());
}
bool AbsolutePath::isFile() const {
vector<string> paths = splitPath(path());
return path().find("/") == string::npos;
// paths.size() == 1;
}
RelativePath AbsolutePath::remove(const AbsolutePath & what) const {
string real = path();
real.erase(0, what.path().size());
while (real.find("/") == 0){
real.erase(0, 1);
}
return RelativePath(real);
}
AbsolutePath AbsolutePath::getDirectory() const {
return AbsolutePath(dirname(path()));
}
AbsolutePath AbsolutePath::getFilename() const {
return AbsolutePath(stripDir(path()));
}
std::string AbsolutePath::getLastComponent() const {
if (getFilename().path() == ""){
return stripDir(removeEndSlashes(path()));
}
return getFilename().path();
}
AbsolutePath AbsolutePath::join(const RelativePath & path) const {
return AbsolutePath(this->path() + "/" + path.path());
}
InsensitivePath::InsensitivePath(const Path & what):
Path(what){
}
bool InsensitivePath::operator==(const Path & path) const {
return Util::upperCaseAll(this->path()) == Util::upperCaseAll(path.path());
}
std::string removeExtension(const std::string & str){
if (str.find(".") != std::string::npos){
return str.substr(0, str.find_last_of("."));
}
return str;
}
AbsolutePath replaceExtension(const Filesystem::AbsolutePath & input, const std::string & extension){
return AbsolutePath(removeExtension(input.path()) + "." + extension);
}
/* a/b/c/d -> d */
std::string stripDir(const std::string & str){
if (str.find("/") != std::string::npos || str.find("\\") != std::string::npos){
std::string temp = str;
size_t rem = temp.find_last_of( "/" );
if (rem != std::string::npos){
return str.substr(rem+1,str.size());
}
rem = temp.find_last_of( "\\" );
if( rem != std::string::npos ){
return str.substr(rem+1,str.size());
}
}
return str;
}
/* a/b/c/d -> a/b/c/ */
std::string stripFilename(const std::string & str){
std::string temp = str;
if( str.find( "/") != std::string::npos || str.find( "\\") != std::string::npos ){
size_t rem = temp.find_last_of( "/" );
if( rem != std::string::npos ){
return str.substr(0,rem+1);
}
rem = temp.find_last_of( "\\" );
if( rem != std::string::npos ){
return str.substr(0,rem+1);
}
}
return "";
}
}
namespace Storage{
Exception::Exception(const std::string & where, int line, const std::string & file):
Exc::Base(where, line),
reason(file){
}
Exception::Exception(const std::string & where, int line, const Exc::Base & nested, const std::string & file):
Exc::Base(where, line, nested),
reason(file){
}
Exception::Exception(const Exception & copy):
Exc::Base(copy),
reason(copy.reason){
}
Exception::~Exception() throw (){
}
const std::string Exception::getReason() const {
return reason;
}
NotFound::NotFound(const std::string & where, int line, const std::string & file):
Exception(where, line, file){
}
NotFound::NotFound(const std::string & where, int line, const Exc::Base & nested, const std::string & file):
Exception(where, line, nested, file){
}
NotFound::NotFound(const NotFound & copy):
Exception(copy){
}
NotFound::~NotFound() throw (){
}
IllegalPath::IllegalPath(const std::string & where, int line, const std::string & file):
Exception(where, line, file){
}
IllegalPath::IllegalPath(const std::string & where, int line, const Exc::Base & nested, const std::string & file):
Exception(where, line, nested, file){
}
IllegalPath::IllegalPath(const IllegalPath & copy):
Exception(copy){
}
IllegalPath::~IllegalPath() throw(){
}
System::System(){
}
System::~System(){
}
vector<Filesystem::AbsolutePath> System::getFiles(const Filesystem::AbsolutePath & dataPath, const Filesystem::RelativePath & find, bool caseInsensitive){
if (find.isFile()){
return getFiles(dataPath, find.path(), caseInsensitive);
}
/* split the path into its consituent parts
* a/b/c -> a/b and c
* search for a/b, then search for c in the results
*/
Filesystem::RelativePath directory = find.getDirectory();
Filesystem::RelativePath file = find.getFilename();
vector<Filesystem::AbsolutePath> more = getFiles(dataPath, directory, caseInsensitive);
vector<Filesystem::AbsolutePath> out;
for (vector<Filesystem::AbsolutePath>::iterator it = more.begin(); it != more.end(); it++){
Filesystem::AbsolutePath path = *it;
/* if its not a directory then we can't keep searching */
if (::System::isDirectory(path.path())){
vector<Filesystem::AbsolutePath> findMore = getFiles(path, file, caseInsensitive);
out.insert(out.end(), findMore.begin(), findMore.end());
}
}
return out;
}
Filesystem::AbsolutePath System::findContainer(const RelativePath & dataPath){
try{
return find(RelativePath(dataPath.path() + ".zip"));
} catch (const NotFound & fail){
}
try{
return find(RelativePath(dataPath.path() + ".7z"));
} catch (const NotFound & fail){
}
throw NotFound(dataPath.path(), __LINE__, __FILE__);
}
vector<Filesystem::AbsolutePath> System::getContainerFilesRecursive(const Filesystem::AbsolutePath & dataPath){
vector<Filesystem::AbsolutePath> out;
vector<Filesystem::AbsolutePath> zips = getFilesRecursive(dataPath, "*.zip");
out.insert(out.end(), zips.begin(), zips.end());
zips = getFilesRecursive(dataPath, "*.7z");
out.insert(out.end(), zips.begin(), zips.end());
return out;
}
vector<Path::AbsolutePath> System::getContainerFiles(const AbsolutePath & dataPath){
vector<Filesystem::AbsolutePath> out;
vector<Filesystem::AbsolutePath> zips = getFiles(dataPath, "*.zip");
out.insert(out.end(), zips.begin(), zips.end());
zips = getFiles(dataPath, "*.7z");
out.insert(out.end(), zips.begin(), zips.end());
return out;
}
vector<Filesystem::AbsolutePath> System::getContainerFiles(const RelativePath & path){
vector<Filesystem::AbsolutePath> out;
vector<Filesystem::AbsolutePath> zips = getFiles(path, Filesystem::RelativePath("*.zip"), false);
out.insert(out.end(), zips.begin(), zips.end());
zips = getFiles(path, Filesystem::RelativePath("*.7z"), false);
out.insert(out.end(), zips.begin(), zips.end());
return out;
}
static Util::ReferenceCount<System> self;
System & instance(){
if (self != NULL){
return *self;
}
self = new Filesystem(Util::getDataPath2());
return *self;
}
File::File(){
}
File::~File(){
}
class NormalFile: public File {
public:
NormalFile(const Path::AbsolutePath & path, Access mode = Read):
path(path){
ios_base::openmode iosMode = fstream::in;
switch (mode){
case Read: iosMode = fstream::in; check(path); break;
case Write: iosMode = fstream::out; break;
case ReadWrite: iosMode = fstream::in | fstream::out; check(path); break;
}
in.open(path.path().c_str(), iosMode | fstream::binary);
if (in.good()){
in >> noskipws;
}
}
Token * location(){
Token * head = new Token();
*head << "file";
*head << path.path();
return head;
}
/* Throws NotFound if path doesnt exist */
void check(const Path::AbsolutePath & path){
if (!instance().systemExists(path)){
ostringstream out;
out << "Could not find '" << path.path() << "'";
throw NotFound(__FILE__, __LINE__, out.str());
}
}
long getModificationTime(){
return ::System::getModificationTime(path.path());
}
bool canStream(){
return true;
}
long tell(){
return in.tellg();
}
void reset(){
in.clear();
}
off_t seek(off_t position, int whence){
switch (whence){
case SEEK_SET: in.seekg(position, ios::beg); break;
case SEEK_CUR: in.seekg(position, ios::cur); break;
case SEEK_END: in.seekg(position, ios::end); break;
}
return in.tellg();
}
bool eof(){
return in.eof();
}
int getSize(){
streampos here = in.tellg();
in.seekg(0, ios::end);
int length = in.tellg();
in.seekg(here, ios::beg);
return length;
}
bool good(){
return in.good();
}
File & operator>>(unsigned char & c){
in >> c;
return *this;
}
int readLine(char * output, int size){
in.read(output, size);
return in.gcount();
}
~NormalFile(){
in.close();
}
protected:
const Path::AbsolutePath path;
std::fstream in;
};
StringFile::StringFile(const std::string & start):
data(start),
stream(start){
stream >> noskipws;
}
Token * StringFile::location(){
Token * head = new Token();
*head << "<string file>";
return head;
}
long StringFile::getModificationTime(){
/* FIXME: maybe return INT_MAX or something? */
return 0;
}
void StringFile::reset(){
/* TODO or nothing..? */
}
int StringFile::readLine(char * output, int size){
stream.read(output, size);
return stream.gcount();
}
bool StringFile::canStream(){
return true;
}
int StringFile::getSize(){
return data.size();
}
long StringFile::tell(){
return stream.tellg();
}
off_t StringFile::seek(off_t position, int whence){
switch (whence){
case SEEK_SET: stream.seekg(position, ios::beg); break;
case SEEK_CUR: stream.seekg(position, ios::cur); break;
case SEEK_END: stream.seekg(position, ios::end); break;
}
return stream.tellg();
}
bool StringFile::eof(){
return stream.eof();
}
bool StringFile::good(){
return stream.good();
}
File & StringFile::operator>>(unsigned char & c){
stream >> c;
return *this;
}
StringFile::~StringFile(){
}
/* For 7z */
class LzmaContainer{
public:
LzmaContainer(const string & path, const Filesystem::AbsolutePath & start):
path(path),
start(start){
allocator.Alloc = SzAlloc;
allocator.Free = SzFree;
allocatorTemporary.Alloc = SzAllocTemp;
allocatorTemporary.Free = SzFreeTemp;
if (InFile_Open(&archiveStream.file, path.c_str())){
/* Error */
}
FileInStream_CreateVTable(&archiveStream);
LookToRead_CreateVTable(&lookStream, False);
lookStream.realStream = &archiveStream.s;
LookToRead_Init(&lookStream);
CrcGenerateTable();
SzArEx_Init(&database);
int ok = SzArEx_Open(&database, &lookStream.s, &allocator, &allocatorTemporary);
if (ok == SZ_OK){
/* Can read files */
UInt16 * name = NULL;
size_t tempSize = 0;
for (unsigned int index = 0; index < database.db.NumFiles; index++){
size_t offset = 0;
size_t outSizeProcessed = 0;
const CSzFileItem * file = database.db.Files + index;
size_t length;
if (file->IsDir){
continue;
}
length = SzArEx_GetFileNameUtf16(&database, index, NULL);
if (length > tempSize){
delete[] name;
name = new UInt16[length];
memset(name, 0, length);
tempSize = length;
}
SzArEx_GetFileNameUtf16(&database, index, name);
files[Utf::utf16_to_utf8(name)] = index;
}
delete[] name;
}
}
void readFile(const Path::AbsolutePath & path, unsigned char ** buffer, size_t * size){
Path::RelativePath find(path.remove(start));
*buffer = 0;
*size = 0;
if (files.find(find.path()) != files.end()){
int index = files[find.path()];
UInt32 block = 0;
size_t offset = 0;
size_t processed = 0;
int ok = SzArEx_Extract(&database, &lookStream.s, index,
&block, buffer, size, &offset, &processed,
&allocator, &allocatorTemporary);
if (ok != SZ_OK){
Global::debug(0) << "Could not read file from 7z archive: " << path.path() << endl;
return;
}
if (offset != 0){
memmove(*buffer, *buffer + offset, processed);
}
/* The original size is the size of the block buffer, but we only care
* about the size of the actual file.
*/
*size = processed;
}
}
vector<string> getFiles(){
vector<string> names;
for (map<string, int>::iterator it = files.begin(); it != files.end(); it++){
names.push_back(it->first);
}
return names;
}
string getPath() const {
return path;
}
string getMount() const {
return start.path();
}
long getModificationTime(const Path::AbsolutePath & path){
if (files.find(path.path()) != files.end()){
int index = files[path.path()];
const CSzFileItem * file = database.db.Files + index;
if (file->MTimeDefined){
CNtfsFileTime time = file->MTime;
/* Divide by 10 million here? */
return (time.Low | ((UInt64)time.High << 32)) / 10000000;
/*
unsigned year, mon, day, hour, min, sec;
UInt64 v64 = (time.Low | ((UInt64)time.High << 32)) / 10000000;
Byte ms[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
unsigned t;
UInt32 v;
sec = (unsigned)(v64 % 60); v64 /= 60;
min = (unsigned)(v64 % 60); v64 /= 60;
hour = (unsigned)(v64 % 24); v64 /= 24;
v = (UInt32)v64;
const int PERIOD_4 = (4 * 365 + 1);
const int PERIOD_100 = (PERIOD_4 * 25 - 1);
const int PERIOD_400 = (PERIOD_100 * 4 + 1);
year = (unsigned)(1601 + v / PERIOD_400 * 400);
v %= PERIOD_400;
t = v / PERIOD_100; if (t == 4) t = 3; year += t * 100; v -= t * PERIOD_100;
t = v / PERIOD_4; if (t == 25) t = 24; year += t * 4; v -= t * PERIOD_4;
t = v / 365; if (t == 4) t = 3; year += t; v -= t * 365;
if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)){
ms[1] = 29;
}
for (mon = 1; mon <= 12; mon++){
unsigned s = ms[mon - 1];
if (v < s)
break;
v -= s;
}
day = (unsigned)v + 1;
struct tm outTime;
memset(&outTime, 0, sizeof(outTime));
outTime.tm_sec = sec;
outTime.tm_min = min;
outTime.tm_hour = hour;
outTime.tm_mday = day;
outTime.tm_mon = mon;
/ * tm_year The number of years since 1900. * /
outTime.tm_year = year - 1900;
outTime.tm_isdst = -1;
return mktime(&outTime);
*/
}
}
return 0;
}
virtual ~LzmaContainer(){
SzArEx_Free(&database, &allocator);
File_Close(&archiveStream.file);
}
string path;
Path::AbsolutePath start;
CFileInStream archiveStream;
CLookToRead lookStream;
CSzArEx database;
ISzAlloc allocator;
ISzAlloc allocatorTemporary;
/* Map the filename to its index in the 7z database */
map<string, int> files;
};
/* overlays:
* add x/y.zip
* y.zip contains
* example.txt
* try to read x/example.txt, goto y.zip
* or y.zip could contain y/
*
* z.zip contains
* example.txt
*
* how can you prevent two zip files from providing the same files?
*/
class ZipContainer{
public:
ZipContainer(const string & path, const Filesystem::AbsolutePath & start):
path(path),
start(start),
locked(false){
zipFile = unzOpen(path.c_str());
if (zipFile == NULL){
throw Exception(__FILE__, __LINE__, "Could not open zip file");
}
if (unzGoToFirstFile(zipFile) != UNZ_OK){
throw Exception(__FILE__, __LINE__, "Could not get to first file");
}
do{
char filename[1024];
unz_file_info fileInfo;
unzGetCurrentFileInfo(zipFile, &fileInfo, filename, sizeof(filename), NULL, 0, NULL, 0);
files.push_back(string(filename));
} while (unzGoToNextFile(zipFile) != UNZ_END_OF_LIST_OF_FILE);
/*
zlib_filefunc64_32_def functions;
functions.open_file_func = __real_open;
functions.tell_file_func = __real_lseek;
functions.seek_file_func = __real_lseek;
*/
/*
unzFile zip = unzOpen(path.c_str());
unz_global_info info;
if (unzGetGlobalInfo(zip, &info) == UNZ_OK){
Global::debug(0) << "Entries: " << info.number_entry << std::endl;
}
if (unzGoToFirstFile(zip) != UNZ_OK){
throw Exception(__FILE__, __LINE__, "Could not get to first file");
}
do{
char filename[1024];
unz_file_info fileInfo;
unzGetCurrentFileInfo(zip, &fileInfo, filename, sizeof(filename), NULL, 0, NULL, 0);
Global::debug(0) << "Got file " << filename << std::endl;
Global::debug(0) << " Compressed " << fileInfo.compressed_size << " uncompressed " << fileInfo.uncompressed_size << std::endl;
} while (unzGoToNextFile(zip) != UNZ_END_OF_LIST_OF_FILE);
unzClose(zip);
*/
}
~ZipContainer(){
if (zipFile != NULL){
unzClose(zipFile);
}
}
string getPath() const {
return path;
}
string getMount() const {
return start.path();
}
long modificationTime(){
char filename[1024];
unz_file_info fileInfo;
unzGetCurrentFileInfo(zipFile, &fileInfo, filename, sizeof(filename), NULL, 0, NULL, 0);
struct tm outTime;
memset(&outTime, 0, sizeof(outTime));
outTime.tm_sec = fileInfo.tmu_date.tm_sec;
outTime.tm_min = fileInfo.tmu_date.tm_min;
outTime.tm_hour = fileInfo.tmu_date.tm_hour;
outTime.tm_mday = fileInfo.tmu_date.tm_mday;
outTime.tm_mon = fileInfo.tmu_date.tm_mon;
/* tm_year The number of years since 1900. */
outTime.tm_year = fileInfo.tmu_date.tm_year - 1900;
outTime.tm_isdst = -1;
return mktime(&outTime);
}
void findFile(const Path::AbsolutePath & file){
Path::RelativePath find(file.remove(start));
if (unzLocateFile(zipFile, find.path().c_str(), 2) != UNZ_OK){
Global::debug(0) << "Could not find " << find.path() << std::endl;
} else {
Global::debug(1) << "Found " << find.path() << " in zip file " << path << std::endl;
}
}
int currentFileSize(){
char filename[1024];
unz_file_info fileInfo;
unzGetCurrentFileInfo(zipFile, &fileInfo, filename, sizeof(filename), NULL, 0, NULL, 0);
return fileInfo.uncompressed_size;
}
int read(char * buffer, int size){
// Global::debug(0) << "offset before read " << unzGetOffset(zipFile) << " tell " << unztell(zipFile) << std::endl;
int got = unzReadCurrentFile(zipFile, buffer, size);
// Global::debug(0) << "offset after read " << unzGetOffset(zipFile) << " tell " << unztell(zipFile) << std::endl;
if (got <= 0){
throw Exception(__FILE__, __LINE__, "Could not read bytes from zip");
}
return got;
}
long tell(){
return unztell(zipFile);
}
void open(const Path::AbsolutePath & file){
if (locked){
std::ostringstream out;
char filename[1024];
unz_file_info fileInfo;
unzGetCurrentFileInfo(zipFile, &fileInfo, filename, sizeof(filename), NULL, 0, NULL, 0);
out << "Could not open zip file entry " << file.path() << " because a zip file is already open: " << filename;
throw Exception(__FILE__, __LINE__, out.str());
}
findFile(file);
if (unzOpenCurrentFile(zipFile) != UNZ_OK){
std::ostringstream out;
out << "Could not open zip file entry " << file.path();
throw Exception(__FILE__, __LINE__, out.str());
}
locked = true;
}
void close(){
unzCloseCurrentFile(zipFile);
locked = false;
}
vector<string> getFiles() const {
return files;
}
protected:
/* Path to the zip file itself */
const string path;
/* Where overlay starts */
const Path::AbsolutePath start;
unzFile zipFile;
vector<string> files;
/* Only one file can be opened at a time, so if another file is opened
* while locked=true then throw an error
*/
bool locked;
};
class ZipFile: public File {
public:
ZipFile(const Path::AbsolutePath & path, const Util::ReferenceCount<ZipContainer> & zip):
path(path),
zip(zip),
atEof(false),
position(0){
zip->open(path);
}
virtual ~ZipFile(){
zip->close();
}
long getModificationTime(){
return zip->modificationTime();
}
Token * location(){
Token * head = new Token();
*head << "container";
/* container zipfile mount-point file-inside-zip */
*head << zip->getPath();
*head << zip->getMount();
*head << path.path();
return head;
}
off_t seek(off_t where, int whence){
/* It seems that minizip is not capable of seeking in a specific file in a zip
* container so we have to re-open the file and read `position' bytes to
* emulate the seek behavior.
*/
switch (whence){
case SEEK_SET: {
if (where >= position){
/* Read bytes until we hit the offset */
position += skipBytes(where - position);
} else {
zip->close();
zip->open(path);
/* re-open file and read where bytes */
position = skipBytes(where);
}
break;
}
case SEEK_CUR: {
position += skipBytes(where);
break;
}
case SEEK_END: {
return seek(getSize() + where, SEEK_SET);
break;
}
}
if (position > getSize()){
position = getSize();
}
atEof = position == getSize();
return position;
}
bool eof(){
return atEof;
}
long tell(){
return zip->tell();
}
void reset(){
/* TODO or nothing..? */
}
bool canStream(){
return false;
}
bool good(){
/* FIXME */
return true;
}
File & operator>>(unsigned char & c){
readLine((char*) &c, 1);
return *this;
}
int getSize(){
return zip->currentFileSize();
}
int readLine(char * output, int size){
try{
int read = zip->read(output, size);
position += read;
return read;
} catch (const Exception & nomore){
atEof = true;
return 0;
}
}
protected:
/* skips `bytes'.
* returns number of bytes skipped (may be less than bytes)
*/
int skipBytes(int bytes){
char dummy[1024];
int total = 0;
while (bytes > 0){
/* Calls the zip file directly here so we don't mess up position */
int read = zip->read(dummy, bytes > (int) sizeof(dummy) ? (int) sizeof(dummy) : bytes);
total += read;
if (read == 0){
return total;
}
bytes -= read;
}
return total;
}
const Path::AbsolutePath path;
const Util::ReferenceCount<ZipContainer> zip;
bool atEof;
/* keep track of bytes read so we can seek easier */
int position;
};
Descriptor::Descriptor(){
}
Descriptor::~Descriptor(){
}
class ZipDescriptor: public Descriptor {
public:
ZipDescriptor(const Path::AbsolutePath & path, const Util::ReferenceCount<ZipContainer> & container):
path(path),
container(container){
}
Path::AbsolutePath path;
Util::ReferenceCount<ZipContainer> container;
using Descriptor::open;
virtual Util::ReferenceCount<File> open(File::Access mode){
return Util::ReferenceCount<File>(new ZipFile(path, container));
}
virtual ~ZipDescriptor(){
}
};
/* Extracts an entire file from a 7z archive into memory */
class LzmaFile: public File {
public:
LzmaFile(const Path::AbsolutePath & path, const Util::ReferenceCount<LzmaContainer> & container):
path(path),
container(container),
position(0),
memory(NULL),
size(0){
container->readFile(path, &memory, &size);
}
virtual ~LzmaFile(){
SzFree(NULL, memory);
}
bool eof(){
return position >= (int) size;
}
virtual bool good(){
return memory != NULL;
}
virtual int getSize(){
return size;
}
virtual bool canStream(){
return true;
}
virtual void reset(){
/* nothing */
}
virtual long tell(){
return position;
}
virtual Token * location(){
Token * head = new Token();
*head << "container";
/* container zipfile mount-point file-inside-zip */
*head << container->getPath();
*head << container->getMount();
*head << path.path();
return head;
}
virtual long getModificationTime(){
return container->getModificationTime(path);
}
virtual off_t seek(off_t position, int whence){
switch (whence){
case SEEK_SET: this->position = position; break;
case SEEK_CUR: this->position += position; break;
case SEEK_END: this->position = this->size + position; break;
}
if (this->position < 0){
this->position = 0;
}
if (this->position > (int) size){
this->position = size;
}
return this->position;
}
virtual File & operator>>(unsigned char & out){
if (this->position < (int) size){
out = memory[position];
position += 1;
}
return *this;
}
virtual int readLine(char * output, int size){
if (size > (int) (this->size - this->position)){
size = this->size - this->position;
}
memmove(output, memory + this->position, size);
this->position += size;
return size;
}
protected:
const Path::AbsolutePath path;
const Util::ReferenceCount<LzmaContainer> container;
/* keep track of bytes read so we can seek easier */
int position;
unsigned char * memory;
size_t size;
};
class LzmaDescriptor: public Descriptor {
public:
LzmaDescriptor(const Path::AbsolutePath & path, const Util::ReferenceCount<LzmaContainer> & container):
path(path),
container(container){
}
Path::AbsolutePath path;
Util::ReferenceCount<LzmaContainer> container;
using Descriptor::open;
virtual Util::ReferenceCount<File> open(File::Access mode){
return Util::ReferenceCount<File>(new LzmaFile(path, container));
}
virtual ~LzmaDescriptor(){
}
};
/* Keep this updated with all the supported container types */
bool isContainer(const Path::AbsolutePath & path){
return path.getExtension() == "zip" ||
path.getExtension() == "7z";
}
vector<std::string> containerTypes(){
vector<string> types;
types.push_back("zip");
types.push_back("7z");
return types;
}
bool System::isDirectory(const AbsolutePath & path){
return virtualDirectory.isDirectory(path) || systemIsDirectory(path);
}
bool System::exists(const AbsolutePath & path){
return virtualDirectory.exists(path) || systemExists(path);
}
void System::overlayFile(const AbsolutePath & where, Util::ReferenceCount<LzmaContainer> container){
virtualDirectory.addFile(where, Util::ReferenceCount<LzmaDescriptor>(new LzmaDescriptor(where, container)));
}
void System::overlayFile(const AbsolutePath & where, Util::ReferenceCount<ZipContainer> zip){
virtualDirectory.addFile(where, Util::ReferenceCount<ZipDescriptor>(new ZipDescriptor(where, zip)));
}
void System::unoverlayFile(const AbsolutePath & where){
virtualDirectory.removeFile(where);
}
vector<string> System::containerFileList(const AbsolutePath & container){
Util::ReferenceCount<ZipContainer> zip(new ZipContainer(container.path(), Filesystem::AbsolutePath()));
return zip->getFiles();
}
static bool isZipFile(const Filesystem::AbsolutePath & path){
return path.path().find(".zip") != string::npos;
}
static bool is7zFile(const Filesystem::AbsolutePath & path){
return path.path().find(".7z") != string::npos;
}
template <class Container>
static void addOverlayFiles(System & system, const Filesystem::AbsolutePath & where, const Util::ReferenceCount<Container> & container){
vector<string> files = container->getFiles();
for (vector<string>::const_iterator it = files.begin(); it != files.end(); it++){
string path = *it;
Global::debug(1) << "Add overlay to " << where.join(Filesystem::RelativePath(path)).path() << std::endl;
system.overlayFile(where.join(Filesystem::RelativePath(path)), container);
}
}
void System::addOverlay(const AbsolutePath & container, const AbsolutePath & where){
if (isZipFile(container)){
Global::debug(1) << "Opening zip file " << container.path() << std::endl;
addOverlayFiles(*this, where, Util::ReferenceCount<ZipContainer>(new ZipContainer(container.path(), where)));
} else if (is7zFile(container)){
addOverlayFiles(*this, where, Util::ReferenceCount<LzmaContainer>(new LzmaContainer(container.path(), where)));
}
}
void System::removeOverlay(const AbsolutePath & container, const AbsolutePath & where){
Util::ReferenceCount<ZipContainer> zip(new ZipContainer(container.path(), where));
vector<string> files = zip->getFiles();
for (vector<string>::const_iterator it = files.begin(); it != files.end(); it++){
string path = *it;
Global::debug(1) << "Remove overlay from " << where.join(Filesystem::RelativePath(path)).path() << std::endl;
unoverlayFile(where.join(Filesystem::RelativePath(path)));
}
}
Util::ReferenceCount<File> System::open(const AbsolutePath & path, File::Access mode){
Util::ReferenceCount<Descriptor> descriptor = virtualDirectory.lookup(path);
if (descriptor != NULL){
return descriptor->open(mode);
} else {
return Util::ReferenceCount<File>(new NormalFile(path, mode));
}
}
std::string readFile(const Path::AbsolutePath & path){
Util::ReferenceCount<Storage::File> file = Storage::instance().open(path);
if (file != NULL){
char * data = new char[file->getSize() + 1];
file->readLine(data, file->getSize());
data[file->getSize()] = 0;
std::string out(data);
delete[] data;
return out;
}
std::ostringstream out;
out << "Could not open file " << path.path();
throw Exception(__FILE__, __LINE__, out.str());
}
bool hasInstance(){
// return true;
return self != NULL;
}
System & setInstance(const Util::ReferenceCount<System> & what){
self = what;
return *self;
}
/* will read upto 'length' bytes unless a null byte is seen first */
string EndianReader::readStringX(int length){
ostringstream out;
uint8_t letter = readByte1();
while (letter != 0 && length > 0){
out << letter;
letter = readByte1();
length -= 1;
}
return out.str();
}
/* unconditionally reads 'length' bytes */
std::string EndianReader::readString2(int length){
ostringstream out;
vector<uint8_t> bytes = readBytes(length);
for (vector<uint8_t>::iterator it = bytes.begin(); it != bytes.end(); it++){
char byte = *it;
if (byte == 0){
break;
}
out << *it;
}
return out.str();
}
void EndianReader::seekEnd(streamoff where){
internal->seekEnd(where);
}
void EndianReader::seek(streampos where){
internal->seek(where);
}
int EndianReader::position(){
return internal->tell();
}
void EndianReader::readBytes(uint8_t * out, int length){
internal->read((char*) out, length);
}
vector<uint8_t> EndianReader::readBytes(int length){
vector<uint8_t> bytes;
for (int i = 0; i < length; i++){
uint8_t byte = 0;
internal->read((char*) &byte, 1);
if (internal->eof()){
throw Eof();
} else {
}
bytes.push_back(byte);
}
return bytes;
}
EndianReader::Internal::Internal(){
}
EndianReader::Internal::~Internal(){
}
bool EndianReader::StreamInternal::eof(){
return stream.eof();
}
int EndianReader::StreamInternal::read(char * data, int length){
stream.read(data, length);
return stream.gcount();
}
void EndianReader::StreamInternal::seekEnd(std::streamoff where){
stream.seekg(where, ios::end);
}
void EndianReader::StreamInternal::seek(std::streamoff where){
stream.seekg(where);
}
int EndianReader::StreamInternal::tell(){
return stream.tellg();
}
EndianReader::StreamInternal::~StreamInternal(){
}
bool EndianReader::FileInternal::eof(){
return file->eof();
}
void EndianReader::FileInternal::seekEnd(std::streamoff where){
file->seek(where, SEEK_END);
}
void EndianReader::FileInternal::seek(std::streamoff where){
file->seek(where, SEEK_SET);
}
int EndianReader::FileInternal::read(char * data, int length){
return file->readLine(data, length);
}
int EndianReader::FileInternal::tell(){
return file->tell();
}
EndianReader::FileInternal::~FileInternal(){
}
}
Filesystem::Filesystem(const AbsolutePath & path):
dataPath(path){
}
#ifdef _WIN32
Filesystem::AbsolutePath Filesystem::userDirectory(){
ostringstream str;
char path[MAX_PATH];
SHGetSpecialFolderPathA(0, path, CSIDL_APPDATA, false);
str << path << "/paintown/";
return Filesystem::AbsolutePath(str.str());
}
Filesystem::AbsolutePath Filesystem::configFile(){
ostringstream str;
char path[MAX_PATH];
SHGetSpecialFolderPathA(0, path, CSIDL_APPDATA, false);
str << path << "/paintown_configuration.txt";
return Filesystem::AbsolutePath(str.str());
}
#else
Filesystem::AbsolutePath Filesystem::configFile(){
ostringstream str;
/* what if HOME isn't set? */
str << getenv("HOME") << "/.paintownrc";
return Filesystem::AbsolutePath(str.str());
}
Filesystem::AbsolutePath Filesystem::userDirectory(){
ostringstream str;
char * home = getenv("HOME");
if (home == NULL){
str << "/tmp/paintown";
} else {
str << home << "/.paintown/";
}
return Filesystem::AbsolutePath(str.str());
}
#endif
Filesystem::AbsolutePath Filesystem::lookup(const RelativePath path){
vector<Filesystem::AbsolutePath> places;
#define push(x) try{ places.push_back(x); } catch (const Storage::IllegalPath & fail){ }
push(dataPath.join(path));
push(userDirectory().join(path));
push(Filesystem::AbsolutePath(path.path()));
#undef push
/* start error stuff early */
ostringstream out;
out << "Cannot find " << path.path() << ". I looked in ";
bool first = true;
for (vector<Filesystem::AbsolutePath>::iterator it = places.begin(); it != places.end(); it++){
const Filesystem::AbsolutePath & final = *it;
if (exists(final)){
return final;
}
if (!first){
out << ", ";
} else {
first = false;
}
out << "'" << final.path() << "'";
}
// out << "Cannot find " << path.path() << ". I looked in '" << dataPath.join(path).path() << "', '" << userDirectory().join(path).path() << "', and '" << path.path() << "'";
throw NotFound(__FILE__, __LINE__, out.str());
#if 0
/* first try the main data directory */
Filesystem::AbsolutePath final = dataPath.join(path);
if (::System::readable(final.path())){
return final;
}
/* then try the user directory, like ~/.paintown */
final = userDirectory().join(path);
if (::System::readable(final.path())){
return final;
}
/* then just look in the cwd */
if (::System::readable(path.path())){
return Filesystem::AbsolutePath(path.path());
}
ostringstream out;
out << "Cannot find " << path.path() << ". I looked in '" << dataPath.join(path).path() << "', '" << userDirectory().join(path).path() << "', and '" << path.path() << "'";
throw NotFound(__FILE__, __LINE__, out.str());
#endif
}
Filesystem::AbsolutePath Filesystem::lookupInsensitive(const Filesystem::AbsolutePath & directory, const Filesystem::RelativePath & path){
if (path.path() == ""){
throw NotFound(__FILE__, __LINE__, "Given empty path to lookup");
}
if (path.path() == "."){
return directory;
}
if (path.path() == ".."){
return directory.getDirectory();
}
if (path.isFile()){
vector<AbsolutePath> all = getFiles(directory, "*", true);
for (vector<AbsolutePath>::iterator it = all.begin(); it != all.end(); it++){
AbsolutePath & check = *it;
if (InsensitivePath(check.getFilename()) == path){
return check;
}
}
ostringstream out;
out << "Cannot find " << path.path() << " in " << directory.path();
throw NotFound(__FILE__, __LINE__, out.str());
} else {
return lookupInsensitive(lookupInsensitive(directory, path.firstDirectory()), path.removeFirstDirectory());
}
}
vector<Filesystem::AbsolutePath> Filesystem::findDirectoriesIn(const Filesystem::AbsolutePath & path){
vector<Filesystem::AbsolutePath> dirs = virtualDirectory.findDirectories(path, "*", false);
DIR * dir = opendir(path.path().c_str());
if (dir == NULL){
return dirs;
}
struct dirent * entry = readdir(dir);
while (entry != NULL){
if (string(entry->d_name) != "." && string(entry->d_name) != ".."){
string total = path.path() + "/" + entry->d_name;
if (::System::isDirectory(total)){
dirs.push_back(AbsolutePath(total));
}
}
entry = readdir(dir);
}
closedir(dir);
return dirs;
}
vector<Filesystem::AbsolutePath> Filesystem::findDirectories(const RelativePath & path){
typedef vector<AbsolutePath> Paths;
Paths dirs;
Paths main_dirs = findDirectoriesIn(dataPath.join(path));
Paths user_dirs = findDirectoriesIn(userDirectory().join(path));
Paths here_dirs = findDirectoriesIn(Filesystem::AbsolutePath(path.path()));
dirs.insert(dirs.end(), main_dirs.begin(), main_dirs.end());
dirs.insert(dirs.end(), user_dirs.begin(), user_dirs.end());
dirs.insert(dirs.end(), here_dirs.begin(), here_dirs.end());
return dirs;
}
/* a/b/c/ -> a/b/c */
static string removeTrailingSlash(string str){
while (str.size() > 0 && str[str.size() - 1] == '/'){
str = str.erase(str.size() - 1);
}
return str;
}
vector<Filesystem::AbsolutePath> Filesystem::getFiles(const AbsolutePath & dataPath, const string & find, bool caseInsensitive){
#ifdef USE_ALLEGRO
struct al_ffblk info;
vector<AbsolutePath> files;
if (al_findfirst((dataPath.path() + "/" + find).c_str(), &info, FA_ALL ) != 0){
return files;
}
files.push_back(AbsolutePath(dataPath.path() + "/" + string(info.name)));
while ( al_findnext( &info ) == 0 ){
files.push_back(AbsolutePath(dataPath.path() + "/" + string(info.name)));
}
al_findclose( &info );
return files;
#else
Util::Thread::ScopedLock scoped(lock);
vector<AbsolutePath> files;
vector<AbsolutePath> more = virtualDirectory.findFiles(dataPath, find, caseInsensitive);
files.insert(files.end(), more.begin(), more.end());
DIRST sflEntry;
// bool ok = open_dir(&sflEntry, removeTrailingSlash(dataPath.path()).c_str());
bool ok = open_dir(&sflEntry, dataPath.path().c_str());
if (!ok){
/* sfldir.c claims that you have to call close_dir even if
* open_dir fails but close_dir will do ASSERT(dir->dir_handle) which is sometimes
* NULL when open_dir fails so we first check if the dir_handle is non-NULL and
* then call close_dir.
*/
if (sflEntry._dir_handle != NULL){
close_dir(&sflEntry);
}
return files;
}
while (ok){
if (file_matches(sflEntry.file_name, find.c_str())){
files.push_back(AbsolutePath(dataPath.path() + "/" + string(sflEntry.file_name)));
}
ok = read_dir(&sflEntry);
}
close_dir(&sflEntry);
/*
for (map<AbsolutePath, Util::ReferenceCount<Storage::ZipContainer> >::iterator it = overlays.begin(); it != overlays.end(); it++){
AbsolutePath path = it->first;
if (it->second == NULL){
continue;
}
// Global::debug(0) << "Check " << path.path() << " (" << path.getDirectory().path() << ") vs directory " << dataPath.path() << " wildcard " << find << " to " << path.getFilename().path() << std::endl;
if (path.getDirectory() == dataPath &&
file_matches(path.getLastComponent().c_str(), find.c_str())){
// Global::debug(0) << "Found overlay " << path.path() << " in " << dataPath.path() << " for wildcard " << find << std::endl;
files.push_back(path);
}
}
*/
// Global::debug(0) << "Warning: Filesystem::getFiles() is not implemented yet for SDL" << endl;
return files;
#endif
}
std::vector<Filesystem::AbsolutePath> Filesystem::getFiles(const RelativePath & path, const RelativePath & find, bool caseInsensitive){
vector<AbsolutePath> directories;
directories.push_back(dataPath.join(path));
directories.push_back(userDirectory().join(path));
directories.push_back(Filesystem::AbsolutePath(path.path()));
vector<AbsolutePath> files;
for (vector<AbsolutePath>::iterator it = directories.begin(); it != directories.end(); it++){
Global::debug(0) << "Search for " << find.path() << " in " << it->path() << std::endl;
vector<AbsolutePath> found = getFiles(*it, find, caseInsensitive);
files.insert(files.end(), found.begin(), found.end());
}
return files;
}
template <class X>
static void append(vector<X> & destination, const vector<X> & source){
/*
for (typename vector<X>::const_iterator it = source.begin(); it != source.end(); it++){
destination.push_back(*it);
}
*/
copy(source.begin(), source.end(), back_insert_iterator<vector<X> >(destination));
}
vector<Filesystem::AbsolutePath> Filesystem::getAllDirectories(const AbsolutePath & path){
vector<AbsolutePath> all = findDirectoriesIn(path);
vector<AbsolutePath> final;
append(final, all);
for (vector<AbsolutePath>::iterator it = all.begin(); it != all.end(); it++){
vector<AbsolutePath> more = getAllDirectories(*it);
append(final, more);
}
return final;
}
vector<Filesystem::AbsolutePath> Filesystem::getFilesRecursive(const AbsolutePath & dataPath, const string & find, bool caseInsensitive){
if (!exists(dataPath)){
return vector<AbsolutePath>();
}
vector<AbsolutePath> directories = getAllDirectories(dataPath);
directories.push_back(dataPath);
vector<AbsolutePath> files;
for (vector<AbsolutePath>::iterator it = directories.begin(); it != directories.end(); it++){
vector<AbsolutePath> found = getFiles(*it, find, caseInsensitive);
append(files, found);
}
return files;
}
/*
std::string find(const std::string path){
if (path.length() == 0){
throw NotFound("No path given");
}
if (path[0] == '/'){
string str(path);
str.erase(0, 1);
string out = lookup(str);
if (System::isDirectory(out)){
return sanitize(out + "/");
}
return sanitize(out);
}
string out = lookup(path);
if (System::isDirectory(out)){
return sanitize(out + "/");
}
return sanitize(out);
}
*/
Filesystem::AbsolutePath Filesystem::find(const RelativePath & path){
if (path.isEmpty()){
throw NotFound(__FILE__, __LINE__, "No path given");
}
AbsolutePath out = lookup(path);
if (::System::isDirectory(out.path())){
return AbsolutePath(out.path() + "/");
}
return AbsolutePath(out.path());
}
Filesystem::AbsolutePath Filesystem::findInsensitive(const RelativePath & path){
try{
/* try sensitive lookup first */
return lookup(path);
} catch (const NotFound & fail){
}
/* get the base directory */
AbsolutePath directory = lookup(path.getDirectory());
return lookupInsensitive(directory, path.getFilename());
}
bool Filesystem::exists(const RelativePath & path){
try{
AbsolutePath absolute = find(path);
return true;
} catch (const NotFound & found){
return false;
}
}
bool Filesystem::systemIsDirectory(const AbsolutePath & path){
return ::System::isDirectory(path.path());
}
bool Filesystem::systemExists(const AbsolutePath & path){
return ::System::readable(path.path());
}
Filesystem::RelativePath Filesystem::cleanse(const AbsolutePath & path){
string str = path.path();
if (str.find(dataPath.path()) == 0){
str.erase(0, dataPath.path().length());
} else if (str.find(userDirectory().path()) == 0){
str.erase(0, userDirectory().path().length());
}
return RelativePath(str);
}
diff --git a/src/font.cpp b/src/font.cpp
index cd1010b9..c9a9b62e 100644
--- a/src/font.cpp
+++ b/src/font.cpp
@@ -1,318 +1,318 @@
#ifdef USE_ALLEGRO
/* for textout_* and whatnot */
#include <allegro.h>
#endif
-#include "graphics/bitmap.h"
-#include "font.h"
-#include "funcs.h"
-#include "init.h"
-#include "ftalleg.h"
-#include "font_factory.h"
-#include "exceptions/exception.h"
+#include "r-tech1/graphics/bitmap.h"
+#include "r-tech1/font.h"
+#include "r-tech1/funcs.h"
+#include "r-tech1/init.h"
+#include "r-tech1/ftalleg.h"
+#include "r-tech1/font_factory.h"
+#include "r-tech1/exceptions/exception.h"
#include <string.h>
using namespace std;
Util::Parameter<Util::ReferenceCount<Filesystem::RelativePath> > Font::defaultFont;
Font::Font(){
}
/* copy/pasted from network/message.cpp */
static vector<string> wrapStrings(const string & left, const string & right, const Font & font, int max, vector< string > accum){
if (left == ""){
return accum;
}
int length = font.textLength(left.c_str());
if (length >= max){
return wrapStrings(left.substr(0, left.length() / 2), left.substr(left.length() / 2) + right, font, max, accum);
} else if (right == "" || font.textLength((left + right.substr(0, 1)).c_str()) >= max){
accum.push_back(left);
return wrapStrings(right, "", font, max, accum);
} else {
return wrapStrings(left + right.substr(0, 1), right.substr(1), font, max, accum);
}
}
void Font::printfWrapLine(int x, int & y, Graphics::Color color, const Graphics::Bitmap & work, int maxWidth, const char * line) const {
vector< string > all;
all = wrapStrings(string(line), "", *this, maxWidth, all );
for ( vector< string >::iterator str = all.begin(); str != all.end(); str++ ){
printf(x, y, color, work, *str, 0);
y += getHeight();
}
y += getHeight() / 2;
}
#if 0
void Font::printfWrapLine2(int x, int & y, int color, const Bitmap & work, int maxWidth, const char * line) const {
int height = getHeight();
while (*line != '\0'){
char tmp2[1024];
int left = strlen(line);
int min = 0;
int max = left;
int current = (min + max) / 2;
strncpy(tmp2, line, current);
tmp2[current] = '\0';
bool done = false;
while (!done){
int length = textLength(tmp2);
if (length >= maxWidth){
max = current;
current = (min + max) / 2;
strncpy(tmp2, line, current);
tmp2[current] = '\0';
} else if (length < maxWidth && current < max){
min = current;
current = (min + max) / 2;
if (current == max - 1){
current = max;
done = true;
}
strncpy(tmp2, line, current);
tmp2[current] = '\0';
} else {
done = true;
}
}
printf(x, y, color, work, string(tmp2), 0);
y += height;
line += current;
}
y += height / 2;
}
#endif
void Font::printfWrap(int x, int y, Graphics::Color color, const Graphics::Bitmap & work, int maxWidth, const std::string & str, int marker, ... ) const {
char buf[4096];
va_list ap;
va_start(ap, marker);
Util::limitPrintf(buf, sizeof(buf), str.c_str(), ap);
va_end(ap);
char * start = buf;
char * end = strchr(start, '\n');
while (end != NULL){
char tmp[1024];
unsigned int ender = end - start;
if (ender >= sizeof(tmp) - 1){
ender = sizeof(tmp) - 1;
}
strncpy(tmp, start, ender);
tmp[ender] = '\0';
printfWrapLine(x, y, color, work, maxWidth, tmp);
start = end + 1;
end = strchr(start, '\n');
}
printfWrapLine(x, y, color, work, maxWidth, start);
}
Font::~Font(){
}
#ifdef USE_ALLEGRO
AllegroFont::AllegroFont( const FONT * const font ):
font(font){
}
-
+
AllegroFont::AllegroFont( const AllegroFont & copy ):
font( copy.getInternalFont() ){
}
AllegroFont::~AllegroFont(){
}
-
+
int AllegroFont::textLength( const char * text ) const{
return text_length( getInternalFont(), text );
}
int AllegroFont::getHeight( const string & str ) const {
return getHeight();
}
int AllegroFont::getHeight() const {
return text_height( getInternalFont() );
}
void AllegroFont::setSize( const int x, const int y ){
}
int AllegroFont::getSizeX() const {
return 0;
}
int AllegroFont::getSizeY() const {
return 0;
}
void AllegroFont::printf( int x, int y, int xSize, int ySize, Graphics::Color color, const Graphics::Bitmap & work, const string & str, int marker, ... ) const {
char buf[512];
va_list ap;
va_start(ap, marker);
Util::limitPrintf(buf, sizeof(buf), str.c_str(), ap);
va_end(ap);
textout_ex(work.getData()->getBitmap(), getInternalFont(), buf, x, y, color.color, -1);
}
-
+
void AllegroFont::printf( int x, int y, Graphics::Color color, const Graphics::Bitmap & work, const string & str, int marker, ... ) const {
char buf[512];
va_list ap;
va_start(ap, marker);
uvszprintf(buf, sizeof(buf), str.c_str(), ap);
va_end(ap);
textout_ex(work.getData()->getBitmap(), getInternalFont(), buf, x, y, color.color, -1);
}
#endif
const Font & Font::getDefaultFont(){
return getDefaultFont(16, 16);
}
const Path::RelativePath & Font::getDefaultFontPath(){
if (defaultFont.current() == NULL){
throw Exception::FontException(__FILE__, __LINE__, "No default font set");
}
return *defaultFont.current();
}
const Font & Font::getDefaultFont(int width, int height){
Font * font = FontFactory::getFont(getDefaultFontPath(), width, height);
if (font == NULL){
throw Exception::FontException(__FILE__, __LINE__, "No default font set");
}
return *font;
}
-
+
/* name should be the path of a .ttf file in the fonts/ directory.
* something like 'arial.ttf'
*/
const Font & Font::getFont(const Filesystem::RelativePath & name, const int x, const int y){
Font * check = FontFactory::getFont(name, x, y);
if (check == NULL){
throw Exception::FontException(__FILE__, __LINE__, "Could not get font");
}
Font & font = *check;
/* sanity check */
if (font.getHeight("A") == 0){
return getDefaultFont();
}
return font;
}
-
+
const Font & Font::getFont( const Filesystem::AbsolutePath & name, const int x, const int y){
return *FontFactory::getFont(name, x, y);
}
FreeTypeFont::FreeTypeFont(const Filesystem::AbsolutePath & str ):
sizeX(16),
sizeY(16),
own(true){
this->font = new ftalleg::freetype(str, getSizeX(), getSizeY() );
}
int FreeTypeFont::getHeight( const string & str ) const {
return this->font->getHeight(str);
}
int FreeTypeFont::getHeight() const {
return getHeight("A");
}
int FreeTypeFont::textLength( const char * text ) const {
return this->font->getLength(string(text));
}
void FreeTypeFont::printf( int x, int y, int xSize, int ySize, Graphics::Color color, const Graphics::Bitmap & work, const string & str, int marker, ... ) const {
char buf[512];
va_list ap;
va_start(ap, marker);
vsnprintf(buf, sizeof(buf), str.c_str(), ap);
va_end(ap);
int old_x = 0;
int old_y = 0;
this->font->getSize(&old_x, &old_y);
this->font->setSize(xSize, ySize);
this->font->render(x, y, color, work, ftalleg::freetype::ftLeft, string(buf), 0);
this->font->setSize(old_x, old_y);
}
-
+
void FreeTypeFont::printf( int x, int y, Graphics::Color color, const Graphics::Bitmap & work, const string & str, int marker, ... ) const {
char buf[512];
va_list ap;
va_start(ap, marker);
vsnprintf(buf, sizeof(buf), str.c_str(), ap);
va_end(ap);
this->font->render(x, y, color, work, ftalleg::freetype::ftLeft, string(buf), 0);
}
void FreeTypeFont::setSize( const int x, const int y ){
this->sizeX = x;
this->sizeY = y;
this->font->setSize( this->sizeX, this->sizeY );
}
int FreeTypeFont::getSizeX() const {
return this->sizeX;
}
int FreeTypeFont::getSizeY() const {
return this->sizeY;
}
FreeTypeFont::~FreeTypeFont(){
- // cout << "Delete font " << this->font << endl;
+ // cout << "Delete font " << this->font << endl;
if (own){
delete this->font;
}
}
NullFont::NullFont(){
}
NullFont::~NullFont(){
}
void NullFont::setSize( const int x, const int y ){
}
int NullFont::getSizeX() const {
return 0;
}
int NullFont::getSizeY() const {
return 0;
}
int NullFont::textLength( const char * text ) const {
return 0;
}
int NullFont::getHeight( const std::string & str ) const {
return 0;
}
int NullFont::getHeight() const {
return 0;
}
void NullFont::printf( int x, int y, int xSize, int ySize, Graphics::Color color, const Graphics::Bitmap & work, const std::string & str, int marker, ... ) const {
}
void NullFont::printf( int x, int y, Graphics::Color color, const Graphics::Bitmap & work, const std::string & str, int marker, ... ) const {
}
diff --git a/src/font_factory.cpp b/src/font_factory.cpp
index a79468f0..a94316c0 100644
--- a/src/font_factory.cpp
+++ b/src/font_factory.cpp
@@ -1,129 +1,129 @@
#include <string>
#ifdef USE_ALLEGRO
#include <allegro.h>
#endif
#include <map>
-#include "font.h"
-#include "funcs.h"
-#include "file-system.h"
-#include "thread.h"
-#include "font_factory.h"
-#include "debug.h"
-#include "exceptions/exception.h"
-#include "exceptions/load_exception.h"
-#include "ftalleg.h"
+#include "r-tech1/font.h"
+#include "r-tech1/funcs.h"
+#include "r-tech1/file-system.h"
+#include "r-tech1/thread.h"
+#include "r-tech1/font_factory.h"
+#include "r-tech1/debug.h"
+#include "r-tech1/exceptions/exception.h"
+#include "r-tech1/exceptions/load_exception.h"
+#include "r-tech1/ftalleg.h"
// #include "fonts.h"
using namespace std;
FontFactory * FontFactory::my_factory = NULL;
Font * FontFactory::getFont(const Filesystem::RelativePath & path, const int x, const int y ){
if ( my_factory == NULL ){
my_factory = new FontFactory();
}
return my_factory->getRealFont(path, x, y );
}
Font * FontFactory::getFont(const Filesystem::AbsolutePath & path, const int x, const int y ){
if ( my_factory == NULL ){
my_factory = new FontFactory();
}
return my_factory->getRealFont(path, x, y );
}
void FontFactory::destroy(){
if ( my_factory != NULL ){
delete my_factory;
my_factory = NULL;
}
}
void FontFactory::clear(){
if (my_factory != NULL){
my_factory->_clear();
}
}
Font * FontFactory::getRealFont(const Filesystem::AbsolutePath & path, int x, int y){
Util::Thread::ScopedLock locked(lock);
if (font_mapper.find(path.path()) == font_mapper.end()){
try{
FreeTypeFont * font = new FreeTypeFont(path);
font_mapper[path.path()] = font;
} catch (const ftalleg::Exception & failure){
throw LoadException(__FILE__, __LINE__, failure.getReason());
}
}
Font * font = font_mapper[path.path()];
if (font == NULL){
std::ostringstream out;
out << "No font for " << path.path();
throw Exception::FontException(__FILE__, __LINE__, out.str());
}
if (x < 1){
x = 1;
}
if (y < 1){
y = 1;
}
font->setSize(x, y);
return font;
}
Font * FontFactory::getRealFont(const Filesystem::RelativePath & path, const int x, const int y ){
Util::Thread::ScopedLock locked(lock);
try{
if (font_mapper.find(path.path()) == font_mapper.end()){
font_mapper[path.path()] = new FreeTypeFont(Storage::instance().find(path));
}
Font * f = font_mapper[path.path()];
if (f == NULL){
std::ostringstream out;
out << "No font for " << path.path();
throw Exception::FontException(__FILE__, __LINE__, out.str());
}
f->setSize(x, y);
return f;
} catch (const Filesystem::NotFound & e){
Global::debug(0) << "Warning: could not find font " << path.path() << ": " << e.getTrace() << endl;
return &nullFont;
}
// return font_mapper[ str ];
}
void FontFactory::_clear(){
for (map<string,Font*>::iterator it = font_mapper.begin(); it != font_mapper.end(); it++){
Font * s = (*it).second;
delete s;
}
font_mapper.clear();
#ifdef USE_ALLEGRO
font_mapper["bios"] = new AllegroFont(::font);
#endif
}
FontFactory::FontFactory(){
// my_data = load_datafile(Filesystem::find(Filesystem::RelativePath("fonts.dat")).path().c_str());
#ifdef USE_ALLEGRO
font_mapper[ "bios" ] = new AllegroFont(::font);
#endif
}
FontFactory::~FontFactory(){
for ( map<string,Font*>::iterator it = font_mapper.begin(); it != font_mapper.end(); it++ ){
Font * s = (*it).second;
delete s;
}
/*
- if ( my_data != NULL ){
- unload_datafile( my_data );
- }
+ if ( my_data != NULL ){
+ unload_datafile( my_data );
+ }
*/
}
diff --git a/src/ftalleg.cpp b/src/ftalleg.cpp
index 96a963cc..b3151506 100644
--- a/src/ftalleg.cpp
+++ b/src/ftalleg.cpp
@@ -1,705 +1,705 @@
/*
--------------
About
--------------
A Freetype wrapper for use with allegro
Feel free to do whatever you like with this, by all means enjoy!
Just add it to your project
--------------
Linking
--------------
on linux:
g++ `freetype-config --cflags` ftalleg.cpp myfiles.cpp `freetype-config --libs` `allegro-config --libs`
on windows (you may need to include the freetype dir location, ie -Ic:/mingw/include):
g++ ftalleg.cpp myfiles.cpp -lfreetype -lalleg
--------------
Disclaimer
--------------
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE
SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef FT_FONT_CPP
#define FT_FONT_CPP
-#include "graphics/bitmap.h"
+#include "r-tech1/graphics/bitmap.h"
/*
#include <allegro.h>
#ifdef _WIN32
#include <winalleg.h>
#endif
*/
-#include "ftalleg.h"
-#include "utf.h"
+#include "r-tech1/ftalleg.h"
+#include "r-tech1/utf.h"
#include <iostream>
#include <sstream>
#include <cassert>
#include <exception>
#ifdef USE_ALLEGRO5
#include <allegro5/allegro_font.h>
#include <allegro5/allegro_ttf.h>
#endif
namespace ftalleg{
Exception::Exception():
std::exception(){
}
Exception::Exception(const std::string reason):
std::exception(),
reason(reason){
}
Exception::~Exception() throw(){
}
- // typedef void (*pixeler)( BITMAP * bitmap, int x, int y, int color );
+ // typedef void (*pixeler)( BITMAP * bitmap, int x, int y, int color );
static Graphics::Color fixColor(const unsigned char c, short grays){
// Safety checks
// assert(c != 0);
assert(grays != 1);
// invariant: c can be dereferenced safely
// invariant: (grays - 1) != 0, thus it can be used as divisor.
int red = c * 255 / (grays - 1);
int green = c * 255 / (grays - 1);
int blue = c * 255 / (grays - 1);
//alpha = *c * 255 / (grays - 1);
return Graphics::makeColor(red,green,blue);
}
- // Static count of instances of fonts to track library
- static int instances = 0;
- static FT_Library ftLibrary = 0;
+ // Static count of instances of fonts to track library
+ static int instances = 0;
+ static FT_Library ftLibrary = 0;
- character::character() {
- }
+ character::character() {
+ }
character::~character() {
if (line){
delete [] line;
}
}
- fontSize::fontSize() {
+ fontSize::fontSize() {
width = height = italics = angle = 0;
- }
+ }
fontSize::fontSize(int width, int height):
width(width),
height(height),
italics(0),
angle(0){
}
- fontSize::~fontSize() {
- }
+ fontSize::~fontSize() {
+ }
- bool fontSize::operator<(const fontSize &fs) const {
+ bool fontSize::operator<(const fontSize &fs) const {
return (width<fs.width || height<fs.height || italics<fs.italics);
- }
+ }
/* im not sure this is a very unique key.. */
- int fontSize::createKey() const {
+ int fontSize::createKey() const {
return ((width+10) * (height+20) * (italics+250));
- }
+ }
#ifdef USE_ALLEGRO5
freetype::freetype(const Filesystem::AbsolutePath & path, const int x, const int y):
alive(5, 5),
path(path),
width(x),
height(y),
original_size(x){
if (instances == 0){
al_init_font_addon();
al_init_ttf_addon();
}
instances += 1;
int flags = al_get_new_bitmap_flags();
/* memory fonts must live in memory */
al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP);
fonts[width].memory = al_load_font(path.path().c_str(), width, 0);
al_set_new_bitmap_flags(flags);
fonts[width].video = al_load_font(path.path().c_str(), width, 0);
}
freetype::~freetype(){
for (std::map<int, FontUse>::iterator it = fonts.begin(); it != fonts.end(); it++){
FontUse & font = it->second;
al_destroy_font(font.memory);
al_destroy_font(font.video);
}
instances -= 1;
if (instances == 0){
al_shutdown_font_addon();
}
}
ALLEGRO_FONT * freetype::currentMemoryFont() const {
std::map<int, FontUse>::const_iterator find = fonts.find(width);
if (find == fonts.end()){
throw Exception("inconsistency error");
}
return find->second.memory;
}
ALLEGRO_FONT * freetype::currentVideoFont() const {
std::map<int, FontUse>::const_iterator find = fonts.find(width);
if (find == fonts.end()){
throw Exception("inconsistency error");
}
return find->second.video;
}
-
+
int freetype::getHeight(const std::string & str) const {
Util::Thread::ScopedLock locked(lock);
/* sort of a hack but we need to set the display to the screen. with
* allegro5 the screen buffer will be the actual screen so no allocation
* will occur.
*/
// al_set_target_bitmap(alive.getData().getBitmap());
// ALLEGRO_BITMAP * target = al_get_target_bitmap();
// al_set_target_bitmap(NULL);
int height = al_get_font_line_height(currentMemoryFont());
// al_set_target_bitmap(target);
return height;
}
int freetype::getLength(const std::string & text) const {
Util::Thread::ScopedLock locked(lock);
// al_set_target_bitmap(alive.getData().getBitmap());
// ALLEGRO_BITMAP * target = al_get_target_bitmap();
// al_set_target_bitmap(NULL);
int width = al_get_text_width(currentMemoryFont(), text.c_str());
// al_set_target_bitmap(target);
return width;
}
void freetype::setSize(unsigned int w, unsigned int h){
Util::Thread::ScopedLock locked(lock);
width = w;
height = h;
if (fonts.find(width) == fonts.end()){
fonts[width].memory = al_load_font(path.path().c_str(), width, 0);
fonts[width].video = al_load_font(path.path().c_str(), width, 0);
}
}
void freetype::getSize(int * w, int * h) const {
Util::Thread::ScopedLock locked(lock);
*w = width;
*h = height;
}
void freetype::render(int x, int y, const Graphics::Color & color, const Graphics::Bitmap & bmp, ftAlign alignment, const std::string & text, int marker, ...){
Util::Thread::ScopedLock locked(lock);
std::ostringstream str;
/* use vsnprintf/Util::limitPrintf here? */
// Get extra arguments
va_list ap;
va_start(ap, marker);
for(unsigned int i = 0; i<text.length();++i) {
if (text[i] == '%') {
if(text[i+1]=='s') {
str << va_arg(ap, char *);
++i;
} else if(text[i+1]=='d'||text[i+1]=='i') {
str << va_arg(ap, signed int);
++i;
} else if(text[i+1]=='c') {
str << (char)va_arg(ap, int);
++i;
} else str << text[i];
} else {
str << text[i];
}
}
va_end(ap);
std::string fixedText(str.str());
if (al_get_target_bitmap() != bmp.getData()->getBitmap()){
al_set_target_bitmap(bmp.getData()->getBitmap());
}
al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA);
/* for setting the blend state and whatnot */
bmp.startDrawing();
al_draw_text(currentVideoFont(), bmp.blendColor(color).color, x, y, 0, fixedText.c_str());
bmp.endDrawing();
}
#else
- //! Constructor
+ //! Constructor
freetype::freetype(const Filesystem::AbsolutePath & str, const int x, const int y ):
face(NULL){
//Load library
if (!ftLibrary){
if (FT_Init_FreeType(&ftLibrary) != 0){
throw Exception("Could not initialize freetype");
}
}
instances += 1;
faceLoaded = kerning = false;
currentIndex = 0;
currentFilename = "";
faceName = "";
// currentChar = new character;
systemName = "";
internalFix = false;
this->load(str, 0, x, y );
}
- //! Destructor
+ //! Destructor
freetype::~freetype(){
//if(face!=NULL)FT_Done_Face(face);
if (faceLoaded && face != NULL){
FT_Done_Face(face);
face = NULL;
}
instances -= 1;
if (instances == 0){
FT_Done_FreeType(ftLibrary);
ftLibrary = NULL;
}
destroyGlyphIndex();
/*
if ( currentChar ){
delete currentChar;
}
*/
}
void freetype::destroyGlyphIndex(){
for (std::map<int, std::map<signed long, character*> >::iterator i1 = fontTable.begin(); i1 != fontTable.end(); i1++){
std::map<signed long, character*> & characters = (*i1).second;
for (std::map<signed long, character*>::iterator i2 = characters.begin(); i2 != characters.end(); i2++){
character * character = (*i2).second;
delete character;
}
}
}
- // Extract glyph
+ // Extract glyph
character * freetype::extractGlyph(signed long unicode){
int w, h, ew;
character * tempChar = new character();
// Translate it according to the given italics
double italics = (double)(size.italics)*GLYPH_PI/180;
FT_Matrix matrix;
matrix.xx = 0x10000L;
matrix.xy = (FT_Fixed)( sin( italics ) * (GLYPH_SQRT2*0x10000L) );
matrix.yx = 0;
matrix.yy = 0x10000L;
FT_Set_Transform( face, &matrix, 0 );
if (FT_Load_Char(face, unicode, FT_LOAD_TARGET_NORMAL | FT_LOAD_RENDER | FT_LOAD_FORCE_AUTOHINT) != 0){
throw Exception("Could not load freetype glyph");
}
w = face->glyph->bitmap.width;
h = face->glyph->bitmap.rows;
ew = 0;
if (!w)ew = 1;
if (!h)h = 1;
tempChar->width = (w + ew);
tempChar->height = h;
tempChar->rows = face->glyph->bitmap.rows;
tempChar->grays = face->glyph->bitmap.num_grays;
tempChar->pitch = face->glyph->bitmap.pitch;
tempChar->line = new unsigned char[tempChar->rows * tempChar->pitch];
memcpy(tempChar->line, face->glyph->bitmap.buffer, tempChar->rows * tempChar->pitch);
tempChar->left = face->glyph->bitmap_left;
tempChar->top = face->glyph->bitmap_top;
tempChar->right = face->glyph->advance.x >> 6;
tempChar->unicode = unicode;
tempChar->length = ((w + ew)+face->glyph->advance.x) >> 6;
return tempChar;
}
- // Create single index
+ // Create single index
void freetype::createIndex(){
std::map<int, std::map<signed long, character*> >::iterator p;
p = fontTable.find(size.createKey());
if (p == fontTable.end()){
if (FT_Set_Pixel_Sizes(face, size.width, size.height) != 0){
throw Exception("Could not set freetype size");
}
FT_UInt glyphIndex;
FT_ULong unicode = FT_Get_First_Char(face, &glyphIndex);
std::map<signed long, character*> tempMap;
while (glyphIndex != 0){
tempMap.insert(std::make_pair(unicode, extractGlyph(unicode)));
unicode = FT_Get_Next_Char(face, unicode, &glyphIndex);
}
fontTable.insert(std::make_pair(size.createKey(), tempMap));
}
if (fontTable.find(size.createKey()) == fontTable.end()){
printf("ftalleg: inconsistency error\n");
throw Exception("inconsistency error");
}
}
/*
- pixeler getPutPixel(){
- switch( get_color_depth() ){
- case 8 : return _putpixel;
- case 15 : return _putpixel15;
- case 16 : return _putpixel16;
- case 24 : return _putpixel24;
- case 32 : return _putpixel32;
- default : return putpixel;
- }
- }
+ pixeler getPutPixel(){
+ switch( get_color_depth() ){
+ case 8 : return _putpixel;
+ case 15 : return _putpixel15;
+ case 16 : return _putpixel16;
+ case 24 : return _putpixel24;
+ case 32 : return _putpixel32;
+ default : return putpixel;
+ }
+ }
*/
void drawOneCharacter(const character * tempChar, int & x1, int & y1, FT_UInt sizeHeight, const Graphics::Bitmap & bitmap, const Graphics::Color & color){
unsigned char * line = tempChar->line;
int colorRed = Graphics::getRed(color);
int colorGreen = Graphics::getGreen(color);
int colorBlue = Graphics::getBlue(color);
/* cache the last color, there is a good chance it will be reused */
unsigned char lastData = -1;
short lastGrays = -1;
Graphics::Color black = Graphics::makeColor(0, 0, 0);
Graphics::Color lastColor = black;
for (int y = 0; y < tempChar->rows; y++){
unsigned char * buffer = line;
for (int x = 0; x < tempChar->width; x++){
Graphics::Color finalColor = black;
unsigned char current = *buffer;
buffer++;
if (current == lastData && lastGrays == tempChar->grays){
finalColor = lastColor;
} else {
Graphics::Color col = fixColor(current, tempChar->grays);
int red = Graphics::getRed(col);
int green = Graphics::getGreen(col);
int blue = Graphics::getBlue(col);
if ((red < 50) ||
(green < 50) ||
(blue < 50)){
continue;
}
red = red * colorRed / 255;
green = green * colorGreen / 255;
blue = blue * colorBlue / 255;
finalColor = Graphics::makeColor(red, green, blue);
lastData = current;
lastColor = finalColor;
lastGrays = tempChar->grays;
}
//col.alpha= col.alpha * color.alpha / 255;
// putpixel(bitmap,x1+tempChar.left+x,y1 - tempChar.top+y + size.height,makecol(red,blue,green));
/* dangerous! putter is probably one of the _putpixel* routines so if x or y are off the bitmap
* you will get a segfault
*/
// putter(bitmap,x1+tempChar.left+x,y1 - tempChar.top+y + size.height,makecol(red,blue,green));
// putter = 0;
int finalX = x1+tempChar->left+x;
int finalY = y1 - tempChar->top + y + sizeHeight;
bitmap.putPixelNormal(finalX, finalY, finalColor);
}
line += tempChar->pitch;
}
x1 += tempChar->right;
}
- // Render a character from the lookup table
+ // Render a character from the lookup table
void freetype::drawCharacter(signed long unicode, int &x1, int &y1, const Graphics::Bitmap & bitmap, const Graphics::Color &color){
// pixeler putter = getPutPixel();
std::map<int, std::map<signed long, character*> >::iterator ft;
ft = fontTable.find(size.createKey());
if (ft != fontTable.end()){
std::map<signed long, character*>::iterator p;
p = (ft->second).find(unicode);
if (p != ft->second.end()){
const character * tempChar = p->second;
drawOneCharacter(tempChar, x1, y1, size.height, bitmap, color);
}
}
}
- //! Load font from memory
+ //! Load font from memory
bool freetype::load(const unsigned char *memoryFont, unsigned int length, int index, unsigned int width, unsigned int height) {
if(!FT_New_Memory_Face(ftLibrary,memoryFont, length,index,&face)) {
currentFilename = "memoryFont";
currentIndex = index;
faceLoaded = true;
size.italics = 0;
setSize(width, height);
if (FT_HAS_GLYPH_NAMES(face)){
char buff[1024];
if(!FT_Get_Glyph_Name(face, currentIndex,buff, sizeof(buff))){
faceName = currentFilename;
}
else faceName = std::string(buff);
} else {
faceName = currentFilename;
}
if(FT_HAS_KERNING(face))kerning=true;
else kerning = false;
} else {
faceLoaded=false;
std::cout << "Load system font failed\n";
}
return faceLoaded;
}
- //! Load font from file
+ //! Load font from file
bool freetype::load(const Filesystem::AbsolutePath & filename, int index, unsigned int width, unsigned int height){
FT_Error error = FT_New_Face(ftLibrary, filename.path().c_str(), index, &face);
if (error == 0){
currentFilename = filename.path();
currentIndex = index;
faceLoaded = true;
size.italics = 0;
setSize(width, height);
if (FT_HAS_GLYPH_NAMES(face)){
char buff[1024];
if (!FT_Get_Glyph_Name(face, currentIndex, buff, sizeof(buff))) {
faceName = currentFilename;
} else {
faceName = std::string(buff);
}
} else {
faceName = currentFilename;
}
kerning = FT_HAS_KERNING(face);
} else {
faceLoaded = false;
std::ostringstream fail;
fail << "Could not load freetype font " << filename.path() << " error code " << error;
throw Exception(fail.str());
}
return faceLoaded;
}
- //! Get text length
+ //! Get text length
int freetype::getLength(const std::string & text) {
Util::Thread::ScopedLock locked(lock);
int length=0;
std::map<int, std::map<signed long, character*> >::iterator ft;
ft = fontTable.find(size.createKey());
if (ft != fontTable.end()){
for (unsigned int i = 0; i < text.length(); i++) {
std::map<signed long, character*>::iterator p;
signed long unicode = Utf::readUtf8CodePoint(text, &i);
p = (ft->second).find(unicode);
if (p != (ft->second).end()){
if (p != fontTable[size.createKey()].end()){
length += (p->second)->length;
}
}
}
}
return length;
}
- //! Render font to a bitmap
+ //! Render font to a bitmap
void freetype::render(int x, int y, const Graphics::Color & color, const Graphics::Bitmap & bmp, ftAlign alignment, const std::string & text, int marker ...) {
if (faceLoaded){
int rend_x = 0;
int rend_y = 0;
std::ostringstream str;
/* use vsnprintf/Util::limitPrintf here? */
// Get extra arguments
va_list ap;
va_start(ap, marker);
for(unsigned int i = 0; i<text.length();++i) {
if (text[i] == '%') {
if(text[i+1]=='s') {
str << va_arg(ap, char *);
++i;
} else if(text[i+1]=='d'||text[i+1]=='i') {
str << va_arg(ap, signed int);
++i;
} else if(text[i+1]=='c') {
str << (char)va_arg(ap, int);
++i;
} else str << text[i];
} else {
str << text[i];
}
}
va_end(ap);
std::string fixedText(str.str());
switch (alignment) {
case ftLeft:
rend_x = x;
rend_y = y;
break;
case ftCenter:
rend_x = x - getLength(fixedText)/2;
rend_y = y;
break;
case ftRight:
rend_x = x - getLength(fixedText);
rend_y = y;
break;
default:
rend_x = x;
rend_y = y;
break;
}
int previous = 0;
int next = 0;
for (unsigned int i = 0; i<fixedText.length(); i++){
long unicode = Utf::readUtf8CodePoint(fixedText, &i);
if (kerning && previous && next){
next = FT_Get_Char_Index(face, unicode);
FT_Vector delta;
FT_Get_Kerning(face, previous, next, FT_KERNING_DEFAULT, &delta);
rend_x += delta.x >> 6;
previous = next;
}
drawCharacter(unicode, rend_x, rend_y, bmp, color);
}
}
}
-
+
int freetype::calculateMaximumHeight(){
Util::Thread::ScopedLock locked(lock);
/* uhh, comment out the printf's ?? */
std::map<int, std::map<signed long, character*> >::iterator ft;
ft = fontTable.find(size.createKey());
int top = 0;
long code = 0;
if ( ft != fontTable.end() ){
std::map<signed long, character*>::iterator p;
std::map< signed long, character* > & map = ft->second;
for ( p = map.begin(); p != map.end(); p++ ){
const character * ch = p->second;
printf( "%c( %ld ). top = %d. rows = %d. total = %d\n", (char) ch->unicode, ch->unicode, ch->top, ch->rows, ch->top + ch->rows );
if ( ch->top + ch->rows > top ){
code = ch->unicode;
top = ch->top + ch->rows;
}
}
}
printf( "Largest letter = %ld\n", code );
return top;
}
int freetype::height(long code) const {
Util::Thread::ScopedLock locked(lock);
std::map<int, std::map<signed long, character*> >::const_iterator ft;
ft = fontTable.find(size.createKey());
if (ft != fontTable.end()){
std::map<signed long, character*>::const_iterator p;
p = (ft->second).find( code );
if ( p != (ft->second).end() ){
const character * temp = p->second;
// printf( "%c top = %d rows = %d\n", (char) code, temp.top, temp.rows );
return temp->top + temp->rows;
}
} else {
throw Exception("Internal inconsistency");
}
return 0;
}
- int freetype::calculateHeight(const std::string & str) const {
+ int freetype::calculateHeight(const std::string & str) const {
int max = 0;
for ( unsigned int i = 0; i < str.length(); i++ ){
int q = height(str[i]);
// printf( "Height of %c is %d\n", str[ i ], q );
if (q > max){
max = q;
}
}
return max;
- }
+ }
- //! Set size
- void freetype::setSize( unsigned int w, unsigned int h){
+ //! Set size
+ void freetype::setSize( unsigned int w, unsigned int h){
Util::Thread::ScopedLock locked(lock);
if ( w != size.width || h != size.height ){
if (internalFix)return;
if (w<=0 || h<=0)return;
size.width = w;
size.height = h;
createIndex();
// maximumHeight = calculateMaximumHeight();
}
- }
+ }
- //! Set italics
- void freetype::setItalics(int i){
+ //! Set italics
+ void freetype::setItalics(int i){
Util::Thread::ScopedLock locked(lock);
- if(internalFix)return;
- if(i<-45)i=(-45);
- else if(i>45)i=45;
- size.italics = i;
- createIndex();
- }
+ if(internalFix)return;
+ if(i<-45)i=(-45);
+ else if(i>45)i=45;
+ size.italics = i;
+ createIndex();
+ }
void freetype::getSize(int * w, int * h) const {
*w = size.width;
*h = size.height;
}
- //! Get Width
- int freetype::getWidth() const {
+ //! Get Width
+ int freetype::getWidth() const {
return size.width;
- }
+ }
- //! Get Height
- int freetype::getHeight( const std::string & str ) const {
+ //! Get Height
+ int freetype::getHeight( const std::string & str ) const {
// return size.height;
return calculateHeight(str);
}
- //! Get Italics
- int freetype::getItalics(){
+ //! Get Italics
+ int freetype::getItalics(){
return size.italics;
- }
+ }
#endif
}
#endif /* FONT_BASE_CPP */
diff --git a/src/funcs.cpp b/src/funcs.cpp
index 7004176e..5887efda 100644
--- a/src/funcs.cpp
+++ b/src/funcs.cpp
@@ -1,387 +1,387 @@
#ifdef USE_ALLEGRO
#include <allegro.h>
#endif
#ifdef USE_SDL
#include <SDL.h>
#endif
#ifdef USE_ALLEGRO5
#include <allegro5/allegro.h>
#endif
-#include "funcs.h"
-#include "debug.h"
+#include "r-tech1/funcs.h"
+#include "r-tech1/debug.h"
#include <vector>
#include <string>
#include <string.h>
#include <algorithm>
-#include "file-system.h"
-#include "graphics/bitmap.h"
-#include "font.h"
-#include "init.h"
+#include "r-tech1/file-system.h"
+#include "r-tech1/graphics/bitmap.h"
+#include "r-tech1/font.h"
+#include "r-tech1/init.h"
#include <sstream>
-#include "file-system.h"
+#include "r-tech1/file-system.h"
#include <math.h>
#ifndef USE_ALLEGRO
/* FIXME: move this to the filesystem module */
-#include "sfl/sfl.h"
-#include "sfl/sflfile.h"
+#include "libs/sfl/sfl.h"
+#include "libs/sfl/sflfile.h"
#endif
#ifndef WINDOWS
#include <unistd.h>
#endif
#ifdef max
#undef max
#endif
#ifdef min
#undef min
#endif
using namespace std;
/* remove this once cmake and scons properly set DATA_PATH */
#ifndef DATA_PATH
#define DATA_PATH "data"
#endif
/* the build system should define DATA_PATH */
static string dataPath = DATA_PATH;
const double Util::pi = 3.14159265358979323846;
double Util::radians(double degree){
return degree * pi / 180.0;
}
double Util::degrees(double radians){
return radians * 180.0 / pi;
}
/*
inline int rnd( int q ){
- if ( q <= 0 ) return 0;
- return (int)( rand() % q );
+ if ( q <= 0 ) return 0;
+ return (int)( rand() % q );
}
*/
int Util::max(int a, int b){
if (a>b){
return a;
}
return b;
}
double Util::min(double a, double b){
if (a < b){
return a;
}
return b;
}
double Util::max(double a, double b){
if (a > b){
return a;
}
return b;
}
/*
int Util::min(int a, int b){
if (a<b){
return a;
}
return b;
}
*/
int Util::clamp(int value, int min, int max){
return Util::min(Util::max(value, min), max);
}
double Util::clamp(double value, double min, double max){
return Util::min(Util::max(value, min), max);
}
int Util::rnd( int q, int min, int range ){
- return q - min + rnd( range );
+ return q - min + rnd( range );
}
int Util::rnd( int min, int max ){
- return rnd( max - min ) + min;
+ return rnd( max - min ) + min;
}
/* sleep for `x' milliseconds */
void Util::rest( int x ){
#ifdef USE_ALLEGRO
::rest(x);
#endif
#ifdef USE_SDL
SDL_Delay(x);
#endif
#ifdef USE_ALLEGRO5
al_rest((double) x / 1000.0);
#endif
}
void Util::restSeconds(double x){
Util::rest((int)(x * 1000));
}
#if 0
bool Util::checkVersion(int version){
if (version == Global::getVersion()){
return true;
}
/* when an incompatible version is made, add a check here, like
* version < getVersion(3, 5)
* would mean any client below version 3.5 is incompatible.
*
* assume versions of client's greater than ourself is compatible, but
* this may not be true. There is no way to check this.
*/
if (version < 0){
return false;
}
return true;
}
#endif
void Util::setDataPath( const string & str ){
- dataPath = str;
+ dataPath = str;
}
Filesystem::AbsolutePath Util::getDataPath2(){
return Filesystem::AbsolutePath(dataPath + "/");
}
/* FIXME: remove this method */
bool Util::exists( const string & file ){
return Storage::instance().exists(Filesystem::AbsolutePath(file));
/*
#ifdef USE_ALLEGRO
return ::exists(file.c_str()) != 0;
#else
return file_exists(file.c_str());
#endif
*/
}
/*
vector<Filesystem::AbsolutePath> Util::getFiles(const Filesystem::AbsolutePath & dataPath, const string & find){
return Filesystem::getFiles(dataPath, find);
}
*/
string Util::trim(const std::string & str){
string s;
size_t startpos = str.find_first_not_of(" \t");
size_t endpos = str.find_last_not_of(" \t");
// if all spaces or empty return an empty string
if ((string::npos == startpos) ||
(string::npos == endpos)){
return "";
} else {
return str.substr(startpos, endpos-startpos+1);
}
return str;
}
/* makes the first letter of a string upper case */
string Util::upcase(std::string str){
if ( str.length() > 0 && (str[0] >= 'a' && str[0] <= 'z') ){
str[0] = str[0] - 'a' + 'A';
}
return str;
}
static int lowerCase(int c){
return tolower(c);
}
static int upperCase(int c){
return toupper(c);
}
string Util::upperCaseAll(std::string str){
std::transform(str.begin(), str.end(), str.begin(), upperCase);
return str;
}
string Util::lowerCaseAll(std::string str){
std::transform(str.begin(), str.end(), str.begin(), lowerCase);
/*
for (unsigned int i = 0; i < str.length(); i++){
if (str[0] >= 'A' && str[0] <= 'Z'){
str[0] = str[0] - 'A' + 'a';
}
}
*/
return str;
}
// Split string
std::vector<std::string> Util::splitString(std::string str, char splitter){
std::vector<std::string> strings;
size_t next = str.find(splitter);
while (next != std::string::npos){
strings.push_back(str.substr(0, next));
str = str.substr(next+1);
next = str.find(splitter);
}
if (str != ""){
strings.push_back(str);
}
return strings;
}
// Join strings
std::string Util::joinStrings(const std::vector< std::string > & message, unsigned int start){
std::string all;
for (unsigned int i = start; i < message.size(); ++i){
all+=message.at(i) + (i < message.size()-1 ? " " : "");
}
return all;
}
/*Gets the minimum of three values*/
static int minimum(int a,int b,int c){
int min=a;
if(b<min)
min=b;
if(c<min)
min=c;
return min;
}
/* Compute levenshtein distance between s and t
* from: http://www.merriampark.com/ldc.htm
*/
static int levenshtein_distance(const char *s, const char *t){
//Step 1
int k,i,j,n,m,cost,distance;
int * d;
n=strlen(s);
m=strlen(t);
if(n!=0&&m!=0){
d = (int*) malloc((sizeof(int))*(m+1)*(n+1));
m++;
n++;
- //Step 2
+ //Step 2
for(k=0;k<n;k++)
- d[k]=k;
+ d[k]=k;
for(k=0;k<m;k++)
d[k*n]=k;
- //Step 3 and 4
+ //Step 3 and 4
for(i=1;i<n;i++)
for(j=1;j<m;j++)
- {
+ {
//Step 5
if(s[i-1]==t[j-1])
cost=0;
else
cost=1;
- //Step 6
+ //Step 6
d[j*n+i]=minimum(d[(j-1)*n+i]+1,d[j*n+i-1]+1,d[(j-1)*n+i-1]+cost);
}
distance=d[n*m-1];
free(d);
return distance;
} else {
return -1; //a negative return value means that one or both strings are empty.
}
}
int Util::levenshtein(const std::string & str1, const std::string & str2){
return levenshtein_distance(str1.c_str(), str2.c_str());
}
void Util::limitPrintf(char * buffer, int size, const char * format, va_list args){
#ifdef USE_ALLEGRO
uvszprintf(buffer, size, format, args);
#else
vsnprintf(buffer, size, format, args);
#endif
}
/*
#ifndef WINDOWS
int Util::getPipe(int files[2]){
#ifdef PS3
return 0;
#else
return pipe(files);
#endif
}
#endif
*/
void Util::showError(const Graphics::Bitmap & screen, const Exception::Base & exception, const string & info){
// screen.BlitFromScreen(0, 0);
Graphics::Bitmap error(screen.getWidth() - 100, screen.getHeight() - 100);
error.fill(Graphics::darken(Graphics::makeColor(160, 0, 0), 3));
error.border(1, 2, Graphics::makeColor(240, 0, 0));
const Font & font = Font::getDefaultFont(17, 17);
int y = 10;
std::ostringstream out;
out << info;
out << " " << exception.getTrace();
Global::debug(0) << out.str() << std::endl;
font.printfWrap(10, 10, Graphics::makeColor(240, 240, 240), error, error.getWidth() - 20, out.str(), 0);
Graphics::Bitmap::transBlender(0, 0, 0, 220);
error.translucent().draw(50, 50, screen);
screen.BlitToScreen();
}
void Util::showError(const Exception::Base & exception, const std::string & info){
Graphics::Bitmap screen(*Graphics::screenParameter.current());
showError(screen, exception, info);
}
static double twoDigits(double x){
return (int) (x * 100) / 100.0;
}
string Util::niceSize(unsigned long size){
const char sizes[] = {'b', 'k', 'm', 'g', 't'};
double real = size;
for (unsigned int i = 0; i < sizeof(sizes) / sizeof(const char); i++){
if (real > 1024){
real /= 1024.0;
} else {
ostringstream in;
in << twoDigits(real) << sizes[i];
return in.str();
}
}
ostringstream in;
in << twoDigits(real) << "t";
return in.str();
}
std::string Util::join(const std::vector<std::string> & list, const std::string & middle){
ostringstream out;
bool first = true;
for (std::vector<std::string>::const_iterator it = list.begin(); it != list.end(); it++){
if (!first){
out << middle;
}
out << *it;
first = false;
}
return out.str();
}
double Util::distance(double x1, double y1, double x2, double y2){
double xs = x1 - x2;
double ys = y1 - y2;
return sqrt(xs * xs + ys * ys);
}
diff --git a/src/graphics/allegro5/bitmap.cpp b/src/graphics/allegro5/bitmap.cpp
index 492bb730..51441538 100644
--- a/src/graphics/allegro5/bitmap.cpp
+++ b/src/graphics/allegro5/bitmap.cpp
@@ -1,1633 +1,1633 @@
#include <sstream>
#include <allegro5/allegro5.h>
#include <allegro5/allegro_memfile.h>
#include <allegro5/allegro_primitives.h>
-#include "util/debug.h"
-#include "util/thread.h"
+#include "r-tech1/debug.h"
+#include "r-tech1/thread.h"
#include <vector>
namespace Graphics{
ALLEGRO_DISPLAY * the_display = NULL;
static std::vector<ALLEGRO_SHADER*> shaders;
// static ALLEGRO_SHADER * shader_default;
static ALLEGRO_SHADER * shader_shadow;
static ALLEGRO_SHADER * shader_lit_sprite;
enum BlendingType{
Translucent,
Add,
Difference,
Multiply
};
struct BlendingData{
BlendingData():
red(0), green(0), blue(0), alpha(0), type(Translucent){
}
int red, green, blue, alpha;
BlendingType type;
};
static BlendingData globalBlend;
Color makeColorAlpha(unsigned char red, unsigned char green, unsigned char blue, unsigned char alpha){
return Color(al_map_rgba(red, green, blue, alpha));
}
Color MaskColor(){
static Color mask = makeColorAlpha(0, 0, 0, 0);
return mask;
}
Color getBlendColor(){
/* sort of a hack */
if (globalBlend.type == Multiply){
return makeColorAlpha(255, 255, 255, 255);
}
return makeColorAlpha(255, 255, 255, globalBlend.alpha);
}
Color doTransBlend(const Color & color, int alpha){
unsigned char red, green, blue;
al_unmap_rgb(color.color, &red, &green, &blue);
return makeColorAlpha(red, green, blue, alpha);
/*
red *= alpha_f;
green *= alpha_f;
blue *= alpha_f;
return al_map_rgb_f(red, green, blue);
*/
}
Color transBlendColor(const Color & color){
return doTransBlend(color, globalBlend.alpha);
}
int getRealWidth(const Bitmap & what){
return al_get_bitmap_width(what.getData()->getBitmap());
}
int getRealHeight(const Bitmap & what){
return al_get_bitmap_height(what.getData()->getBitmap());
}
class Blender{
public:
Blender(){
}
virtual ~Blender(){
/* default is to draw the source and ignore the destination */
al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO);
}
};
class MaskedBlender: public Blender {
public:
MaskedBlender(){
al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA);
}
};
class LitBlender: public Blender {
public:
LitBlender(ALLEGRO_COLOR lit){
// al_set_blend_color(lit);
// al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE_MINUS_DST_COLOR, ALLEGRO_ZERO);
}
};
class TransBlender: public Blender {
public:
TransBlender(){
switch (globalBlend.type){
case Translucent: al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA); break;
case Add: al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE); break;
case Multiply: al_set_blender(ALLEGRO_ADD, ALLEGRO_DEST_COLOR, ALLEGRO_INVERSE_ALPHA); break;
case Difference: al_set_blender(ALLEGRO_DEST_MINUS_SRC, ALLEGRO_ONE, ALLEGRO_ONE); break;
}
}
};
static const int WINDOWED = 0;
static const int FULLSCREEN = 1;
// static Bitmap * Scaler = NULL;
Bitmap::Bitmap():
mustResize(false),
bit8MaskColor(makeColor(0, 0, 0)),
width(0),
height(0){
/* TODO */
}
Bitmap::Bitmap( const char * load_file ):
mustResize(false),
bit8MaskColor(makeColor(0, 0, 0)){
internalLoadFile(load_file);
width = al_get_bitmap_width(getData()->getBitmap());
height = al_get_bitmap_height(getData()->getBitmap());
}
Bitmap::Bitmap( const std::string & load_file ):
mustResize(false),
bit8MaskColor(makeColor(0, 0, 0)){
internalLoadFile(load_file.c_str());
width = al_get_bitmap_width(getData()->getBitmap());
height = al_get_bitmap_height(getData()->getBitmap());
}
Bitmap::Bitmap(ALLEGRO_BITMAP * who, bool deep_copy):
mustResize(false),
bit8MaskColor(makeColor(0, 0, 0)){
if (deep_copy){
ALLEGRO_BITMAP * clone = al_clone_bitmap(who);
setData(Util::ReferenceCount<BitmapData>(new BitmapData(clone)));
} else {
setData(Util::ReferenceCount<BitmapData>(new BitmapData(who)));
}
this->width = al_get_bitmap_width(getData()->getBitmap());
this->height = al_get_bitmap_height(getData()->getBitmap());
}
Bitmap::Bitmap(int width, int height):
mustResize(false),
bit8MaskColor(makeColor(0, 0, 0)){
ALLEGRO_BITMAP * bitmap = al_create_bitmap(width, height);
if (bitmap == NULL){
std::ostringstream out;
out << "Could not create bitmap with dimensions " << width << ", " << height;
throw BitmapException(__FILE__, __LINE__, out.str());
}
/*
if (al_get_bitmap_flags(bitmap) & ALLEGRO_VIDEO_BITMAP){
ALLEGRO_BITMAP * old = al_get_target_bitmap();
al_set_target_bitmap(bitmap);
al_use_shader(shader_default);
al_set_target_bitmap(old);
}
*/
setData(Util::ReferenceCount<BitmapData>(new BitmapData(bitmap)));
this->width = al_get_bitmap_width(getData()->getBitmap());
this->height = al_get_bitmap_height(getData()->getBitmap());
}
Bitmap::Bitmap(const Bitmap & copy, bool deep_copy):
mustResize(false),
bit8MaskColor(copy.bit8MaskColor),
width(copy.width),
height(copy.height){
if (deep_copy){
ALLEGRO_BITMAP * clone = al_clone_bitmap(copy.getData()->getBitmap());
setData(Util::ReferenceCount<BitmapData>(new BitmapData(clone)));
} else {
setData(copy.getData());
}
}
Bitmap Bitmap::createMemoryBitmap(int width, int height){
int flags = al_get_new_bitmap_flags();
al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP);
Bitmap out = Bitmap(width, height);
al_set_new_bitmap_flags(flags);
return out;
}
void Bitmap::convertToVideo(){
ALLEGRO_BITMAP * original = getData()->getBitmap();
ALLEGRO_BITMAP * copy = al_clone_bitmap(original);
if (copy == NULL){
throw BitmapException(__FILE__, __LINE__, "Could not create video bitmap");
}
al_destroy_bitmap(getData()->getBitmap());
getData()->setBitmap(copy);
/*
if (al_get_bitmap_flags(copy) & ALLEGRO_VIDEO_BITMAP){
ALLEGRO_BITMAP * old = al_get_target_bitmap();
al_set_target_bitmap(copy);
al_use_shader(shader_default);
al_set_target_bitmap(old);
}
*/
}
void changeTarget(const Bitmap & from, const Bitmap & who){
/* pray that if drawing is held then who is already the current target */
if (!al_is_bitmap_drawing_held()){
if (al_get_target_bitmap() != who.getData()->getBitmap()){
al_set_target_bitmap(who.getData()->getBitmap());
}
if ((al_get_bitmap_flags(who.getData()->getBitmap()) & ALLEGRO_VIDEO_BITMAP) &&
(al_get_bitmap_flags(from.getData()->getBitmap()) & ALLEGRO_MEMORY_BITMAP)){
((Bitmap&) from).convertToVideo();
/* How can from == who? If they were the same then the bitmap flags above
* would not have been different.
*/
if (&from == &who){
al_set_target_bitmap(who.getData()->getBitmap());
}
}
}
}
void changeTarget(const Bitmap * from, const Bitmap & who){
changeTarget(*from, who);
}
void changeTarget(const Bitmap & from, const Bitmap * who){
changeTarget(from, *who);
}
void changeTarget(const Bitmap * from, const Bitmap * who){
changeTarget(*from, *who);
}
void dumpColor(const Color & color){
unsigned char red, green, blue, alpha;
al_unmap_rgba(color.color, &red, &green, &blue, &alpha);
Global::debug(0) << "red " << (int) red << " green " << (int) green << " blue " << (int) blue << " alpha " << (int) alpha << std::endl;
}
Color pcxMaskColor(unsigned char * data, const int length){
if (length >= 769){
if (data[length - 768 - 1] == 12){
unsigned char * palette = &data[length - 768];
unsigned char red = palette[0];
unsigned char green = palette[1];
unsigned char blue = palette[2];
return makeColorAlpha(red, green, blue, 255);
}
}
return makeColorAlpha(255, 255, 255, 255);
}
Bitmap memoryPCX(unsigned char * const data, const int length, const bool mask){
ALLEGRO_FILE * memory = al_open_memfile((void *) data, length, "r");
ALLEGRO_BITMAP * pcx = al_load_bitmap_f(memory, ".pcx");
al_fclose(memory);
if (pcx == NULL){
throw BitmapException(__FILE__, __LINE__, "Could not load pcx");
}
// dumpColor(al_get_pixel(pcx, 0, 0));
Bitmap out(pcx);
out.set8BitMaskColor(pcxMaskColor(data, length));
return out;
}
static bool isVideoBitmap(ALLEGRO_BITMAP * bitmap){
return (al_get_bitmap_flags(bitmap) & ALLEGRO_VIDEO_BITMAP) &&
!(al_get_bitmap_flags(bitmap) & ALLEGRO_MEMORY_BITMAP);
}
void Bitmap::replaceColor(const Color & original, const Color & replaced){
changeTarget(this, this);
if (isVideoBitmap(getData()->getBitmap())){
al_lock_bitmap(getData()->getBitmap(), ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_READWRITE);
}
int width = getRealWidth(*this);
int height = getRealHeight(*this);
for (int x = 0; x < width; x++){
for (int y = 0; y < height; y++){
Color pixel = getPixel(x, y);
if (pixel == original){
al_put_pixel(x, y, replaced.color);
}
}
}
if (isVideoBitmap(getData()->getBitmap())){
al_unlock_bitmap(getData()->getBitmap());
}
}
static ALLEGRO_BITMAP * memoryGIF(const char * data, int length){
ALLEGRO_FILE * memory = al_open_memfile((void *) data, length, "r");
al_fclose(memory);
/* FIXME: get gif addon for a5 */
#if 0
RGB * palette = NULL;
/* algif will close the packfile for us in both error and success cases */
BITMAP * gif = load_gif_packfile(pack, palette);
if (!gif){
al_fclose(memory);
// pack_fclose(pack);
ostringstream out;
out <<"Could not load gif from memory: " << (void*) data << " length " << length;
throw LoadException(__FILE__, __LINE__, out.str());
}
BITMAP * out = create_bitmap(gif->w, gif->h);
blit(gif, out, 0, 0, 0, 0, gif->w, gif->h);
destroy_bitmap(gif);
// pack_fclose(pack);
#endif
ALLEGRO_BITMAP * out = NULL;
return out;
}
void Bitmap::internalLoadFile(const char * path){
this->path = path;
ALLEGRO_BITMAP * loaded = al_load_bitmap(path);
if (loaded == NULL){
std::ostringstream out;
out << "Could not load file '" << path << "'";
throw BitmapException(__FILE__, __LINE__, out.str());
}
al_convert_mask_to_alpha(loaded, al_map_rgb(255, 0, 255));
setData(Util::ReferenceCount<BitmapData>(new BitmapData(loaded)));
}
static ALLEGRO_BITMAP * do_load_from_memory(const char * data, int length, const char * type){
ALLEGRO_FILE * memory = al_open_memfile((void*) data, length, "r");
ALLEGRO_BITMAP * bitmap = al_load_bitmap_f(memory, type);
al_fclose(memory);
al_convert_mask_to_alpha(bitmap, al_map_rgb(255, 0, 255));
return bitmap;
}
static ALLEGRO_BITMAP * load_bitmap_from_memory(const char * data, int length, ImageFormat type){
switch (type){
case FormatBMP: return do_load_from_memory(data, length, ".bmp");
case FormatPNG: return do_load_from_memory(data, length, ".png");
case FormatJPG: return do_load_from_memory(data, length, ".jpg");
case FormatPCX: return do_load_from_memory(data, length, ".pcx");
case FormatTGA: return do_load_from_memory(data, length, ".tga");
case FormatTIF: return do_load_from_memory(data, length, ".tif");
case FormatXPM: return do_load_from_memory(data, length, ".xpm");
case FormatUnknown: break;
case FormatGIF : {
return memoryGIF(data, length);
break;
}
}
std::ostringstream out;
out << "Could not load the bitmap because its format was not known";
throw BitmapException(__FILE__, __LINE__, out.str());
}
Bitmap::Bitmap(const char * data, int length):
mustResize(false),
bit8MaskColor(makeColor(0, 0, 0)){
loadFromMemory(data, length);
}
void Bitmap::loadFromMemory(const char * data, int length){
setData(Util::ReferenceCount<BitmapData>(new BitmapData(load_bitmap_from_memory(data, length, identifyImage((const unsigned char *) data, length)))));
if (getData()->getBitmap() == NULL){
std::ostringstream out;
out << "Could not create bitmap from memory";
throw BitmapException(__FILE__, __LINE__, out.str());
}
width = al_get_bitmap_width(getData()->getBitmap());
height = al_get_bitmap_height(getData()->getBitmap());
}
Bitmap::Bitmap( const Bitmap & copy, int x, int y, int width, int height ):
mustResize(false),
bit8MaskColor(copy.bit8MaskColor),
width(width),
height(height){
path = copy.getPath();
ALLEGRO_BITMAP * his = copy.getData()->getBitmap();
if (x < 0)
x = 0;
if (y < 0)
y = 0;
if (width < 1 || height < 1){
std::ostringstream out;
out << "Attempting to create a sub-bitmap.";
if (width < 1){
out << " Width was less than 1: " << width;
}
if (height < 1){
out << " Height was less than 1: " << height;
}
throw BitmapException(__FILE__, __LINE__, out.str());
}
/*
if (width + x > al_get_bitmap_width(his)){
width = al_get_bitmap_width(his) - x;
}
if (height + y > al_get_bitmap_height(his)){
height = al_get_bitmap_height(his) - y;
}
*/
ALLEGRO_BITMAP * old_target = al_get_target_bitmap();
ALLEGRO_TRANSFORM transform;
al_identity_transform(&transform);
if (al_get_target_bitmap() != copy.getData()->getBitmap()){
al_set_target_bitmap(copy.getData()->getBitmap());
}
if (al_get_current_transform() != NULL){
if (old_target != copy.getData()->getBitmap()){
al_set_target_bitmap(copy.getData()->getBitmap());
}
al_copy_transform(&transform, al_get_current_transform());
}
float x_scaled = x;
float y_scaled = y;
float width_scaled = width;
float height_scaled = height;
al_transform_coordinates(&transform, &x_scaled, &y_scaled);
al_transform_coordinates(&transform, &width_scaled, &height_scaled);
// ALLEGRO_BITMAP * sub = al_create_sub_bitmap(his, x, y, width, height);
ALLEGRO_BITMAP * sub = al_create_sub_bitmap(his, (int) x_scaled, (int) y_scaled, (int) width_scaled, (int) height_scaled);
// ALLEGRO_BITMAP * sub = al_create_sub_bitmap(his, (int) x_scaled, (int) y_scaled, width, height);
setData(Util::ReferenceCount<BitmapData>(new BitmapData(sub)));
al_set_target_bitmap(sub);
al_use_transform(&transform);
al_set_target_bitmap(old_target);
}
static bool isBackBuffer(ALLEGRO_BITMAP * bitmap){
return bitmap == al_get_backbuffer(the_display);
}
int Bitmap::getWidth() const {
/* Always return the true dimensions of the backbuffer */
if (getData() != NULL && isBackBuffer(getData()->getBitmap())){
return al_get_bitmap_width(getData()->getBitmap());
}
return width;
/*
if (getData()->getBitmap() != NULL){
return al_get_bitmap_width(getData()->getBitmap());
}
return 0;
*/
}
int getRed(Color color){
unsigned char red, green, blue;
al_unmap_rgb(color.color, &red, &green, &blue);
return red;
}
int getAlpha(Color color){
unsigned char red, green, blue, alpha;
al_unmap_rgba(color.color, &red, &green, &blue, &alpha);
return alpha;
}
int getGreen(Color color){
unsigned char red, green, blue;
al_unmap_rgb(color.color, &red, &green, &blue);
return green;
}
int getBlue(Color color){
unsigned char red, green, blue;
al_unmap_rgb(color.color, &red, &green, &blue);
return blue;
}
Color makeColor(int red, int blue, int green){
return Color(al_map_rgb(red, blue, green));
}
int Bitmap::getHeight() const {
if (getData() != NULL && isBackBuffer(getData()->getBitmap())){
return al_get_bitmap_height(getData()->getBitmap());
}
return height;
/*
if (getData()->getBitmap() != NULL){
return al_get_bitmap_height(getData()->getBitmap());
}
return 0;
*/
}
void initializeExtraStuff(){
// al_set_new_bitmap_format(ALLEGRO_PIXEL_FORMAT_RGB_565);
}
std::string defaultVertexShader(){
return std::string(al_get_default_shader_source(ALLEGRO_SHADER_GLSL, ALLEGRO_VERTEX_SHADER));
}
std::string defaultPixelShader(){
return std::string(al_get_default_shader_source(ALLEGRO_SHADER_GLSL, ALLEGRO_PIXEL_SHADER));
}
void setShaderSampler(ALLEGRO_SHADER * shader, const std::string & name, const Bitmap & texture, int unit){
al_set_shader_sampler(name.c_str(), texture.getData()->getBitmap(), unit);
}
void setShaderBool(ALLEGRO_SHADER * shader, const std::string & name, bool value){
setShaderInt(shader, name, value);
}
void setShaderInt(ALLEGRO_SHADER * shader, const std::string & name, int value){
al_set_shader_int(name.c_str(), value);
}
void setShaderFloat(ALLEGRO_SHADER * shader, const std::string & name, float value){
al_set_shader_float(name.c_str(), value);
}
void setShaderVec4(ALLEGRO_SHADER * shader, const std::string & name, float v1, float v2, float v3, float v4){
float vector[4];
vector[0] = v1;
vector[1] = v2;
vector[2] = v3;
vector[3] = v4;
al_set_shader_float_vector(name.c_str(), 4, &vector[0], 1);
}
ALLEGRO_SHADER * create_shader(const std::string & vertex, const std::string & pixel){
ALLEGRO_SHADER * shader = al_create_shader(ALLEGRO_SHADER_GLSL);
if (shader == NULL){
return NULL;
}
if (!al_attach_shader_source(shader, ALLEGRO_VERTEX_SHADER, vertex.c_str())){
Global::debug(0) << "attach vertex shader source failed: " << al_get_shader_log(shader) << std::endl << vertex << std::endl;
return NULL;
}
if (!al_attach_shader_source(shader, ALLEGRO_PIXEL_SHADER, pixel.c_str())){
Global::debug(0) << "attach pixel shader source failed: " << al_get_shader_log(shader) << std::endl << pixel << std::endl;
return NULL;
}
if (!al_build_shader(shader)){
Global::debug(0) << "shader al_link_shader failed: " << al_get_shader_log(shader) << std::endl;
return NULL;
}
return shader;
}
int changeGraphicsMode(int mode, int width, int height){
switch (mode){
case FULLSCREEN: {
al_set_display_flag(the_display, ALLEGRO_FULLSCREEN_WINDOW, true);
break;
}
case WINDOWED: {
al_set_display_flag(the_display, ALLEGRO_FULLSCREEN_WINDOW, false);
break;
}
}
return !al_resize_display(the_display, width, height);
}
static int createShaders(){
try{
shader_shadow = create_shader(defaultVertexShader(), Storage::readFile(Storage::instance().find(Filesystem::RelativePath("shaders/shadow.fragment.glsl"))));
if (shader_shadow == NULL){
return 1;
}
shaders.push_back(shader_shadow);
Global::debug(1) << "Created shadow shader" << std::endl;
} catch (const Filesystem::NotFound & fail){
Global::debug(0) << "Could not load shadow shader: " << fail.getTrace() << std::endl;
return 1;
}
try{
shader_lit_sprite = create_shader(defaultVertexShader(), Storage::readFile(Storage::instance().find(Filesystem::RelativePath("shaders/lit-sprite.fragment.glsl"))));
if (shader_lit_sprite == NULL){
return 1;
}
shaders.push_back(shader_lit_sprite);
Global::debug(1) << "Created lit sprite shader" << std::endl;
} catch (const Filesystem::NotFound & fail){
Global::debug(0) << "Could not load lit sprite shader: " << fail.getTrace() << std::endl;
return 1;
}
return 0;
}
int setGraphicsMode(int mode, int width, int height){
initializeExtraStuff();
/* FIXME: the configuration should pass in fullscreen mode here */
#ifdef IPHONE
mode = FULLSCREEN;
#endif
switch (mode){
case FULLSCREEN: {
#ifdef IPHONE
al_set_new_display_option(ALLEGRO_SUPPORTED_ORIENTATIONS, ALLEGRO_DISPLAY_ORIENTATION_LANDSCAPE, ALLEGRO_SUGGEST);
al_set_new_display_flags(ALLEGRO_FULLSCREEN_WINDOW | ALLEGRO_PROGRAMMABLE_PIPELINE);
#else
#ifdef ANDROID
al_set_new_display_flags(ALLEGRO_FULLSCREEN | ALLEGRO_PROGRAMMABLE_PIPELINE);
#else
al_set_new_display_flags(ALLEGRO_FULLSCREEN_WINDOW | ALLEGRO_RESIZABLE |
ALLEGRO_OPENGL | ALLEGRO_PROGRAMMABLE_PIPELINE);
#endif
#endif
break;
}
case WINDOWED: {
al_set_new_display_flags(ALLEGRO_WINDOWED | ALLEGRO_RESIZABLE |
ALLEGRO_PROGRAMMABLE_PIPELINE |
ALLEGRO_OPENGL);
break;
}
default: break;
}
the_display = al_create_display(width, height);
if (the_display == NULL){
std::ostringstream out;
out << "Could not create display with dimensions " << width << ", " << height;
throw BitmapException(__FILE__, __LINE__, out.str());
}
// Global::debug(0) << "Set width " << al_get_display_width(the_display) << " height " << al_get_display_height(the_display) << std::endl;
// Global::debug(0) << "Backbuffer width " << al_get_bitmap_width(al_get_backbuffer(the_display)) << " height " << al_get_bitmap_height(al_get_backbuffer(the_display)) << std::endl;
try{
/* TODO: maybe find a more general way to get the icon */
ALLEGRO_BITMAP * icon = al_load_bitmap(Storage::instance().find(Filesystem::RelativePath("menu/icon.bmp")).path().c_str());
if (icon != NULL){
al_set_display_icon(the_display, icon);
}
} catch (const Filesystem::NotFound & fail){
Global::debug(0) << "Could not set window icon: " << fail.getTrace() << std::endl;
}
Screen = new Bitmap(al_get_backbuffer(the_display));
/* dont destroy the backbuffer */
Screen->getData()->setDestroy(false);
/*
ALLEGRO_TRANSFORM transformation;
al_identity_transform(&transformation);
al_scale_transform(&transformation, (double) Screen->getWidth() / (double) width, (double) Screen->getHeight() / (double) height);
al_set_target_bitmap(Screen->getData()->getBitmap());
al_use_transform(&transformation);
*/
// Scaler = new Bitmap(width, height);
/* default drawing mode */
// al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO);
al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA);
// shader_default = create_shader(defaultVertexShader(), defaultPixelShader());
// al_use_shader(shader_default);
/* Default shader */
/*
shader_default = al_create_shader(ALLEGRO_SHADER_GLSL);
al_attach_shader_source(shader_default, ALLEGRO_VERTEX_SHADER, al_get_default_glsl_vertex_shader());
al_attach_shader_source(shader_default, ALLEGRO_PIXEL_SHADER, al_get_default_glsl_pixel_shader());
if (!al_link_shader(shader_default)){
Global::debug(0) << "default shader al_link_shader failed: " << al_get_shader_log(shader_default) << std::endl;
return 1;
}
*/
// al_set_shader(the_display, shader_default);
// shaders.push_back(shader_default);
// Global::debug(1) << "Created default shader" << std::endl;
if (createShaders()){
return 1;
}
return 0;
}
void Bitmap::lock() const {
al_lock_bitmap(getData()->getBitmap(), ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_READWRITE);
}
void Bitmap::lock(int x, int y, int width, int height) const {
al_lock_bitmap_region(getData()->getBitmap(), x, y, width, height, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_READWRITE);
}
void Bitmap::unlock() const {
al_unlock_bitmap(getData()->getBitmap());
}
Color Bitmap::getPixel(const int x, const int y) const {
// changeTarget(this, this);
return Color(al_get_pixel(getData()->getBitmap(), x, y));
}
void Bitmap::putPixel(int x, int y, Color pixel) const {
changeTarget(this, this);
// al_put_pixel(x, y, pixel);
al_draw_pixel(x, y, pixel.color);
}
void Bitmap::putPixelNormal(int x, int y, Color col) const {
putPixel(x, y, col);
/*
changeTarget(this, this);
al_put_pixel(x, y, col.color);
*/
}
void Bitmap::fill(Color color) const {
changeTarget(this, this);
al_clear_to_color(color.color);
}
void Bitmap::startDrawing() const {
/* we are about to draw on this bitmap so make sure we are the target */
changeTarget(this, this);
al_hold_bitmap_drawing(true);
}
void Bitmap::endDrawing() const {
al_hold_bitmap_drawing(false);
}
void TranslucentBitmap::startDrawing() const {
al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA);
}
void TranslucentBitmap::endDrawing() const {
al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO);
}
Color Bitmap::blendColor(const Color & input) const {
return input;
}
Color TranslucentBitmap::blendColor(const Color & color) const {
unsigned char red, green, blue;
unsigned char alpha = globalBlend.alpha;
al_unmap_rgb(color.color, &red, &green, &blue);
return makeColorAlpha(red, green, blue, alpha);
}
void Bitmap::StretchHqx(const Bitmap & where, const int sourceX, const int sourceY, const int sourceWidth, const int sourceHeight, const int destX, const int destY, const int destWidth, const int destHeight) const {
/* TODO */
}
void Bitmap::StretchXbr(const Bitmap & where, const int sourceX, const int sourceY, const int sourceWidth, const int sourceHeight, const int destX, const int destY, const int destWidth, const int destHeight) const {
/* TODO */
}
void Bitmap::Stretch(const Bitmap & where, const int sourceX, const int sourceY, const int sourceWidth, const int sourceHeight, const int destX, const int destY, const int destWidth, const int destHeight) const {
changeTarget(this, where);
al_draw_scaled_bitmap(getData()->getBitmap(),
sourceX, sourceY, sourceWidth, sourceHeight,
destX, destY, destWidth, destHeight,
0);
}
void Bitmap::StretchBy2(const Bitmap & where){
Stretch(where, 0, 0, getWidth(), getHeight(), 0, 0, getWidth() * 2, getHeight() * 2);
}
void Bitmap::StretchBy4(const Bitmap & where){
Stretch(where, 0, 0, getWidth(), getHeight(), 0, 0, getWidth() * 4, getHeight() * 4);
}
void Bitmap::drawRotate(const int x, const int y, const int angle, const Bitmap & where ){
changeTarget(this, where);
MaskedBlender blender;
al_draw_rotated_bitmap(getData()->getBitmap(), getWidth() / 2, getHeight() / 2, x, y, Util::radians(angle), ALLEGRO_FLIP_HORIZONTAL);
}
void Bitmap::drawPivot( const int centerX, const int centerY, const int x, const int y, const int angle, const Bitmap & where ){
changeTarget(this, where);
MaskedBlender blender;
al_draw_rotated_bitmap(getData()->getBitmap(), getWidth() / 2, getHeight() / 2, x, y, Util::radians(-angle), 0);
}
void Bitmap::drawPivot( const int centerX, const int centerY, const int x, const int y, const int angle, const double scale, const Bitmap & where ){
/* TODO */
}
void Bitmap::drawStretched( const int x, const int y, const int new_width, const int new_height, const Bitmap & who ) const {
/* FIXME */
changeTarget(this, who);
MaskedBlender blender;
al_draw_scaled_bitmap(getData()->getBitmap(), 0, 0, al_get_bitmap_width(getData()->getBitmap()), al_get_bitmap_height(getData()->getBitmap()), x, y, new_width, new_height, 0);
#if 0
ALLEGRO_TRANSFORM save;
al_copy_transform(&save, al_get_current_transform());
ALLEGRO_TRANSFORM stretch;
al_identity_transform(&stretch);
// al_translate_transform(&stretch, x / ((double) new_width / getWidth()), y / ((double) new_height / getHeight()));
al_scale_transform(&stretch, (double) new_width / getWidth(), (double) new_height / getHeight());
al_translate_transform(&stretch, x, y);
// al_translate_transform(&stretch, -x / ((double) new_width / getWidth()), -y / ((double) (new_height / getHeight())));
al_use_transform(&stretch);
/* any source pixels with an alpha value of 0 will be masked */
// al_draw_bitmap(getData().getBitmap(), x, y, 0);
al_draw_bitmap(getData().getBitmap(), 0, 0, 0);
al_use_transform(&save);
#endif
}
Bitmap Bitmap::scaleTo(const int width, const int height) const {
if (width == getRealWidth(*this) && height == getRealHeight(*this)){
return *this;
}
Bitmap scaled(width, height);
changeTarget(*this, scaled);
al_draw_scaled_bitmap(getData()->getBitmap(), 0, 0, getRealWidth(*this), getRealHeight(*this),
0, 0, width, height, 0);
return scaled;
}
void Bitmap::Blit(const int mx, const int my, const int width, const int height, const int wx, const int wy, const Bitmap & where) const {
// double start = al_get_time();
// changeTarget(this, where);
// al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO);
/*
if (&where != Screen){
al_draw_bitmap(getData().getBitmap(), wx, wy, 0);
}
*/
changeTarget(this, where);
Bitmap part(*this, mx, my, width, height);
// al_use_shader(shader_default);
// al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO);
al_draw_bitmap(part.getData()->getBitmap(), wx, wy, 0);
/*
double end = al_get_time();
Global::debug(0) << "Draw in " << (end - start) << " seconds" << std::endl;
*/
}
void Bitmap::drawHFlip(const int x, const int y, const Bitmap & where) const {
draw(x, y, NULL, where, ALLEGRO_FLIP_HORIZONTAL);
}
void Bitmap::drawHFlip(const int x, const int y, Filter * filter, const Bitmap & where) const {
draw(x, y, filter, where, ALLEGRO_FLIP_HORIZONTAL);
}
void Bitmap::drawVFlip( const int x, const int y, const Bitmap & where ) const {
draw(x, y, NULL, where, ALLEGRO_FLIP_VERTICAL);
}
void Bitmap::drawVFlip( const int x, const int y, Filter * filter, const Bitmap & where ) const {
draw(x, y, filter, where, ALLEGRO_FLIP_VERTICAL);
}
void Bitmap::drawHVFlip( const int x, const int y, const Bitmap & where ) const {
draw(x, y, NULL, where, ALLEGRO_FLIP_HORIZONTAL | ALLEGRO_FLIP_VERTICAL);
}
void Bitmap::drawHVFlip( const int x, const int y, Filter * filter, const Bitmap & where ) const {
draw(x, y, filter, where, ALLEGRO_FLIP_HORIZONTAL | ALLEGRO_FLIP_VERTICAL);
}
void Bitmap::BlitMasked(const int mx, const int my, const int width, const int height, const int wx, const int wy, const Bitmap & where) const {
/* TODO */
}
void Bitmap::BlitToScreen(const int upper_left_x, const int upper_left_y) const {
#if 0
if (getWidth() != Screen->getWidth() || getHeight() != Screen->getHeight()){
/*
this->Blit( upper_left_x, upper_left_y, *Buffer );
Buffer->Stretch(*Scaler);
Scaler->Blit(0, 0, 0, 0, *Screen);
*/
this->Stretch(*Scaler, 0, 0, getWidth(), getHeight(), upper_left_x, upper_left_y, Scaler->getWidth(), Scaler->getHeight());
Scaler->Blit(0, 0, 0, 0, *Screen);
} else {
this->Blit(upper_left_x, upper_left_y, *Screen);
}
#endif
/*
if (&where == Screen){
al_flip_display();
}
*/
changeTarget(this, Screen);
if (getData()->getBitmap() != Screen->getData()->getBitmap()){
Blit(*Screen);
}
al_flip_display();
}
void Bitmap::BlitAreaToScreen(const int upper_left_x, const int upper_left_y) const {
changeTarget(this, Screen);
/*
if (getData()->getBitmap() != Screen->getData()->getBitmap()){
Blit(upper_left_y, upper_left_y, *Screen);
}
*/
al_flip_display();
}
void Bitmap::draw(const int x, const int y, Filter * filter, const Bitmap & where, int flags) const {
changeTarget(this, where);
MaskedBlender blender;
Util::ReferenceCount<Shader> shader;
if (filter != NULL){
shader = filter->getShader();
}
ALLEGRO_SHADER * a5shader = NULL;
if (shader != NULL){
a5shader = shader->getShader();
}
if (a5shader != NULL){
al_use_shader(a5shader);
filter->setupShader(shader);
}
/* any source pixels with an alpha value of 0 will be masked */
al_draw_bitmap(getData()->getBitmap(), x, y, flags);
if (a5shader != NULL){
al_use_shader(NULL);
}
}
void Bitmap::draw(const int x, const int y, const Bitmap & where) const {
draw(x, y, NULL, where, 0);
/*
// TransBlender blender;
changeTarget(this, where);
MaskedBlender blender;
/ * any source pixels with an alpha value of 0 will be masked * /
al_draw_bitmap(getData()->getBitmap(), x, y, 0);
*/
}
void Bitmap::draw(const int x, const int y, Filter * filter, const Bitmap & where) const {
draw(x, y, filter, where, 0);
}
void Bitmap::drawShadow(Bitmap & where, int x, int y, int intensity, Color color, double scale, bool facingRight) const {
changeTarget(this, where);
MaskedBlender blender;
int newHeight = fabs(scale) * getHeight();
int flags = 0;
if (!facingRight){
flags |= ALLEGRO_FLIP_HORIZONTAL;
}
float shadowColor[4];
al_unmap_rgb_f(color.color, &shadowColor[0], &shadowColor[1], &shadowColor[2]);
shadowColor[3] = (float) intensity / 255.0;
al_use_shader(shader_shadow);
if (!al_set_shader_float_vector("shadow", 4, shadowColor, 1)){
/* Well.. thats not good. Did the shader source get messed up? */
}
al_draw_scaled_bitmap(getData()->getBitmap(), 0, 0, getWidth(), getHeight(), x, y - newHeight, getWidth(), newHeight, flags);
al_use_shader(NULL);
}
void Bitmap::hLine(const int x1, const int y, const int x2, const Color color) const {
line(x1, y, x2, y, color);
}
void Bitmap::vLine(const int y1, const int x, const int y2, const Color color) const {
line(x, y1, x, y2, color);
}
void Bitmap::arc(const int x, const int y, const double ang1, const double ang2, const int radius, const Color color ) const {
changeTarget(this, this);
al_draw_arc(x, y, radius, ang1 - Util::pi/2, ang2 - ang1, color.color, 1);
}
void TranslucentBitmap::arc(const int x, const int y, const double ang1, const double ang2, const int radius, const Color color ) const {
TransBlender blender;
Bitmap::arc(x, y, ang1, ang2, radius, transBlendColor(color));
/*
changeTarget(this);
al_draw_arc(x, y, radius, ang1 + S_PI/2, ang2 - ang1, doTransBlend(color, globalBlend.alpha), 0);
*/
}
/* from http://www.allegro.cc/forums/thread/605684/892721#target */
#if 0
void al_draw_filled_pieslice(float cx, float cy, float r, float start_theta,
float delta_theta, ALLEGRO_COLOR color){
ALLEGRO_VERTEX vertex_cache[ALLEGRO_VERTEX_CACHE_SIZE];
int num_segments, ii;
num_segments = fabs(delta_theta / (2 * ALLEGRO_PI) * ALLEGRO_PRIM_QUALITY * sqrtf(r));
if (num_segments < 2)
return;
if (num_segments >= ALLEGRO_VERTEX_CACHE_SIZE) {
num_segments = ALLEGRO_VERTEX_CACHE_SIZE - 1;
}
al_calculate_arc(&(vertex_cache[1].x), sizeof(ALLEGRO_VERTEX), cx, cy, r, r, start_theta, delta_theta, 0, num_segments);
vertex_cache[0].x = cx; vertex_cache[0].y = cy;
for (ii = 0; ii < num_segments + 1; ii++) {
vertex_cache[ii].color = color;
vertex_cache[ii].z = 0;
}
al_draw_prim(vertex_cache, NULL, NULL, 0, num_segments + 1, ALLEGRO_PRIM_TRIANGLE_FAN);
// al_draw_prim(vertex_cache, NULL, NULL, 0, 3, ALLEGRO_PRIM_TRIANGLE_FAN);
}
#endif
static float min(float a, float b){
return a < b ? a : b;
}
void Bitmap::roundRect(int radius, int x1, int y1, int x2, int y2, Color color) const {
changeTarget(this, this);
double mx = x2 - x1;
double my = y2 - y1;
double radius_use = min(min(radius, mx / 2), my / 2);
al_draw_rounded_rectangle(x1, y1, x2, y2, radius_use, radius_use, color.color, 1);
}
void TranslucentBitmap::roundRect(int radius, int x1, int y1, int x2, int y2, Color color) const {
TransBlender blender;
Bitmap::roundRect(radius, x1, y1, x2, y2, transBlendColor(color));
}
void Bitmap::roundRectFill(int radius, int x1, int y1, int x2, int y2, Graphics::Color color) const {
changeTarget(this, this);
double mx = x2 - x1;
double my = y2 - y1;
double radius_use = min(min(radius, mx / 2), my / 2);
al_draw_filled_rounded_rectangle(x1, y1, x2, y2, radius_use, radius_use, color.color);
}
void TranslucentBitmap::roundRectFill(int radius, int x1, int y1, int x2, int y2, Graphics::Color color) const {
TransBlender blender;
Bitmap::roundRectFill(radius, x1, y1, x2, y2, transBlendColor(color));
}
void Bitmap::arcFilled(const int x, const int y, const double ang1, const double ang2, const int radius, const Color color ) const {
changeTarget(this, this);
al_draw_filled_pieslice(x, y, radius, ang1 - Util::pi/2, ang2 - ang1, color.color);
}
void TranslucentBitmap::arcFilled(const int x, const int y, const double ang1, const double ang2, const int radius, const Color color ) const {
changeTarget(this, this);
TransBlender blender;
Bitmap::arcFilled(x, y, ang1, ang2, radius, transBlendColor(color));
}
void Bitmap::floodfill( const int x, const int y, const Color color ) const {
/* TODO */
}
void Bitmap::line(const int x1, const int y1, const int x2, const int y2, const Color color) const {
changeTarget(this, this);
al_draw_line(x1, y1, x2, y2, color.color, 1);
}
void TranslucentBitmap::line(const int x1, const int y1, const int x2, const int y2, const Color color) const {
TransBlender blender;
Bitmap::line(x1, y1, x2, y2, transBlendColor(color));
}
void Bitmap::circleFill(int x, int y, int radius, Color color) const {
changeTarget(this, this);
al_draw_filled_circle(x, y, radius, color.color);
}
void Bitmap::circle(int x, int y, int radius, Color color) const {
changeTarget(this, this);
al_draw_circle(x, y, radius, color.color, 1);
}
void Bitmap::circle(int x, int y, int radius, int thickness, Color color) const {
changeTarget(this, this);
al_draw_circle(x, y, radius, color.color, thickness);
}
void Bitmap::rectangle(int x1, int y1, int x2, int y2, Color color ) const {
changeTarget(this, this);
// al_draw_rectangle(x1, y1, x2, y2, color.color, 0);
al_draw_rectangle(x1 + 0.5, y1 + 0.5, x2 - 0.5, y2 - 0.5, color.color, 1);
}
void Bitmap::rectangleFill( int x1, int y1, int x2, int y2, Color color ) const {
changeTarget(this, this);
// al_draw_filled_rectangle(x1 - 0.5, y1 - 0.5, x2 + 0.5, y2 + 0.5, color.color);
al_draw_filled_rectangle(x1, y1, x2 + 1, y2 + 1, color.color);
}
void Bitmap::triangle( int x1, int y1, int x2, int y2, int x3, int y3, Color color ) const {
changeTarget(this, this);
al_draw_filled_triangle(x1, y1, x2, y2, x3, y3, color.color);
}
void Bitmap::polygon( const int * verts, const int nverts, const Color color ) const {
/* TODO */
}
void Bitmap::ellipse( int x, int y, int rx, int ry, Color color ) const {
changeTarget(this, this);
al_draw_ellipse(x, y, rx, ry, color.color, 0);
}
void Bitmap::ellipseFill( int x, int y, int rx, int ry, Color color ) const {
changeTarget(this, this);
al_draw_filled_ellipse(x, y, rx, ry, color.color);
}
void Bitmap::applyTrans(const Color color) const {
TransBlender blender;
changeTarget(this, this);
al_draw_filled_rectangle(0, 0, getWidth(), getHeight(), transBlendColor(color).color);
}
void Bitmap::light(int x, int y, int width, int height, int start_y, int focus_alpha, int edge_alpha, Color focus_color, Color edge_color) const {
/* TODO */
}
void Bitmap::drawCharacter( const int x, const int y, const Color color, const int background, const Bitmap & where ) const {
/* TODO */
}
void Bitmap::save( const std::string & str ) const {
/* TODO */
}
void Bitmap::readLine(std::vector<Color> & line, int y){
/* TODO */
}
void TranslucentBitmap::draw(const int x, const int y, Filter * filter, const Bitmap & where, int flags) const {
changeTarget(this, where);
TransBlender blender;
Util::ReferenceCount<Shader> shader;
if (filter != NULL){
shader = filter->getShader();
}
ALLEGRO_SHADER * a5shader = NULL;
if (shader != NULL){
a5shader = shader->getShader();
}
if (a5shader != NULL){
al_use_shader(a5shader);
filter->setupShader(shader);
}
al_draw_tinted_bitmap(getData()->getBitmap(), getBlendColor().color, x, y, flags);
if (a5shader != NULL){
al_use_shader(NULL);
}
}
void TranslucentBitmap::draw(const int x, const int y, const Bitmap & where) const {
draw(x, y, NULL, where, 0);
}
void LitBitmap::draw(const int x, const int y, const Bitmap & where) const {
draw(x, y, NULL, where, 0);
}
void LitBitmap::draw(const int x, const int y, Filter * filter, const Bitmap & where, int flags) const {
if (filter == NULL){
changeTarget(this, where);
/*
TransBlender blender;
Util::ReferenceCount<Shader> shader;
if (filter != NULL){
shader = filter->getShader();
}
ALLEGRO_SHADER * a5shader = NULL;
if (shader != NULL){
a5shader = shader->getShader();
}
if (a5shader != NULL){
al_set_shader(the_display, a5shader);
al_use_shader(a5shader, true);
}
al_draw_tinted_bitmap(getData()->getBitmap(), getBlendColor().color, x, y, flags);
if (a5shader != NULL){
al_set_shader(the_display, shader_default);
al_use_shader(shader_default, true);
}
*/
MaskedBlender blender;
ALLEGRO_SHADER * shader = shader_lit_sprite;
float light[4];
Color color = makeColor(globalBlend.red, globalBlend.green, globalBlend.blue);
al_unmap_rgb_f(color.color, &light[0], &light[1], &light[2]);
light[3] = 1;
float intensity = (float) globalBlend.alpha / 255.0;
al_use_shader(shader);
if (!al_set_shader_float_vector("light_color", 4, light, 1)){
/* Well.. thats not good. Did the shader source get messed up? */
}
if (!al_set_shader_float("light_intensity", intensity)){
}
al_draw_bitmap(getData()->getBitmap(), x, y, flags);
al_use_shader(NULL);
} else {
Bitmap temp(getWidth(), getHeight());
temp.fill(MaskColor());
Bitmap::draw(0, 0, filter, temp, 0);
LitBitmap(temp).draw(x, y, NULL, where, flags);
}
}
void LitBitmap::draw( const int x, const int y, Filter * filter, const Bitmap & where ) const {
draw(x, y, filter, where, 0);
// LitBlender blender(makeColorAlpha(globalBlend.red, globalBlend.green, globalBlend.blue, globalBlend.alpha));
// TransBlender blender;
// al_draw_bitmap(getData()->getBitmap(), x, y, 0);
// al_draw_tinted_bitmap(getData()->getBitmap(), al_map_rgba_f(1, 0, 0, 1), x, y, 0);
}
void LitBitmap::drawHFlip( const int x, const int y, const Bitmap & where ) const {
draw(x, y, NULL, where, ALLEGRO_FLIP_HORIZONTAL);
}
void LitBitmap::drawHFlip( const int x, const int y, Filter * filter, const Bitmap & where ) const {
draw(x, y, filter, where, ALLEGRO_FLIP_HORIZONTAL);
}
void LitBitmap::drawVFlip( const int x, const int y, const Bitmap & where ) const {
draw(x, y, NULL, where, ALLEGRO_FLIP_VERTICAL);
}
void LitBitmap::drawVFlip( const int x, const int y, Filter * filter, const Bitmap & where ) const {
draw(x, y, filter, where, ALLEGRO_FLIP_VERTICAL);
}
void LitBitmap::drawHVFlip( const int x, const int y, const Bitmap & where ) const {
draw(x, y, NULL, where, ALLEGRO_FLIP_HORIZONTAL | ALLEGRO_FLIP_VERTICAL);
}
void LitBitmap::drawHVFlip( const int x, const int y, Filter * filter, const Bitmap & where ) const {
draw(x, y, filter, where, ALLEGRO_FLIP_HORIZONTAL | ALLEGRO_FLIP_VERTICAL);
}
void TranslucentBitmap::draw( const int x, const int y, Filter * filter, const Bitmap & where ) const {
draw(x, y, filter, where, 0);
}
void TranslucentBitmap::drawHFlip( const int x, const int y, const Bitmap & where ) const {
draw(x, y, NULL, where, ALLEGRO_FLIP_HORIZONTAL);
}
void TranslucentBitmap::drawHFlip( const int x, const int y, Filter * filter, const Bitmap & where ) const {
draw(x, y, filter, where, ALLEGRO_FLIP_HORIZONTAL);
}
void TranslucentBitmap::drawVFlip( const int x, const int y, const Bitmap & where ) const {
draw(x, y, NULL, where, ALLEGRO_FLIP_VERTICAL);
}
void TranslucentBitmap::drawVFlip( const int x, const int y, Filter * filter, const Bitmap & where ) const {
draw(x, y, filter, where, ALLEGRO_FLIP_VERTICAL);
}
void TranslucentBitmap::drawHVFlip( const int x, const int y, const Bitmap & where ) const {
draw(x, y, NULL, where, ALLEGRO_FLIP_HORIZONTAL | ALLEGRO_FLIP_VERTICAL);
}
void TranslucentBitmap::drawHVFlip( const int x, const int y, Filter * filter,const Bitmap & where ) const {
draw(x, y, filter, where, ALLEGRO_FLIP_HORIZONTAL | ALLEGRO_FLIP_VERTICAL);
}
void TranslucentBitmap::hLine( const int x1, const int y, const int x2, const Color color ) const {
TransBlender blender;
Bitmap::hLine(x1, y, x2, doTransBlend(color, globalBlend.alpha));
}
void TranslucentBitmap::circleFill(int x, int y, int radius, Color color) const {
TransBlender blender;
Bitmap::circleFill(x, y, radius, doTransBlend(color, globalBlend.alpha));
}
void TranslucentBitmap::putPixelNormal(int x, int y, Color color) const {
TransBlender blender;
Bitmap::putPixelNormal(x, y, doTransBlend(color, globalBlend.alpha));
}
void TranslucentBitmap::rectangle( int x1, int y1, int x2, int y2, Color color ) const {
TransBlender blender;
Bitmap::rectangle(x1, y1, x2, y2, doTransBlend(color, globalBlend.alpha));
}
void TranslucentBitmap::rectangleFill(int x1, int y1, int x2, int y2, Color color) const {
TransBlender blender;
Bitmap::rectangleFill(x1, y1, x2, y2, doTransBlend(color, globalBlend.alpha));
}
void TranslucentBitmap::ellipse( int x, int y, int rx, int ry, Color color ) const {
TransBlender blender;
Bitmap::ellipse(x, y, rx, ry, doTransBlend(color, globalBlend.alpha));
}
void TranslucentBitmap::ellipseFill( int x, int y, int rx, int ry, Color color ) const {
TransBlender blender;
Bitmap::ellipseFill(x, y, rx, ry, doTransBlend(color, globalBlend.alpha));
}
void Bitmap::setClipRect( int x1, int y1, int x2, int y2 ) const {
/* TODO */
}
void Bitmap::getClipRect(int & x1, int & y1, int & x2, int & y2) const {
/* TODO */
}
int setGfxModeFullscreen(int x, int y){
return setGraphicsMode(FULLSCREEN, x, y);
}
int setGfxModeWindowed( int x, int y ){
return setGraphicsMode(WINDOWED, x, y);
}
int setGfxModeText(){
/* TODO */
return 0;
}
bool Bitmap::getError(){
/* TODO */
return false;
}
void Bitmap::alphaBlender(int source, int dest){
/* TODO */
}
void Bitmap::transBlender(int r, int g, int b, int a){
globalBlend.red = r;
globalBlend.green = g;
globalBlend.blue = b;
globalBlend.alpha = a;
globalBlend.type = Translucent;
}
void Bitmap::addBlender(int r, int g, int b, int a){
globalBlend.red = r;
globalBlend.green = g;
globalBlend.blue = b;
globalBlend.alpha = a;
globalBlend.type = Add;
}
void Bitmap::differenceBlender( int r, int g, int b, int a ){
globalBlend.red = r;
globalBlend.green = g;
globalBlend.blue = b;
globalBlend.alpha = a;
globalBlend.type = Difference;
}
void Bitmap::multiplyBlender( int r, int g, int b, int a ){
globalBlend.red = r;
globalBlend.green = g;
globalBlend.blue = b;
globalBlend.alpha = a;
globalBlend.type = Multiply;
}
/*
void Bitmap::drawingMode(int type){
}
*/
void Bitmap::shutdown(){
/* Make sure the display is set */
if (Screen != NULL){
al_set_target_bitmap(Screen->getData()->getBitmap());
}
al_use_shader(NULL);
for (std::vector<ALLEGRO_SHADER*>::iterator it = shaders.begin(); it != shaders.end(); it++){
ALLEGRO_SHADER * shader = *it;
al_destroy_shader(shader);
}
delete Screen;
Screen = NULL;
al_destroy_display(the_display);
the_display = NULL;
/*
delete Scaler;
Scaler = NULL;
delete Buffer;
Buffer = NULL;
*/
}
StretchedBitmap::StretchedBitmap(int width, int height, const Bitmap & parent, Clear clear, QualityFilter filter):
Bitmap(parent, 0, 0, parent.getWidth(), parent.getHeight()),
width(width),
height(height),
where(parent),
filter(filter),
clearKind(clear){
scale_x = (double) parent.getWidth() / width;
scale_y = (double) parent.getHeight() / height;
ALLEGRO_BITMAP * old_target = al_get_target_bitmap();
if (al_get_target_bitmap() != parent.getData()->getBitmap()){
al_set_target_bitmap(parent.getData()->getBitmap());
}
ALLEGRO_TRANSFORM transform;
al_identity_transform(&transform);
if (al_get_current_transform() != NULL){
al_copy_transform(&transform, al_get_current_transform());
}
al_scale_transform(&transform, scale_x, scale_y);
if (al_get_target_bitmap() != getData()->getBitmap()){
al_set_target_bitmap(getData()->getBitmap());
}
al_use_transform(&transform);
if (old_target != al_get_target_bitmap()){
al_set_target_bitmap(old_target);
}
switch (clear){
case NoClear: break;
case FullClear: this->clear();
case Mask: break;
}
/* TODO: handle filter */
}
void StretchedBitmap::start(){
#if 0
ALLEGRO_TRANSFORM transform;
changeTarget(this, this);
al_copy_transform(&transform, al_get_current_transform());
// al_identity_transform(&transform);
// al_scale_transform(&transform, Bitmap::getWidth() / width, Bitmap::getHeight() / height);
al_scale_transform(&transform, scale_x, scale_y);
al_use_transform(&transform);
#endif
}
void StretchedBitmap::finish(){
#if 0
ALLEGRO_TRANSFORM transform;
changeTarget(this, this);
al_copy_transform(&transform, al_get_current_transform());
/* apply the inverse transform */
al_scale_transform(&transform, 1.0/scale_x, 1.0/scale_y);
// al_identity_transform(&transform);
al_use_transform(&transform);
#endif
}
SubTranslucentBitmap::SubTranslucentBitmap(const Bitmap & where, int x, int y, int width, int height, Clear clear):
Bitmap(where, x, y, width, height),
translucent(*this),
clearKind(clear){
switch (clear){
case NoClear: break;
case FullClear: translucent.clear();
case Mask: break;
}
}
void SubTranslucentBitmap::finish(){
}
void SubTranslucentBitmap::start(){
}
void SubTranslucentBitmap::roundRect(int radius, int x1, int y1, int x2, int y2, Color color) const {
translucent.roundRect(radius, x1, y1, x2, y2, color);
}
void SubTranslucentBitmap::roundRectFill(int radius, int x1, int y1, int x2, int y2, Graphics::Color color) const {
translucent.roundRectFill(radius, x1, y1, x2, y2, color);
}
TranslatedBitmap::TranslatedBitmap(int x, int y, const Bitmap & where):
Bitmap(where),
x(x),
y(y){
ALLEGRO_TRANSFORM transform;
changeTarget(this, where);
al_identity_transform(&transform);
if (al_get_current_transform() != NULL){
al_copy_transform(&transform, al_get_current_transform());
}
al_translate_transform(&transform, x, y);
al_use_transform(&transform);
}
void TranslatedBitmap::BlitToScreen() const {
Bitmap::BlitToScreen();
}
TranslatedBitmap::~TranslatedBitmap(){
ALLEGRO_TRANSFORM transform;
al_copy_transform(&transform, al_get_current_transform());
al_translate_transform(&transform, -x, -y);
al_use_transform(&transform);
}
Bitmap * getScreenBuffer(){
return Screen;
}
RestoreState::RestoreState(){
al_store_state(&state, ALLEGRO_STATE_ALL);
}
RestoreState::~RestoreState(){
al_restore_state(&state);
}
Shader::Shader():
shader(NULL){
}
Shader::~Shader(){
if (shader != NULL){
al_destroy_shader(shader);
}
}
Shader::Shader(ALLEGRO_SHADER * shader):
shader(shader){
}
ALLEGRO_SHADER * Shader::getShader(){
return shader;
}
}
static inline bool close(float x, float y){
static float epsilon = 0.001;
return fabs(x - y) < epsilon;
}
static inline bool sameColor(const ALLEGRO_COLOR & color1, const ALLEGRO_COLOR & color2){
// return memcmp(&color1, &color2, sizeof(Graphics::Color)) == 0;
float r1, g1, b1, a1;
float r2, g2, b2, a2;
al_unmap_rgba_f(color1, &r1, &g1, &b1, &a1);
al_unmap_rgba_f(color2, &r2, &g2, &b2, &a2);
return close(r1, r2) &&
close(g1, g2) &&
close(b1, b2) &&
close(a1, a2);
/*
unsigned char r1, g1, b1, a1;
unsigned char r2, g2, b2, a2;
al_unmap_rgba(color1, &r1, &g1, &b1, &a1);
al_unmap_rgba(color2, &r2, &g2, &b2, &a2);
return r1 == r2 &&
g1 == g2 &&
b1 == b2 &&
a1 == a2;
*/
}
static uint32_t quantify(const ALLEGRO_COLOR & color){
unsigned char red, green, blue, alpha;
al_unmap_rgba(color, &red, &green, &blue, &alpha);
return (red << 24) |
(green << 16) |
(blue << 8) |
alpha;
}
bool operator<(const ALLEGRO_COLOR & color1, const ALLEGRO_COLOR & color2){
return quantify(color1) < quantify(color2);
}
bool operator!=(const ALLEGRO_COLOR & color1, const ALLEGRO_COLOR & color2){
return !(color1 == color2);
}
bool operator==(const ALLEGRO_COLOR & color1, const ALLEGRO_COLOR & color2){
return sameColor(color1, color2);
}
diff --git a/src/graphics/bitmap.cpp b/src/graphics/bitmap.cpp
index 8b79ec17..5ac2c45d 100644
--- a/src/graphics/bitmap.cpp
+++ b/src/graphics/bitmap.cpp
@@ -1,593 +1,593 @@
-#include "../funcs.h"
-#include "bitmap.h"
-#include "../file-system.h"
+#include "r-tech1/funcs.h"
+#include "r-tech1/graphics/bitmap.h"
+#include "r-tech1/file-system.h"
#include <string>
#include <stdio.h>
#include <math.h>
namespace Graphics{
static Bitmap * Screen = NULL;
/* bitmaps that should always be resized to the dimensions of the screen */
static std::vector<Bitmap*> needResize;
Util::Parameter<Bitmap*> screenParameter;
Util::Parameter<Util::ReferenceCount<ShaderManager> > shaderManager;
ShaderManager::ShaderManager(){
}
ShaderManager::~ShaderManager(){
}
Util::ReferenceCount<Shader> ShaderManager::getShader(const std::string & name, Util::ReferenceCount<Shader> (*create)()){
std::map<std::string, Util::ReferenceCount<Shader> >::iterator it = shaders.find(name);
if (it == shaders.end()){
shaders[name] = create();
it = shaders.find(name);
}
return it->second;
}
/* implementation independant definitions can go here */
Bitmap * Bitmap::temporary_bitmap = NULL;
Bitmap * Bitmap::temporary_bitmap2 = NULL;
/*
int SCALE_X = 0;
int SCALE_Y = 0;
*/
/*
const int Bitmap::MODE_TRANS = 0;
const int Bitmap::MODE_SOLID = 1;
*/
-
+
const int SPRITE_NO_FLIP = 0;
const int SPRITE_V_FLIP = 1;
const int SPRITE_H_FLIP = 2;
-
+
const int SPRITE_NORMAL = 1;
const int SPRITE_LIT = 2;
const int SPRITE_TRANS = 3;
static inline int max(int a, int b){
return a > b ? a : b;
}
INTERNAL_COLOR Color::defaultColor(){
return makeColor(0, 0, 0).color;
}
-
+
void initializeExtraStuff();
Bitmap::Bitmap(Storage::File & file):
mustResize(false),
error(false),
bit8MaskColor(makeColor(0, 0, 0)){
int length = file.getSize();
if (length == -1){
throw BitmapException(__FILE__, __LINE__, std::string("Could not read from file"));
}
char * data = new char[length];
try{
file.readLine(data, length);
loadFromMemory(data, length);
delete[] data;
} catch (const BitmapException & fail){
delete[] data;
throw;
} catch (...){
delete[] data;
throw;
}
}
QualityFilter qualityFilterName(const std::string & type){
if (type == "xbr"){
return XbrFilter;
}
if (type == "hqx"){
return HqxFilter;
}
return NoFilter;
}
Bitmap::~Bitmap(){
if (mustResize){
for (std::vector<Bitmap*>::iterator it = needResize.begin(); it != needResize.end(); it++){
Bitmap * who = *it;
if (who == this){
needResize.erase(it);
break;
}
}
}
}
static Bitmap makeTemporaryBitmap(Bitmap *& temporary, int w, int h){
if (temporary == NULL){
temporary = new Bitmap(w, h);
} else if (temporary->getWidth() < w || temporary->getHeight() < h){
int mw = max(temporary->getWidth(), w);
int mh = max(temporary->getHeight(), h);
// printf("Create temporary bitmap %d %d\n", mw, mh);
delete temporary;
temporary = new Bitmap(mw, mh);
}
if (temporary == NULL){
printf("*bug* temporary bitmap is null\n");
}
return Bitmap(*temporary, 0, 0, w, h);
}
/*
Bitmap Bitmap::temporaryBitmap(int w, int h){
return makeTemporaryBitmap(temporary_bitmap, w, h);
}
Bitmap Bitmap::temporaryBitmap2(int w, int h){
return makeTemporaryBitmap(temporary_bitmap2, w, h);
}
*/
void Bitmap::cleanupTemporaryBitmaps(){
if (temporary_bitmap != NULL){
delete temporary_bitmap;
temporary_bitmap = NULL;
}
if (temporary_bitmap2 != NULL){
delete temporary_bitmap2;
temporary_bitmap2 = NULL;
}
}
Bitmap & Bitmap::operator=(const Bitmap & copy){
path = copy.getPath();
this->width = copy.getWidth();
this->height = copy.getHeight();
setData(copy.getData());
return *this;
}
double Bitmap::getScale(){
/* the game is pretty much hard coded to run at 320 scaled upto 640
* and then scaled to whatever the user wants, but as long as
* 320 and 640 remain this number will be 2.
* maybe calculate this at some point
*/
return 2;
/*
if (Scaler != NULL && Buffer != NULL){
double x1 = Scaler->getWidth();
double x2 = Buffer->getWidth();
return x2 / x1;
}
return 1;
*/
}
bool Bitmap::isEmpty() const {
return getWidth() == 0 || getHeight() == 0;
}
/* taken from the color addon from allegro 4.9 */
static void al_color_cmyk_to_rgb(float cyan, float magenta, float yellow, float key, float *red, float *green, float *blue){
float max = 1 - key;
*red = max - cyan * max;
*green = max - magenta * max;
*blue = max - yellow * max;
}
void Bitmap::cymkToRGB(int c, int y, int m, int k, int * r, int * g, int * b){
float fc = (float)c / 255.0;
float fy = (float)y / 255.0;
float fm = (float)m / 255.0;
float fk = (float)k / 255.0;
float fr, fg, fb;
al_color_cmyk_to_rgb(fc, fm, fy, fk, &fr, &fg, &fb);
*r = (int)(fr * 255.0);
*g = (int)(fg * 255.0);
*b = (int)(fb * 255.0);
}
void Bitmap::updateOnResize(){
if (!mustResize){
mustResize = true;
needResize.push_back(this);
}
}
void Bitmap::updateSize(const int width, const int height){
if (getWidth() == width && getHeight() == height){
return;
}
Bitmap created(width, height);
*this = created;
}
/* resize the internal bitmap. not guaranteed to destroy the internal bitmap */
void Bitmap::resize(const int width, const int height){
/* if internal bitmap is already the proper size, do nothing */
if (getWidth() == width && getHeight() == height){
return;
}
Bitmap created(width, height);
Stretch(created);
*this = created;
}
/* decrement bitmap reference counter and free memory if counter hits 0 */
#if 0
void Bitmap::releaseInternalBitmap(){
const int MAGIC_DEBUG = 0xa5a5a5;
if (own != NULL){
if (*own == MAGIC_DEBUG){
printf("[bitmap] Trying to delete an already deleted reference counter %p\n", own);
}
(*own) -= 1;
if ( *own == 0 ){
*own = MAGIC_DEBUG;
delete own;
destroyPrivateData();
own = NULL;
}
}
}
#endif
void Bitmap::BlitToScreen() const {
// this->Blit( *Bitmap::Screen );
this->BlitToScreen(0, 0);
}
void Bitmap::load( const std::string & str ){
// releaseInternalBitmap();
internalLoadFile( str.c_str() );
}
Bitmap Bitmap::scaleBy(const double widthRatio, const double heightRatio) const {
return scaleTo(getWidth() * widthRatio, getHeight() * heightRatio);
}
void Bitmap::border( int min, int max, Color color ) const {
int w = getWidth();
int h = getHeight();
for (int i = min; i < max; i++){
rectangle(i, i, w - 1 - i, h - 1 - i, color);
}
}
void Bitmap::drawHFlip(const int x, const int y, const int startWidth, const int startHeight, const int width, const int height, const Bitmap & where) const {
drawHFlip(x, y, startWidth, startHeight, width, height, NULL, where);
}
void Bitmap::drawHFlip(const int x, const int y, const int startWidth, const int startHeight, const int width, const int height, Filter * filter, const Bitmap & where) const {
Bitmap sub(*this, getWidth() - width, getHeight() - height, getWidth() - startWidth, getHeight() - startHeight);
sub.drawHFlip(x + startWidth, y + startHeight, filter, where);
}
void Bitmap::drawRotateCenter(const int x, const int y, const int angle, const Bitmap & where){
drawRotate(x - getWidth() / 2, y - getHeight() / 2, angle, where);
}
void Bitmap::drawCenter(const int x, const int y, const Bitmap & where) const {
draw(x - getWidth() / 2, y - getHeight() / 2, where);
}
-
+
void Bitmap::drawStretched(const Bitmap & who) const {
drawStretched(0, 0, who.getWidth(), who.getHeight(), who);
}
void Bitmap::draw(const int x, const int y, const int startWidth, const int startHeight, const int width, const int height, const Bitmap & where) const {
draw(x, y, startWidth, startHeight, width, height, NULL, where);
/*
Bitmap sub(*this, startWidth, startHeight, width, height);
sub.draw(x + startWidth, y + startHeight, where);
*/
}
void Bitmap::draw(const int x, const int y, const int startWidth, const int startHeight, const int width, const int height, Filter * filter, const Bitmap & where) const {
Bitmap sub(*this, startWidth, startHeight, width, height);
sub.draw(x + startWidth, y + startHeight, filter, where);
}
void Bitmap::horizontalLine( const int x1, const int y, const int x2, const Graphics::Color color ) const{
this->hLine(x1, y, x2, color);
}
void Bitmap::equilateralTriangle(int x, int y, int angle, int size, Color color) const {
double radians = Util::radians(angle);
int x1 = x + size / 2 * cos(radians + 2 * Util::pi / 3);
int y1 = y + size / 2 * sin(radians + 2 * Util::pi / 3);
int x2 = x + size / 2 * cos(radians - 2 * Util::pi / 3);
int y2 = y + size / 2 * sin(radians - 2 * Util::pi / 3);
int x3 = x + size / 2 * cos(radians);
int y3 = y + size / 2 * sin(radians);
triangle(x1, y1, x2, y2, x3, y3, color);
}
Bitmap Bitmap::greyScale(){
Bitmap grey(getWidth(), getHeight());
for (int x = 0; x < getWidth(); x++){
for (int y = 0; y < getHeight(); y++){
- Color pixel = getPixel(x, y);
+ Color pixel = getPixel(x, y);
int val = (int)((0.299*getRed(pixel) + 0.587*getGreen(pixel) + 0.114*getBlue(pixel) + 0.5) + 16);
if (val > 255){
val = 255;
}
grey.putPixel(x, y, makeColor(val, val, val));
}
}
return grey;
}
bool Bitmap::inRange(int x, int y) const {
int x1 = 0, y1 = 0, x2 = 0, y2 = 0;
getClipRect(x1, y1, x2, y2);
return (x >= x1 && x <= x2 &&
y >= y1 && y <= y2);
}
void Bitmap::drawMask( const int _x, const int _y, const Bitmap & where ){
Color mask = MaskColor();
for (int x = 0; x < getWidth(); x++){
for (int y = 0; y < getHeight(); y++){
if (getPixel(x,y) == mask){
where.putPixel(x+_x, y+_y, mask);
}
}
}
}
void Bitmap::set8BitMaskColor(const Color & color){
bit8MaskColor = color;
}
Color Bitmap::get8BitMaskColor(){
return bit8MaskColor;
}
void Bitmap::setFakeGraphicsMode(int width, int height){
initializeExtraStuff();
Screen = new Bitmap(width, height);
}
void Bitmap::Blit( const std::string & xpath ) const {
Bitmap duh(xpath);
duh.Blit(*this);
}
void Bitmap::Blit(const Bitmap & where) const {
this->Blit(0, 0, where);
}
void Bitmap::Blit(const int x, const int y, const Bitmap & where) const {
Blit(0, 0, x, y, where);
}
void Bitmap::Blit(const int mx, const int my, const int wx, const int wy, const Bitmap & where) const {
Blit(mx, my, getWidth(), getHeight(), wx, wy, where);
}
void Bitmap::BlitFromScreen(const int x, const int y) const {
Screen->Blit(x, y, getWidth(), getHeight(), 0, 0, *this);
}
//! min (borrowed from allegro)
static inline int Min(int x, int y){ return (((x) < (y)) ? (x) : (y)); }
//! max (borrowed from allegro)
static inline int Max(int x, int y){ return (((x) > (y)) ? (x) : (y)); }
//! mid (borrowed from allegro)
static inline int Mid(int x,int y,int z){ return (Max((x), Min((y), (z)))); }
int Bitmap::getScreenWidth(){
if (Screen != 0){
return Screen->getWidth();
}
return 0;
}
int Bitmap::getScreenHeight(){
if (Screen != 0){
return Screen->getHeight();
}
return 0;
}
void Bitmap::clear() const {
fill(makeColor(0, 0, 0));
}
void Bitmap::copy(const Bitmap & him){
resize(him.getWidth(), him.getHeight());
him.Blit(*this);
}
void Bitmap::Stretch( const Bitmap & where ) const {
if (getWidth() == where.getWidth() && getHeight() == where.getHeight()){
Blit(where);
} else {
Stretch(where, 0, 0, getWidth(), getHeight(), 0, 0, where.getWidth(), where.getHeight());
}
}
void Bitmap::StretchHqx(const Bitmap & where) const {
if (getWidth() == where.getWidth() && getHeight() == where.getHeight()){
Blit(where);
} else {
StretchHqx(where, 0, 0, getWidth(), getHeight(), 0, 0, where.getWidth(), where.getHeight());
}
}
void Bitmap::StretchXbr(const Bitmap & where) const {
if (getWidth() == where.getWidth() && getHeight() == where.getHeight()){
Blit(where);
} else {
StretchXbr(where, 0, 0, getWidth(), getHeight(), 0, 0, where.getWidth(), where.getHeight());
}
}
Bitmap Bitmap::aspectRatio(int aspectWidth, int aspectHeight) const {
double width = getWidth();
double height = getHeight();
double ratio = (double) aspectWidth / (double) aspectHeight;
width = (double) height * ratio;
if (width > getWidth()){
width = getWidth();
height = width / ratio;
}
int x = (getWidth() - width) / 2;
int y = (getHeight() - height) / 2;
return Bitmap(*this, x, y, (int) width, (int) height);
}
Color darken(Color color, double factor ){
int r = (int)((double)getRed(color) / factor);
int g = (int)((double)getGreen(color) / factor);
int b = (int)((double)getBlue(color) / factor);
return makeColor(r, g, b);
}
LitBitmap::LitBitmap(const Bitmap & b):
Bitmap(b){
int x1, y1, x2, y2;
b.getClipRect(x1, y1, x2, y2);
setClipRect(x1, y1, x2, y2);
}
LitBitmap::LitBitmap():
Bitmap(){
}
-
+
LitBitmap::~LitBitmap(){
}
LitBitmap Bitmap::lit() const {
return LitBitmap(*this);
}
TranslucentBitmap Bitmap::translucent() const {
return TranslucentBitmap(*this);
}
TranslucentBitmap Bitmap::translucent(int red, int green, int blue, int alpha) const {
transBlender(red, green, blue, alpha);
return TranslucentBitmap(*this);
}
TranslucentBitmap::TranslucentBitmap(const Bitmap & b):
Bitmap(b){
int x1, y1, x2, y2;
b.getClipRect(x1, y1, x2, y2);
setClipRect(x1, y1, x2, y2);
}
TranslucentBitmap::TranslucentBitmap():
Bitmap(){
}
TranslucentBitmap::~TranslucentBitmap(){
}
void TranslucentBitmap::fill(Color color) const {
Bitmap::applyTrans(color);
}
int StretchedBitmap::getWidth() const {
return width;
}
int StretchedBitmap::getHeight() const {
return height;
}
double StretchedBitmap::getScaleWidth() const {
return (double) where.getWidth() / (double) getWidth();
}
double StretchedBitmap::getScaleHeight() const {
return (double) where.getHeight() / (double) getHeight();
}
BlendPoint::BlendPoint(const Color & color, int length):
color(color),
length(length){
}
void blend_palette(Color * pal, int mp, const Color & startColor, const Color & endColor){
/*
ASSERT(pal);
ASSERT(mp != 0);
*/
int sc_r = Graphics::getRed(startColor);
int sc_g = Graphics::getGreen(startColor);
int sc_b = Graphics::getBlue(startColor);
int ec_r = Graphics::getRed(endColor);
int ec_g = Graphics::getGreen(endColor);
int ec_b = Graphics::getBlue(endColor);
for ( int q = 0; q < mp; q++ ) {
float j = (float)( q + 1 ) / (float)( mp );
int f_r = (int)( 0.5 + (float)( sc_r ) + (float)( ec_r-sc_r ) * j );
int f_g = (int)( 0.5 + (float)( sc_g ) + (float)( ec_g-sc_g ) * j );
int f_b = (int)( 0.5 + (float)( sc_b ) + (float)( ec_b-sc_b ) * j );
pal[q] = Graphics::makeColor( f_r, f_g, f_b );
}
}
std::vector<Color> blend_palette(const std::vector<BlendPoint> & in){
std::vector<Color> out;
int here = 0;
for (int i = 1; i < in.size(); i++){
const BlendPoint & start = in[here];
const BlendPoint & end = in[i];
Color * save = new Color[start.length];
blend_palette(save, start.length, start.color, end.color);
for (int use = 0; use < start.length; use++){
out.push_back(save[use]);
}
delete[] save;
here = i;
}
return out;
}
}
#ifdef USE_ALLEGRO
#include "allegro/bitmap.cpp"
#endif
#ifdef USE_SDL
#include "sdl/bitmap.cpp"
#endif
#ifdef USE_ALLEGRO5
#include "allegro5/bitmap.cpp"
#endif
diff --git a/src/graphics/fire.cpp b/src/graphics/fire.cpp
index 371dd88d..15cbbf72 100644
--- a/src/graphics/fire.cpp
+++ b/src/graphics/fire.cpp
@@ -1,170 +1,170 @@
-#include "bitmap.h"
+#include "r-tech1/graphics/bitmap.h"
#include <vector>
-#include "fire.h"
+#include "r-tech1/graphics/fire.h"
#include <string.h>
-#include "util/funcs.h"
+#include "r-tech1/funcs.h"
#include <math.h>
namespace Paintown{
static int MAX_X = 320;
static int MAX_Y = 240;
Fire::Fire(){
Graphics::blend_palette(colors, 64, Graphics::makeColor(64, 0, 0), Graphics::makeColor(255, 0, 0));
Graphics::blend_palette(colors + 64, 64, Graphics::makeColor(255, 0, 0), Graphics::makeColor(255, 255, 0));
Graphics::blend_palette(colors + 64 + 64, 96, Graphics::makeColor(255, 255, 0), Graphics::makeColor(255, 255, 255));
Graphics::blend_palette(colors + 64 + 64 + 64 + 32, 32, Graphics::makeColor(255, 255, 255), Graphics::makeColor(255, 255, 255));
data = new unsigned char*[MAX_Y];
for (int i = 0; i < MAX_Y; i++){
data[i] = new unsigned char[MAX_X];
memset(data[i], 0, MAX_X);
}
for (int i = 0; i < MAX_HOTSPOTS; i++){
hotspots[i] = Util::rnd(MAX_X);
directions[i] = 0;
}
for (int i = 0; i < MAX_WISPS; i++){
Wisp & wisp = wisps[i];
wisp.y = MAX_Y-1 + Util::rnd(MAX_Y);
wisp.x = Util::rnd(MAX_X);
wisp.life = MAX_Y;
wisp.angle = Util::rnd(360);
}
}
void Fire::updateHotspots(){
for (int i = 0; i < MAX_HOTSPOTS; i++){
// hotspots[i] = (hotspots[i] + Util::rnd(5) - 2) % MAX_X;
hotspots[i] += directions[i];
if (hotspots[i] >= MAX_X){
hotspots[i] -= MAX_X;
}
if (hotspots[i] < 0){
hotspots[i] += MAX_X;
}
directions[i] += (double) (Util::rnd(7) - 3) / 5.0;
if (directions[i] < -4){
directions[i] = -4;
}
if (directions[i] > 4){
directions[i] = 4;
}
}
int hotspot_length = 40;
for (int i = 0; i < MAX_HOTSPOTS; i++){
for (int x = -hotspot_length/2; x < hotspot_length/2; x++){
int position = ((int) hotspots[i] + x + MAX_X) % MAX_X;
int more = (int) (data[MAX_Y-1][position] + (hotspot_length / 2 - fabs((double) x)));
if (more >= MAX_COLORS){
more = MAX_COLORS - 1;
}
data[MAX_Y-1][position] = more;
}
}
}
void Fire::updateWisps(){
for (int i = 0; i < MAX_WISPS; i++){
Wisp & wisp = wisps[i];
wisp.y -= 2;
wisp.life -= 1;
wisp.angle = (wisp.angle + 1) % 360;
if (wisp.life < 0){
wisp.y = MAX_Y-1 + Util::rnd(MAX_Y);
wisp.life = MAX_Y;
}
int my = (int) wisp.y;
int mx = (int)(wisp.x + sin(Util::radians(wisp.angle)) * 10);
if (mx < 0){
mx += MAX_X;
}
if (mx >= MAX_X){
mx -= MAX_X;
}
if (my > 0 && my < MAX_Y){
int z = data[my][mx] + wisp.life * 2;
if (z >= MAX_COLORS){
z = MAX_COLORS - 1;
}
// z = MAX_COLORS - 1;
// std::cout << "Update flicker at " << mx << ", " << my << " to " << z << std::endl;
data[my][mx] = z;
}
}
}
void Fire::update(){
updateHotspots();
// updateWisps();
int decay = 1;
// for (int y = MAX_Y-1; y > 0; y--){
for (int y = 0; y < MAX_Y; y++){
for (int x = 0; x < MAX_X; x++){
if (y < MAX_Y-1){
int lx = x-1;
if (lx < 0){
lx += MAX_X;
}
int rx = x+1;
if (rx >= MAX_X){
rx -= MAX_X;
}
// int less = (int)((double) data[y+1][x] * 0.6 + (double) data[y+1][lx] * 0.3 + (double) data[y+1][rx] * 0.3);
unsigned char * down = data[y+1];
/* dont change these numbers (0.2, 0.62, 9) because they affect
* the height of the flames. if the value of fire does not go down
* monotonically then the entire screen will be filled with flames.
*/
int less = (int)((double) down[lx] * 0.19);
less += (int)((double) down[rx] * 0.19);
less += (int)((double) down[x] * (0.4 + Util::rnd(25) / 100.0));
less += (int)((double) data[y][x] * 0.10);
// less -= Util::rnd(15);
if (less < 0){
less = 0;
}
if (less >= MAX_COLORS){
less = MAX_COLORS - 1;
}
data[y][x] = (unsigned char) less;
} else {
int less = (int)((double) data[y][x] * 0.95);
if (less < 0){
less = 0;
}
data[y][x] = (unsigned char) less;
}
}
}
}
void Fire::draw(const Graphics::Bitmap & work){
// Bitmap::drawingMode(Bitmap::MODE_TRANS);
for (int y = 0; y < MAX_Y; y++){
for (int x = 0; x < MAX_X; x++){
// work.putPixel(x, y, colors[data[y][x]]);
if (data[y][x] > 0){
work.rectangleFill(x*2, y*2, x*2+1, y*2+1, colors[data[y][x]]);
}
}
}
// Bitmap::drawingMode(Bitmap::MODE_SOLID);
}
Fire::~Fire(){
for (int y = 0; y < MAX_Y; y++){
delete[] data[y];
}
delete[] data;
}
}
diff --git a/src/graphics/gradient.cpp b/src/graphics/gradient.cpp
index c69e2baf..49f16555 100644
--- a/src/graphics/gradient.cpp
+++ b/src/graphics/gradient.cpp
@@ -1,111 +1,111 @@
-#include "gradient.h"
-#include "../funcs.h"
-#include "../token.h"
+#include "r-tech1/graphics/gradient.h"
+#include "r-tech1/funcs.h"
+#include "r-tech1/token.h"
namespace Effects{
Gradient::Gradient():
colors(NULL),
size(1),
index(0){
colors = new Graphics::Color[size];
colors[0] = Graphics::makeColor(255, 255, 255);
}
Gradient::Gradient(Graphics::Color singleColor):
colors(NULL),
size(1),
index(0){
colors = new Graphics::Color[size];
colors[0] = singleColor;
}
/* this class does virtually no error checking. great job */
Gradient::Gradient(int size, Graphics::Color startColor, Graphics::Color endColor):
colors(0),
size(size),
index(0){
size = Util::clamp(size, 2, 10000);
colors = new Graphics::Color[size];
Graphics::blend_palette(colors, size / 2, startColor, endColor);
Graphics::blend_palette(colors + size / 2, size / 2, endColor, startColor);
}
Gradient::Gradient(const Token * token):
colors(NULL),
size(10),
index(0){
int lowRed = 0, lowGreen = 0, lowBlue = 0;
int highRed = 255, highGreen = 255, highBlue = 255;
token->match("_/low", lowRed, lowGreen, lowBlue);
token->match("_/high", highRed, highGreen, highBlue);
token->match("_/distance", size);
token->match("_/size", size);
size = Util::clamp(size, 2, 10000);
Graphics::Color startColor = Graphics::makeColor(lowRed, lowGreen, lowBlue);
Graphics::Color endColor = Graphics::makeColor(highRed, highGreen, highBlue);
colors = new Graphics::Color[size];
Graphics::blend_palette(colors, size / 2, startColor, endColor);
Graphics::blend_palette(colors + size / 2, size / 2, endColor, startColor);
}
Gradient::Gradient(const Gradient & copy):
colors(NULL),
size(copy.size),
index(copy.index){
colors = new Graphics::Color[size];
for (unsigned int i = 0; i < size; i++){
colors[i] = copy.colors[i];
}
}
Gradient & Gradient::operator=(const Gradient & copy){
delete[] colors;
size = copy.size;
index = copy.index;
colors = new Graphics::Color[size];
for (unsigned int i = 0; i < size; i++){
colors[i] = copy.colors[i];
}
return *this;
}
void Gradient::forward(){
index = (index + 1) % size;
}
void Gradient::backward(){
/* This goofy logic is used because index is an unsigned int and its a bad idea
* to subtract 1 from an unsigned int whose value is 0.
*/
if (index == 0){
index = size - 1;
} else {
index -= 1;
}
}
void Gradient::update(){
forward();
}
void Gradient::reset(){
index = 0;
}
Graphics::Color Gradient::current() const {
return colors[index];
}
Graphics::Color Gradient::current(int offset) const {
return colors[(index + offset + size) % size];
}
Gradient::~Gradient(){
delete[] colors;
}
}
diff --git a/src/graphics/image.cpp b/src/graphics/image.cpp
index 409c054d..bba7af47 100644
--- a/src/graphics/image.cpp
+++ b/src/graphics/image.cpp
@@ -1,156 +1,156 @@
-#include "bitmap.h"
+#include "r-tech1/graphics/bitmap.h"
#include <string.h>
namespace Graphics{
static bool isPng(const unsigned char * data, int length){
return length > 3 &&
data[0] == 0x89 &&
data[1] == 'P' &&
data[2] == 'N' &&
data[3] == 'G';
}
static bool isBmp(const unsigned char * data, int length){
return length > 2 &&
data[0] == 'B' &&
data[1] == 'M';
}
static bool isJpg(const unsigned char * data, int length){
/* TODO */
return false;
#if 0
int start;
- int is_JPG;
- int in_scan;
- Uint8 magic[4];
+ int is_JPG;
+ int in_scan;
+ Uint8 magic[4];
- /* This detection code is by Steaphan Greene <stea@cs.binghamton.edu> */
- /* Blame me, not Sam, if this doesn't work right. */
- /* And don't forget to report the problem to the the sdl list too! */
+ /* This detection code is by Steaphan Greene <stea@cs.binghamton.edu> */
+ /* Blame me, not Sam, if this doesn't work right. */
+ /* And don't forget to report the problem to the the sdl list too! */
- if ( !src )
- return 0;
- start = SDL_RWtell(src);
- is_JPG = 0;
- in_scan = 0;
- if ( SDL_RWread(src, magic, 2, 1) ) {
- if ( (magic[0] == 0xFF) && (magic[1] == 0xD8) ) {
- is_JPG = 1;
- while (is_JPG == 1) {
- if(SDL_RWread(src, magic, 1, 2) != 2) {
- is_JPG = 0;
- } else if( (magic[0] != 0xFF) && (in_scan == 0) ) {
- is_JPG = 0;
- } else if( (magic[0] != 0xFF) || (magic[1] == 0xFF) ) {
- /* Extra padding in JPEG (legal) */
- /* or this is data and we are scanning */
- SDL_RWseek(src, -1, RW_SEEK_CUR);
- } else if(magic[1] == 0xD9) {
- /* Got to end of good JPEG */
- break;
- } else if( (in_scan == 1) && (magic[1] == 0x00) ) {
- /* This is an encoded 0xFF within the data */
- } else if( (magic[1] >= 0xD0) && (magic[1] < 0xD9) ) {
- /* These have nothing else */
- } else if(SDL_RWread(src, magic+2, 1, 2) != 2) {
- is_JPG = 0;
- } else {
- /* Yes, it's big-endian */
- Uint32 start;
- Uint32 size;
- Uint32 end;
- start = SDL_RWtell(src);
- size = (magic[2] << 8) + magic[3];
- end = SDL_RWseek(src, size-2, RW_SEEK_CUR);
- if ( end != start + size - 2 ) is_JPG = 0;
- if ( magic[1] == 0xDA ) {
- /* Now comes the actual JPEG meat */
-#ifdef FAST_IS_JPEG
- /* Ok, I'm convinced. It is a JPEG. */
- break;
+ if ( !src )
+ return 0;
+ start = SDL_RWtell(src);
+ is_JPG = 0;
+ in_scan = 0;
+ if ( SDL_RWread(src, magic, 2, 1) ) {
+ if ( (magic[0] == 0xFF) && (magic[1] == 0xD8) ) {
+ is_JPG = 1;
+ while (is_JPG == 1) {
+ if(SDL_RWread(src, magic, 1, 2) != 2) {
+ is_JPG = 0;
+ } else if( (magic[0] != 0xFF) && (in_scan == 0) ) {
+ is_JPG = 0;
+ } else if( (magic[0] != 0xFF) || (magic[1] == 0xFF) ) {
+ /* Extra padding in JPEG (legal) */
+ /* or this is data and we are scanning */
+ SDL_RWseek(src, -1, RW_SEEK_CUR);
+ } else if(magic[1] == 0xD9) {
+ /* Got to end of good JPEG */
+ break;
+ } else if( (in_scan == 1) && (magic[1] == 0x00) ) {
+ /* This is an encoded 0xFF within the data */
+ } else if( (magic[1] >= 0xD0) && (magic[1] < 0xD9) ) {
+ /* These have nothing else */
+ } else if(SDL_RWread(src, magic+2, 1, 2) != 2) {
+ is_JPG = 0;
+ } else {
+ /* Yes, it's big-endian */
+ Uint32 start;
+ Uint32 size;
+ Uint32 end;
+ start = SDL_RWtell(src);
+ size = (magic[2] << 8) + magic[3];
+ end = SDL_RWseek(src, size-2, RW_SEEK_CUR);
+ if ( end != start + size - 2 ) is_JPG = 0;
+ if ( magic[1] == 0xDA ) {
+ /* Now comes the actual JPEG meat */
+#ifdef FAST_IS_JPEG
+ /* Ok, I'm convinced. It is a JPEG. */
+ break;
#else
- /* I'm not convinced. Prove it! */
- in_scan = 1;
+ /* I'm not convinced. Prove it! */
+ in_scan = 1;
#endif
- }
- }
- }
- }
- }
- SDL_RWseek(src, start, RW_SEEK_SET);
- return(is_JPG);
+ }
+ }
+ }
+ }
+ }
+ SDL_RWseek(src, start, RW_SEEK_SET);
+ return(is_JPG);
#endif
}
static bool isPcx(const unsigned char * data, int length){
const int ZSoft_Manufacturer = 10;
const int PC_Paintbrush_Version = 5;
const int PCX_Uncompressed_Encoding = 0;
const int PCX_RunLength_Encoding = 1;
return length > 3 &&
data[0] == ZSoft_Manufacturer &&
data[1] == PC_Paintbrush_Version &&
(data[2] == PCX_RunLength_Encoding ||
data[2] == PCX_Uncompressed_Encoding);
}
static bool isTga(const unsigned char * data, int length){
/* No magic for tga files.. come up with some way to detect them */
return false;
}
static bool isTif(const unsigned char * data, int length){
return length > 4 &&
((data[0] == 'I' &&
data[1] == 'I' &&
data[2] == 0x2a &&
data[3] == 0x00) ||
(data[0] == 'M' &&
data[1] == 'M' &&
data[2] == 0x00 &&
data[3] == 0x2a));
}
static bool isXpm(const unsigned char * data, int length){
return strncmp((const char *) data, "/* XPM */", length) == 0;
}
static bool isGif(const unsigned char * data, int length){
return length > 7 &&
(strncmp((const char *) data, "GIF", 3) == 0) &&
(strncmp((const char *) data + 3, "87a", 3) == 0 ||
strncmp((const char *) data + 3, "89a", 3) == 0);
}
ImageFormat identifyImage(const unsigned char * data, int length){
if (isPng(data, length)){
return FormatPNG;
}
if (isBmp(data, length)){
return FormatBMP;
}
if (isJpg(data, length)){
return FormatJPG;
}
if (isPcx(data, length)){
return FormatPCX;
}
if (isTga(data, length)){
return FormatTGA;
}
if (isTif(data, length)){
return FormatTIF;
}
if (isXpm(data, length)){
return FormatXPM;
}
if (isGif(data, length)){
return FormatGIF;
}
return FormatUnknown;
}
}
diff --git a/src/gui/animation.cpp b/src/gui/animation.cpp
index 131aeeed..935dc630 100644
--- a/src/gui/animation.cpp
+++ b/src/gui/animation.cpp
@@ -1,1258 +1,1258 @@
-#include "animation.h"
+#include "r-tech1/gui/animation.h"
#include <stdio.h>
#include <vector>
#include <math.h>
#include <sstream>
-#include "util/token.h"
-#include "util/graphics/bitmap.h"
-#include "util/font.h"
-#include "util/graphics/gradient.h"
-#include "../debug.h"
-#include "../funcs.h"
-#include "../file-system.h"
-#include "../events.h"
-#include "util/exceptions/load_exception.h"
+#include "r-tech1/token.h"
+#include "r-tech1/graphics/bitmap.h"
+#include "r-tech1/font.h"
+#include "r-tech1/graphics/gradient.h"
+#include "r-tech1/debug.h"
+#include "r-tech1/funcs.h"
+#include "r-tech1/file-system.h"
+#include "r-tech1/events.h"
+#include "r-tech1/exceptions/load_exception.h"
using namespace std;
using namespace Gui;
// Temporary solution
static void renderSprite(const Graphics::Bitmap & bmp, const int x, const int y, const int alpha, const bool hflip, const bool vflip, const Graphics::Bitmap & work){
if (alpha != 255){
Graphics::Bitmap::transBlender( 0, 0, 0, alpha );
if (hflip && !vflip){
bmp.translucent().drawHFlip(x,y, work);
} else if (!hflip && vflip){
bmp.translucent().drawVFlip(x,y, work);
} else if (hflip && vflip){
bmp.translucent().drawHVFlip(x,y, work);
} else if (!hflip && !vflip){
bmp.translucent().draw(x,y, work);
}
} else {
if (hflip && !vflip){
bmp.drawHFlip(x,y, work);
} else if (!hflip && vflip){
bmp.drawVFlip(x,y, work);
} else if (hflip && vflip){
bmp.drawHVFlip(x,y, work);
} else if (!hflip && !vflip){
bmp.draw(x,y, work);
}
}
}
Element::Element(const Token * token):
time(50),
alpha(255){
if (token != NULL){
TokenView view = token->view();
while (view.hasMore()){
try{
const Token * tok;
view >> tok;
parseToken(tok);
} catch ( const TokenException & ex ) {
throw LoadException(__FILE__, __LINE__, ex, "Gui::Animation::Element parse error");
} catch ( const LoadException & ex ) {
throw ex;
}
}
}
}
Element::~Element(){
}
void Element::parseToken(const Token * token){
if (*token == "alpha"){
// get alpha
token->view() >> alpha;
} else if (*token == "offset"){
// Get the offset location it defaults to 0,0
double x=0, y=0;
try {
token->view() >> x >> y;
} catch (const TokenException & ex){
}
offset.set(x,y);
} else if (*token == "time"){
// time to display
token->view() >> time;
} else {
Global::debug( 3 ) << "Unhandled Gui::Animation::Element attribute: " << endl;
if (Global::getDebug() >= 3){
token->print(" ");
}
}
}
void Element::act(double xvel, double yvel){
scrollOffset.moveBy(xvel, yvel);
}
ImageFrame::ImageFrame(const Token *the_token, ImageMap &images, const string & baseDir):
Element(the_token),
bmp(NULL),
horizontalFlip(false),
verticalFlip(false){
/*
if (*the_token != "frame"){
throw LoadException(__FILE__, __LINE__, "Not an frame");
}
*/
/* The usual setup of an animation frame is
// use image -1 to not draw anything, it can be used to get a blinking effect
(frame (image NUM) (alpha NUM) (offset x y) (hflip 0|1) (vflip 0|1) (time NUM))
*/
TokenView view = the_token->view();
while (view.hasMore()){
try{
const Token * token;
view >> token;
parseToken(token, baseDir, images);
} catch ( const TokenException & ex ) {
throw LoadException(__FILE__, __LINE__, ex, "Menu animation parse error");
} catch ( const LoadException & ex ) {
throw ex;
}
}
}
void ImageFrame::parseToken(const Token * token, const string & baseDir, ImageMap & images){
if (*token == "image"){
// get the number
string maybeNumber;
token->view() >> maybeNumber;
if (Util::matchRegex(maybeNumber, Util::Regex("\\d+"))){
int num;
token->view() >> num;
if (images.find(num) == images.end()){
ostringstream out;
out << "No image for index " << num;
throw LoadException(__FILE__, __LINE__, out.str());
}
// now assign the bitmap
bmp = images[num];
} else {
bmp = Util::ReferenceCount<Graphics::Bitmap>(new Graphics::Bitmap(Storage::instance().find(Filesystem::RelativePath(baseDir + "/" + maybeNumber)).path()));
}
} else if (*token == "hflip"){
// horizontal flip
token->view() >> horizontalFlip;
} else if (*token == "vflip"){
// horizontal flip
token->view() >> verticalFlip;
} else {
Global::debug( 3 ) << "Unhandled Gui::Animation::ImageFrame attribute: "<<endl;
if (Global::getDebug() >= 3){
token->print(" ");
}
}
}
ImageFrame::ImageFrame(Util::ReferenceCount<Graphics::Bitmap> bmp):
Element(NULL),
bmp(bmp),
horizontalFlip(false),
verticalFlip(false){
time = -1;
}
ImageFrame::~ImageFrame(){
}
static bool closeFloat(double a, double b){
const double epsilon = 0.001;
return fabs(a-b) < epsilon;
}
void ImageFrame::act(double xvel, double yvel){
scrollOffset.moveBy(xvel, yvel);
if (bmp != NULL){
if (scrollOffset.getDistanceFromCenterX() >= bmp->getWidth()){
scrollOffset.setX(0);
} else if (scrollOffset.getDistanceFromCenterX() <= -(bmp->getWidth())){
scrollOffset.setX(0);
}
if (scrollOffset.getDistanceFromCenterY() >= bmp->getHeight()){
scrollOffset.setY(0);
} else if (scrollOffset.getDistanceFromCenterY() <= -(bmp->getHeight())){
scrollOffset.setY(0);
}
}
}
void ImageFrame::draw(const int xaxis, const int yaxis, const Graphics::Bitmap & work){
if (!bmp){
return;
}
if (!closeFloat(scrollOffset.getDistanceFromCenterX(), 0) || !closeFloat(scrollOffset.getDistanceFromCenterY(), 0)){
// Lets do some scrolling
// Graphics::Bitmap temp = Graphics::Bitmap::temporaryBitmap(bmp->getWidth(), bmp->getHeight());
//AnimationPoint loc;
AbsolutePoint loc;
if (scrollOffset.getRelativeX() < 0){
loc.setX(scrollOffset.getDistanceFromCenterX() + bmp->getWidth());
} else if (scrollOffset.getRelativeX() > 0){
loc.setX(scrollOffset.getDistanceFromCenterX() - bmp->getWidth());
}
if (scrollOffset.getRelativeY() < 0){
loc.setY(scrollOffset.getDistanceFromCenterY() + bmp->getHeight());
} else if (scrollOffset.getRelativeY() > 0){
loc.setY(scrollOffset.getDistanceFromCenterY() - bmp->getHeight());
}
/*
bmp->Blit((int) scrollOffset.getDistanceFromCenterX(), (int) scrollOffset.getDistanceFromCenterY(), temp);
bmp->Blit((int) scrollOffset.getDistanceFromCenterX(), (int) loc.getY(), temp);
bmp->Blit((int) loc.getX(), (int) scrollOffset.getDistanceFromCenterY(), temp);
bmp->Blit((int) loc.getX(), (int) loc.getY(), temp);
renderSprite(temp, (int)(xaxis+offset.getDistanceFromCenterX()), (int)(yaxis+offset.getDistanceFromCenterY()), alpha, horizontalFlip, verticalFlip, work);
*/
double x = xaxis+offset.getDistanceFromCenterX();
double y = yaxis+offset.getDistanceFromCenterY();
renderSprite(*bmp,
(int)(x + scrollOffset.getDistanceFromCenterX()),
(int)(y + scrollOffset.getDistanceFromCenterY()),
alpha, horizontalFlip, verticalFlip, work);
renderSprite(*bmp,
(int)(x + loc.getX()),
(int)(y + scrollOffset.getDistanceFromCenterY()),
alpha, horizontalFlip, verticalFlip, work);
renderSprite(*bmp,
(int)(x + scrollOffset.getDistanceFromCenterX()),
(int)(y + loc.getY()),
alpha, horizontalFlip, verticalFlip, work);
renderSprite(*bmp,
(int)(x + loc.getX()),
(int)(y + loc.getY()),
alpha, horizontalFlip, verticalFlip, work);
} else {
renderSprite(*bmp, (int)(xaxis+offset.getDistanceFromCenterX()), (int)(yaxis+offset.getDistanceFromCenterY()), alpha, horizontalFlip, verticalFlip, work);
}
}
/* This is mainly called from select-list to draw the cells. I'm not sure
* of the utility of stretching the bitmap to fit the cell dimensions. Most
* likely the cell will contain an image and the image will be the same
* size as the cell.
*/
void ImageFrame::draw(const Graphics::Bitmap & work){
Graphics::Bitmap temp(bmp->getWidth(), bmp->getHeight());
temp.clearToMask();
renderSprite(*bmp, 0, 0, alpha, horizontalFlip, verticalFlip, temp);
temp.drawStretched(work);
/* FIXME: This should work, but it doesn't.. */
/*
Graphics::StretchedBitmap show(bmp->getWidth(), bmp->getHeight(), work);
show.start();
renderSprite(*bmp, 0, 0, alpha, horizontalFlip, verticalFlip, show);
show.finish();
*/
}
void ImageFrame::reset(){
scrollOffset = RelativePoint();
}
void ImageFrame::setToEnd(const RelativePoint & end){
scrollOffset = end;
}
static const char * FRAME_TEXT = "Offset: ( %f, %f)\nScroll Offset: ( %f, %f)\nTime: %d\nHorizontal Flip: %d\nVertical Flip: %d\nAlpha: %d\n\n";
const std::string ImageFrame::getInfo(){
char info[255];
sprintf(info, FRAME_TEXT, offset.getRelativeX(), offset.getRelativeY(), scrollOffset.getRelativeX(), scrollOffset.getRelativeY(), time, horizontalFlip, verticalFlip, alpha);
return std::string(info);
}
TextFrame::TextFrame(const Token *token):
Element(token),
fontWidth(20),
fontHeight(20){
TokenView view = token->view();
while (view.hasMore()){
try{
const Token * token;
view >> token;
parseToken(token);
} catch ( const TokenException & ex ) {
throw LoadException(__FILE__, __LINE__, ex, "Menu animation parse error");
} catch ( const LoadException & ex ) {
throw ex;
}
}
}
TextFrame::~TextFrame(){
}
void TextFrame::act(double xvel, double yvel){
gradient.forward();
Element::act(xvel, yvel);
}
static const Font & getFont(const string & font, int width, int height){
if (font != ""){
return Font::getFont(Filesystem::RelativePath(font), width, height);
}
return Font::getDefaultFont(width, height);
}
void TextFrame::draw(int xaxis, int yaxis, const Graphics::Bitmap & work){
double x = xaxis + offset.getDistanceFromCenterX() + scrollOffset.getDistanceFromCenterX();
double y = yaxis + offset.getDistanceFromCenterY() + scrollOffset.getDistanceFromCenterY();
const Font & font = getFont(this->font, fontWidth, fontHeight);
font.printf((int) x, (int) y, gradient.current(), work, "%s", 0, message.c_str());
}
void TextFrame::draw(const Graphics::Bitmap & work){
/* Probably don't need this.. but implement it if you do! */
}
void TextFrame::reset(){
scrollOffset = RelativePoint();
}
void TextFrame::setToEnd(const RelativePoint & point){
scrollOffset = point;
}
const std::string TextFrame::getInfo(){
return message;
}
void TextFrame::parseToken(const Token * token){
if (*token == "message"){
token->view() >> message;
} else if (*token == "font"){
TokenView view = token->view();
view >> font;
try{
view >> fontWidth >> fontHeight;
} catch (const TokenException & ignore){
}
if (fontWidth < 1){
fontWidth = 1;
}
if (fontHeight < 1){
fontHeight = 1;
}
} else if (*token == "color"){
int red, green, blue;
token->view() >> red >> green >> blue;
gradient = Effects::Gradient(Graphics::makeColor(red, green, blue));
} else if (*token == "gradient"){
gradient = Effects::Gradient(token);
}
}
Sequence::Sequence(){
}
Sequence::~Sequence(){
}
SequenceFrame::SequenceFrame(const Util::ReferenceCount<Element> & frame):
frame(frame),
ticks(0){
}
void SequenceFrame::draw(int xaxis, int yaxis, const Graphics::Bitmap & work) const {
frame->draw(xaxis, yaxis, work);
}
Util::ReferenceCount<Element> SequenceFrame::getCurrentFrame() const {
return frame;
}
int SequenceFrame::totalTicks() const {
return frame->getTime();
}
void SequenceFrame::setToEnd(){
ticks = frame->getTime();
}
bool SequenceFrame::forward(int tickCount, double velocityX, double velocityY){
frame->act(tickCount * velocityX, tickCount * velocityY);
ticks += tickCount;
return ticks > frame->getTime();
}
bool SequenceFrame::reverse(int tickCount, double velocityX, double velocityY){
frame->act(-tickCount * velocityX, -tickCount * velocityY);
ticks -= tickCount;
return ticks < 0;
}
void SequenceFrame::forwardFrame(){
/* nop */
}
void SequenceFrame::backFrame(){
/* nop */
}
void SequenceFrame::reset(){
ticks = 0;
frame->reset();
}
void SequenceFrame::resetTicks(){
ticks = 0;
}
SequenceLoop::SequenceLoop(int loops):
currentFrame(0),
currentLoop(loops),
loopTimes(loops){
}
Util::ReferenceCount<Element> SequenceLoop::getCurrentFrame() const {
if (currentFrame < frames.size()){
return frames[currentFrame]->getCurrentFrame();
} else {
/* Return the last frame */
if (frames.size() > 0){
return frames[frames.size() - 1]->getCurrentFrame();
}
}
return Util::ReferenceCount<Element>(NULL);
}
Util::ReferenceCount<Sequence> SequenceLoop::getCurrentSequence() const {
if (currentFrame < frames.size()){
return frames[currentFrame];
} else {
/* Return the last frame */
if (frames.size() > 0){
return frames[frames.size() - 1];
}
}
return Util::ReferenceCount<Sequence>(NULL);
}
void SequenceLoop::draw(int xaxis, int yaxis, const Graphics::Bitmap & work) const {
Util::ReferenceCount<Sequence> current = getCurrentSequence();
if (current != NULL){
current->draw(xaxis, yaxis, work);
}
}
void SequenceLoop::reset(){
currentFrame = 0;
currentLoop = loopTimes;
for (vector<Util::ReferenceCount<Sequence> >::iterator it = frames.begin(); it != frames.end(); it++){
Util::ReferenceCount<Sequence> & sequence = *it;
sequence->reset();
}
}
/* Does the same thing as reset except for calling resetTicks on children nodes */
void SequenceLoop::resetTicks(){
currentFrame = 0;
currentLoop = loopTimes;
for (vector<Util::ReferenceCount<Sequence> >::iterator it = frames.begin(); it != frames.end(); it++){
Util::ReferenceCount<Sequence> & sequence = *it;
sequence->resetTicks();
}
}
/* Similar to resetTicks but doesn't reset the current frame or loop */
void SequenceLoop::resetChildrenTicks(){
for (vector<Util::ReferenceCount<Sequence> >::iterator it = frames.begin(); it != frames.end(); it++){
Util::ReferenceCount<Sequence> & sequence = *it;
sequence->resetTicks();
}
}
void SequenceLoop::setToEnd(){
/* FIXME */
}
void SequenceLoop::addSequence(const Util::ReferenceCount<Sequence> & sequence){
frames.push_back(sequence);
}
static Util::ReferenceCount<Sequence> parseSequence(const Token * token, ImageMap & images, const string & baseDir){
if (*token == "frame"){
Util::ReferenceCount<Element> frame(new ImageFrame(token, images, baseDir));
return Util::ReferenceCount<Sequence>(new SequenceFrame(frame));
} else if (*token == "text"){
Util::ReferenceCount<Element> frame(new TextFrame(token));
return Util::ReferenceCount<Sequence>(new SequenceFrame(frame));
} else if (*token == "loop"){
int times;
token->view() >> times;
Util::ReferenceCount<SequenceLoop> loop(new SequenceLoop(times));
loop->parse(token, images, baseDir);
return loop;
} else if (*token == "all"){
return Util::ReferenceCount<Sequence>(new SequenceAll(token, images, baseDir));
} else if (*token == "random"){
return Util::ReferenceCount<Sequence>(new SequenceRandom(token, images, baseDir));
}
return Util::ReferenceCount<Sequence>(NULL);
}
void SequenceLoop::parse(const Token * token, ImageMap & images, const string & baseDir){
TokenView view = token->view();
/* first ignore the number of times to loop */
int ignore;
view >> ignore;
while (view.hasMore()){
const Token * next;
view >> next;
Util::ReferenceCount<Sequence> sequence = parseSequence(next, images, baseDir);
if (sequence != NULL){
addSequence(sequence);
}
}
}
int SequenceLoop::totalTicks() const {
int total = 0;
for (vector<Util::ReferenceCount<Sequence> >::const_iterator it = frames.begin(); it != frames.end(); it++){
const Util::ReferenceCount<Sequence> & sequence = *it;
total += sequence->totalTicks();
}
return total * (1 + loopTimes);
}
bool SequenceLoop::forward(int tickCount, double velocityX, double velocityY){
Util::ReferenceCount<Sequence> current = getCurrentSequence();
if (current != NULL){
if (current->forward(tickCount, velocityX, velocityY)){
forwardFrame();
}
}
return currentFrame == frames.size();
}
bool SequenceLoop::reverse(int tickCount, double velocityX, double velocityY){
Util::ReferenceCount<Sequence> current = getCurrentSequence();
if (current != NULL){
if (current->reverse(tickCount, velocityX, velocityY)){
backFrame();
}
}
return currentFrame == frames.size();
}
void SequenceLoop::forwardFrame(){
currentFrame += 1;
/* do the loop */
if (currentFrame == frames.size() && currentLoop > 0){
currentLoop -= 1;
currentFrame = 0;
resetChildrenTicks();
}
}
void SequenceLoop::backFrame(){
currentFrame -= 1;
/* do the loop */
if (currentFrame <= 0 && currentLoop > 0){
currentLoop -= 1;
resetChildrenTicks();
if (frames.size() > 0){
currentFrame = frames.size() - 1;
} else {
currentFrame = 0;
}
}
}
SequenceAll::SequenceAll(const Token * token, ImageMap & images, const string & baseDir){
TokenView view = token->view();
while (view.hasMore()){
const Token * next;
view >> next;
Util::ReferenceCount<Sequence> sequence = parseSequence(next, images, baseDir);
if (sequence != NULL){
addSequence(sequence);
}
}
}
Util::ReferenceCount<Element> SequenceAll::getCurrentFrame() const {
return Util::ReferenceCount<Element>(NULL);
}
void SequenceAll::reset(){
for (SequenceIterator it = sequences.begin(); it != sequences.end(); it++){
Util::ReferenceCount<Sequence> & next = *it;
next->reset();
}
}
void SequenceAll::resetTicks(){
for (SequenceIterator it = sequences.begin(); it != sequences.end(); it++){
Util::ReferenceCount<Sequence> & next = *it;
next->resetTicks();
}
}
void SequenceAll::setToEnd(){
for (SequenceIterator it = sequences.begin(); it != sequences.end(); it++){
Util::ReferenceCount<Sequence> & next = *it;
next->setToEnd();
}
}
void SequenceAll::addSequence(const Util::ReferenceCount<Sequence> & sequence){
sequences.push_back(sequence);
}
void SequenceAll::draw(int xaxis, int yaxis, const Graphics::Bitmap & work) const {
for (SequenceConstIterator it = sequences.begin(); it != sequences.end(); it++){
const Util::ReferenceCount<Sequence> & next = *it;
next->draw(xaxis, yaxis, work);
}
}
/* Maximum ticks of any sequence */
int SequenceAll::totalTicks() const {
int max = 0;
for (SequenceConstIterator it = sequences.begin(); it != sequences.end(); it++){
const Util::ReferenceCount<Sequence> & next = *it;
int what = next->totalTicks();
if (what > max){
max = what;
}
}
return max;
}
bool SequenceAll::forward(int tickCount, double velocityX, double velocityY){
bool go = false;
for (SequenceIterator it = sequences.begin(); it != sequences.end(); it++){
Util::ReferenceCount<Sequence> & next = *it;
go = next->forward(tickCount, velocityX, velocityY) && go;
}
return go;
}
bool SequenceAll::reverse(int tickCount, double velocityX, double velocityY){
bool go = false;
for (SequenceIterator it = sequences.begin(); it != sequences.end(); it++){
Util::ReferenceCount<Sequence> & next = *it;
go = next->reverse(tickCount, velocityX, velocityY) && go;
}
return go;
}
void SequenceAll::forwardFrame(){
for (SequenceIterator it = sequences.begin(); it != sequences.end(); it++){
Util::ReferenceCount<Sequence> & next = *it;
next->forwardFrame();
}
}
void SequenceAll::backFrame(){
for (SequenceIterator it = sequences.begin(); it != sequences.end(); it++){
Util::ReferenceCount<Sequence> & next = *it;
next->backFrame();
}
}
SequenceRandom::SequenceRandom(const Token * token, ImageMap & images, const std::string & baseDir):
current(0){
TokenView view = token->view();
while (view.hasMore()){
const Token * next;
view >> next;
Util::ReferenceCount<Sequence> sequence = parseSequence(next, images, baseDir);
if (sequence != NULL){
addSequence(sequence);
}
}
current = Util::rnd(sequences.size());
}
Util::ReferenceCount<Element> SequenceRandom::getCurrentFrame() const {
return Util::ReferenceCount<Element>(NULL);
}
void SequenceRandom::reset(){
current = Util::rnd(sequences.size());
for (SequenceIterator it = sequences.begin(); it != sequences.end(); it++){
Util::ReferenceCount<Sequence> & next = *it;
next->reset();
}
}
void SequenceRandom::resetTicks(){
current = Util::rnd(sequences.size());
for (SequenceIterator it = sequences.begin(); it != sequences.end(); it++){
Util::ReferenceCount<Sequence> & next = *it;
next->resetTicks();
}
}
void SequenceRandom::setToEnd(){
for (SequenceIterator it = sequences.begin(); it != sequences.end(); it++){
Util::ReferenceCount<Sequence> & next = *it;
next->setToEnd();
}
}
void SequenceRandom::addSequence(const Util::ReferenceCount<Sequence> & sequence){
sequences.push_back(sequence);
}
void SequenceRandom::draw(int xaxis, int yaxis, const Graphics::Bitmap & work) const {
if (current < sequences.size()){
Util::ReferenceCount<Sequence> now = sequences[current];
now->draw(xaxis, yaxis, work);
}
}
int SequenceRandom::totalTicks() const {
int max = 0;
for (SequenceConstIterator it = sequences.begin(); it != sequences.end(); it++){
const Util::ReferenceCount<Sequence> & next = *it;
int what = next->totalTicks();
if (what > max){
max = what;
}
}
return max;
}
bool SequenceRandom::forward(int tickCount, double velocityX, double velocityY){
if (current < sequences.size()){
Util::ReferenceCount<Sequence> now = sequences[current];
return now->forward(tickCount, velocityX, velocityY);
}
return true;
}
bool SequenceRandom::reverse(int tickCount, double velocityX, double velocityY){
if (current < sequences.size()){
Util::ReferenceCount<Sequence> now = sequences[current];
return now->reverse(tickCount, velocityX, velocityY);
}
return true;
}
void SequenceRandom::forwardFrame(){
if (current < sequences.size()){
sequences[current]->forwardFrame();
}
}
void SequenceRandom::backFrame(){
if (current < sequences.size()){
sequences[current]->backFrame();
}
}
static int CURRENT_ID = 0;
static int getNextId(){
return CURRENT_ID++;
}
Animation::Animation(const Token *the_token):
id(getNextId()),
depth(BackgroundBottom),
allowReset(true),
sequence(0){
/* Whats this for? */
images[-1] = 0;
std::string basedir = ".";
if ( *the_token != "anim" && *the_token != "animation" ){
throw LoadException(__FILE__, __LINE__, "Not an animation");
}
/* The usual setup of an animation is
- The images must be listed prior to listing any frames, basedir can be used to set the directory where the images are located
- loop will begin at the subsequent frame listed after loop
- axis is the location in which the drawing must be placed
- location *old* - used to render in background or foreground (0 == background [default]| 1 == foreground)
+ The images must be listed prior to listing any frames, basedir can be used to set the directory where the images are located
+ loop will begin at the subsequent frame listed after loop
+ axis is the location in which the drawing must be placed
+ location *old* - used to render in background or foreground (0 == background [default]| 1 == foreground)
depth - used to render in background or foreground space (depth background bottom|middle|top) | (depth foreground bottom|midle|top)
- reset - used to allow resetting of animation (0 == no | 1 == yes [default])
- velocity - used to get a wrapping scroll effect while animating
+ reset - used to allow resetting of animation (0 == no | 1 == yes [default])
+ velocity - used to get a wrapping scroll effect while animating
window - area in which the item will be contained
- (anim (id NUM)
- (location NUM)
+ (anim (id NUM)
+ (location NUM)
(scale NUM) ;; optional
(depth background|foreground NUM)
- (basedir LOCATION)
- (image NUM FILE [SCALE])
- (velocity x y)
- (axis x y)
- (frame "Read comments above in constructor")
- (loop 2)
- (reset NUM)
- (window x1 y1 x2 y2))
+ (basedir LOCATION)
+ (image NUM FILE [SCALE])
+ (velocity x y)
+ (axis x y)
+ (frame "Read comments above in constructor")
+ (loop 2)
+ (reset NUM)
+ (window x1 y1 x2 y2))
*/
double scale = 1.0;
bool scaleSet = false;
const Token & tok = *the_token;
TokenView view = tok.view();
while (view.hasMore()){
try{
const Token * token;
view >> token;
if (*token == "id"){
// get the id
token->view() >> id;
} else if (*token == "location"){
// translate location to depth
/*int location = 0;
token->view() >> location;
if (location == 0){
depth = BackgroundBottom;
} else if (location == 1){
depth = ForegroundBottom;
}*/
Global::debug(0) << "The option (" << token->getLineage() << ") in the file '" << token->getFileName() << "' is no longer valid and will be ignored. Consider using 'depth' instead." << std::endl;
} else if (*token == "scale"){
token->view() >> scale;
scaleSet = true;
} else if (*token == "depth"){
// get the depth
std::string name, level;
token->view() >> name >> level;
if (name == "background"){
if (level == "bottom"){
depth = BackgroundBottom;
} else if (level == "middle"){
depth = BackgroundMiddle;
} else if (level == "top"){
depth = BackgroundTop;
}
} else if (name == "foreground"){
if (level == "bottom"){
depth = ForegroundBottom;
} else if (level == "middle"){
depth = ForegroundMiddle;
} else if (level == "top"){
depth = ForegroundTop;
}
}
} else if (*token == "basedir"){
// set the base directory for loading images
token->view() >> basedir;
} else if (*token == "image"){
// add bitmaps by number to the map
int number;
std::string temp;
double localScale = 1;
bool localScaleSet = false;
TokenView view = token->view();
view >> number >> temp;
try{
view >> localScale;
localScaleSet = true;
} catch (const TokenException & fail){
}
Util::ReferenceCount<Graphics::Bitmap> bmp(new Graphics::Bitmap(*Storage::instance().open(Storage::instance().find(Filesystem::RelativePath(basedir + "/" + temp)))));
if (!bmp->getError()){
if (scaleSet || localScaleSet){
if (localScaleSet){
*bmp = bmp->scaleBy(localScale, localScale);
} else {
*bmp = bmp->scaleBy(scale, scale);
}
}
images[number] = bmp;
}
} else if (*token == "axis"){
// Get the axis location it defaults to 0,0
double x=0, y=0;
try {
token->view() >> x >> y;
} catch (const TokenException & ex){
}
axis.set(x,y);
} else if (*token == "window"){
// Windowed area where to clip if necessary otherwise it defaults to max
double x1=0,x2=0, y1=0,y2=0;
try {
token->view() >> x1 >> y1 >> x2 >> y2;
} catch (const TokenException & ex){
}
window.set(x1,y1,x2,y2);
} else if (*token == "velocity"){
// This allows the animation to get a wrapping scroll action going on
double x=0, y=0;
try {
token->view() >> x >> y;
} catch (const TokenException & ex){
}
velocity.set(x,y);
} else if (*token == "frame"){
Util::ReferenceCount<Element> frame(new ImageFrame(token, images, basedir));
sequence.addSequence(Util::ReferenceCount<Sequence>(new SequenceFrame(frame)));
} else if (*token == "text"){
Util::ReferenceCount<Element> frame(new TextFrame(token));
sequence.addSequence(Util::ReferenceCount<Sequence>(new SequenceFrame(frame)));
} else if (*token == "all"){
sequence.addSequence(Util::ReferenceCount<Sequence>(new SequenceAll(token, images, basedir)));
} else if (*token == "random"){
sequence.addSequence(Util::ReferenceCount<Sequence>(new SequenceRandom(token, images, basedir)));
} else if (*token == "loop"){
// start loop here
int times;
token->view() >> times;
Util::ReferenceCount<SequenceLoop> loop(new SequenceLoop(times));
loop->parse(token, images, basedir);
sequence.addSequence(loop);
/*
- if (l >= (int)frames.size()){
- ostringstream out;
- out << "Loop location is larger than the number of frames. Loop: " << loop << " Frames: " << frames.size();
- throw LoadException(__FILE__, __LINE__, out.str());
- }
+ if (l >= (int)frames.size()){
+ ostringstream out;
+ out << "Loop location is larger than the number of frames. Loop: " << loop << " Frames: " << frames.size();
+ throw LoadException(__FILE__, __LINE__, out.str());
+ }
*/
} else if (*token == "reset"){
// Allow reset of animation
token->view() >> allowReset;
} else {
Global::debug( 3 ) << "Unhandled menu attribute: "<<endl;
if (Global::getDebug() >= 3){
token->print(" ");
}
}
} catch ( const TokenException & ex ) {
throw LoadException(__FILE__, __LINE__, ex, "Menu animation parse error");
} catch ( const LoadException & ex ) {
throw ex;
}
}
}
Animation::Animation():
id(getNextId()),
depth(BackgroundBottom),
allowReset(false),
sequence(0){
}
Animation::Animation(const std::string & background):
id(getNextId()),
depth(BackgroundBottom),
allowReset(true),
sequence(0){
// add bitmap
Util::ReferenceCount<Graphics::Bitmap> bmp(new Graphics::Bitmap(*Storage::instance().open(Storage::instance().find(Filesystem::RelativePath(background)))));
if (bmp->getError()){
throw LoadException(__FILE__,__LINE__, "Problem loading file: " + background);
} else {
images[0] = bmp;
}
Util::ReferenceCount<Element> frame(new ImageFrame(bmp));
sequence.addSequence(Util::ReferenceCount<Sequence>(new SequenceFrame(frame)));
}
Animation::Animation(const Filesystem::AbsolutePath & path):
id(getNextId()),
depth(BackgroundBottom),
allowReset(true),
sequence(0){
// add bitmap
Util::ReferenceCount<Graphics::Bitmap> bmp(new Graphics::Bitmap(*Storage::instance().open(path)));
if (bmp->getError()){
throw LoadException(__FILE__,__LINE__, "Problem loading file: " + path.path());
} else {
images[0] = bmp;
}
Util::ReferenceCount<Element> frame(new ImageFrame(bmp));
sequence.addSequence(Util::ReferenceCount<Sequence>(new SequenceFrame(frame)));
}
Animation::Animation(Util::ReferenceCount<Graphics::Bitmap> image):
id(getNextId()),
depth(BackgroundBottom),
allowReset(true),
sequence(0){
images[0] = image;
Util::ReferenceCount<Element> frame(new ImageFrame(image));
sequence.addSequence(Util::ReferenceCount<Sequence>(new SequenceFrame(frame)));
}
Animation::~Animation(){
}
int Animation::totalTicks() const {
return sequence.totalTicks();
}
void Animation::forward(int tickCount){
sequence.forward(tickCount, velocity.getRelativeX(), velocity.getRelativeY());
}
void Animation::reverse(int tickCount){
sequence.reverse(tickCount, velocity.getRelativeX(), velocity.getRelativeY());
}
void Animation::act(){
forward();
}
void Animation::draw(const Graphics::Bitmap & work) const {
/* FIXME: should use sub-bitmaps here */
/*const int x = window.getX();
const int y = window.getY();
const int width = window.getWidth();
const int height = window.getHeight();
Global::debug(0) << "Distance x2: " << width << " Distance y2: " << height << std::endl;
Graphics::Bitmap clipped(work, x, y, height, width);
frames[currentFrame]->draw(0, 0,clipped);*/
// Set clip from the axis default is 0,0,bitmap width, bitmap height
work.setClipRect(-window.getPosition().getDistanceFromCenterX(),
-window.getPosition().getDistanceFromCenterY(),
work.getWidth() - window.getPosition2().getDistanceFromCenterX(),
work.getHeight() - window.getPosition2().getDistanceFromCenterY());
sequence.draw(axis.getDistanceFromCenterX(), axis.getDistanceFromCenterY(), work);
work.setClipRect(0, 0, work.getWidth(), work.getHeight());
}
void Animation::draw(int x, int y, int width, int height, const Graphics::Bitmap & work) const {
const Util::ReferenceCount<Element> & frame = sequence.getCurrentFrame();
if (frame != NULL){
Graphics::Bitmap clipped(work, x, y, width, height);
frame->draw(clipped);
}
}
void Animation::forwardFrame(){
sequence.forwardFrame();
}
void Animation::backFrame(){
sequence.backFrame();
}
void Animation::reset(){
sequence.reset();
}
void Animation::resetAll(){
sequence.reset();
}
void Animation::setToEnd(){
/* FIXME */
sequence.setToEnd();
// currentFrame = frames.size()-1;
// currentLoop = 0;
// Set offsets
/*
for (std::vector<Util::ReferenceCount<Element> >::iterator i = frames.begin(); i != frames.end(); ++i){
Util::ReferenceCount<Element> frame = *i;
frame->setToEnd(RelativePoint(ticks * velocity.getRelativeX(), ticks * velocity.getRelativeY()));
}
*/
}
DrawableAnimation::DrawableAnimation(const Util::ReferenceCount<Util::Draw> & drawer, Depth depth):
drawer(drawer){
this->depth = depth;
}
DrawableAnimation::DrawableAnimation(const Util::ReferenceCount<Util::Draw> & drawer):
drawer(drawer){
}
void DrawableAnimation::draw(const Graphics::Bitmap & work) const {
drawer->draw(work);
}
void DrawableAnimation::draw(int x, int y, int width, int height, const Graphics::Bitmap & work) const {
draw(Graphics::Bitmap(work, x, y, width, height));
}
const std::string Animation::getInfo(){
/*
static const char * ANIMATION_TEXT = "Animation ID: %d\nTicks: %d\nFrame Index: %d\nLoop From: %d\nAxis: ( %f, %f)\nVelocity: ( %f, %f)\n";
char info[255];
sprintf(info, ANIMATION_TEXT, id, ticks, currentFrame, loop, axis.getRelativeX(), axis.getRelativeY(), velocity.getRelativeX(), velocity.getRelativeY());
return std::string(info) + frames[currentFrame]->getInfo();
*/
/* FIXME */
ostringstream out;
out << "Animation ID: " << id;
return out.str();
}
AnimationManager::AnimationManager(){
// Set the current id to 0 for each context
CURRENT_ID = 0;
}
AnimationManager::AnimationManager(const AnimationManager & copy):
animations(copy.animations){
// Set the current id to 0 for each context
CURRENT_ID = 0;
}
AnimationManager::~AnimationManager(){
}
const AnimationManager & AnimationManager::operator=(const AnimationManager & copy){
animations = copy.animations;
return *this;
}
void AnimationManager::forward(int tickCount){
for (std::map<Gui::Animation::Depth, std::vector<Util::ReferenceCount<Gui::Animation> > >::iterator i = animations.begin(); i != animations.end(); ++i){
std::vector<Util::ReferenceCount<Gui::Animation> > & animations = i->second;
for (std::vector<Util::ReferenceCount<Gui::Animation> >::iterator j = animations.begin(); j != animations.end(); ++j){
Util::ReferenceCount<Gui::Animation> animation = *j;
if (animation != NULL){
animation->forward(tickCount);
}
}
}
}
void AnimationManager::reverse(int tickCount){
for (std::map<Gui::Animation::Depth, std::vector<Util::ReferenceCount<Gui::Animation> > >::iterator i = animations.begin(); i != animations.end(); ++i){
std::vector<Util::ReferenceCount<Gui::Animation> > & animations = i->second;
for (std::vector<Util::ReferenceCount<Gui::Animation> >::iterator j = animations.begin(); j != animations.end(); ++j){
Util::ReferenceCount<Gui::Animation> animation = *j;
if (animation != NULL){
animation->reverse(tickCount);
}
}
}
}
void AnimationManager::act(){
forward();
}
void AnimationManager::render(const Gui::Animation::Depth & depth, const Graphics::Bitmap & work) const {
std::map< Gui::Animation::Depth, std::vector< Util::ReferenceCount<Gui::Animation> > >::const_iterator animation = animations.find(depth);
if (animation != animations.end()){
const vector<Util::ReferenceCount<Gui::Animation> > & all = animation->second;
for (std::vector<Util::ReferenceCount<Gui::Animation> >::const_iterator i = all.begin(); i != all.end(); ++i){
Util::ReferenceCount<Gui::Animation> animation = *i;
if (animation != NULL){
animation->draw(work);
}
}
}
}
void AnimationManager::add(const Util::ReferenceCount<Gui::Animation > & animation){
animations[animation->getDepth()].push_back(animation);
}
void AnimationManager::reset(){
for (std::map<Gui::Animation::Depth, std::vector<Util::ReferenceCount<Gui::Animation> > >::iterator i = animations.begin(); i != animations.end(); ++i){
std::vector<Util::ReferenceCount<Gui::Animation> > & animations = i->second;
for (std::vector<Util::ReferenceCount<Gui::Animation> >::iterator j = animations.begin(); j != animations.end(); ++j){
Util::ReferenceCount<Gui::Animation> animation = *j;
if (animation != NULL){
animation->resetAll();
}
}
}
}
int AnimationManager::totalTicks() const {
int count = 0;
for (map<Gui::Animation::Depth, vector<Util::ReferenceCount<Gui::Animation> > >::const_iterator it = animations.begin(); it != animations.end(); it++){
Gui::Animation::Depth depth = it->first;
const vector<Util::ReferenceCount<Gui::Animation> > & stuff = it->second;
int next = countTicks(stuff);
/* If any animation takes infinite time then the whole thing takes infinite time */
if (next == -1){
return -1;
}
if (next > count){
count = next;
}
}
return count;
}
int AnimationManager::countTicks(const vector<Util::ReferenceCount<Animation> > & toCount) const {
int total = 0;
for (vector<Util::ReferenceCount<Animation> >::const_iterator it = toCount.begin(); it != toCount.end(); it++){
const Util::ReferenceCount<Animation> & animation = *it;
int ticks = animation->totalTicks();
if (ticks == -1){
return ticks;
}
total += ticks;
}
return total;
}
void AnimationManager::setToEnd(){
for (std::map<Gui::Animation::Depth, std::vector<Util::ReferenceCount<Gui::Animation> > >::iterator i = animations.begin(); i != animations.end(); ++i){
std::vector<Util::ReferenceCount<Gui::Animation> > & animations = i->second;
for (std::vector<Util::ReferenceCount<Gui::Animation> >::iterator j = animations.begin(); j != animations.end(); ++j){
Util::ReferenceCount<Gui::Animation> animation = *j;
if (animation != NULL){
animation->setToEnd();
}
}
}
}
const std::string AnimationManager::getInfo(int id, bool all){
std::string info("");
for (std::map<Gui::Animation::Depth, std::vector<Util::ReferenceCount<Gui::Animation> > >::iterator i = animations.begin(); i != animations.end(); ++i){
std::vector<Util::ReferenceCount<Gui::Animation> > & animations = i->second;
for (std::vector<Util::ReferenceCount<Gui::Animation> >::iterator j = animations.begin(); j != animations.end(); ++j){
Util::ReferenceCount<Gui::Animation> animation = *j;
if (animation != NULL){
if (id == animation->getID() || all){
info += animation->getInfo();
}
}
}
}
return info;
}
const std::vector<int> AnimationManager::getIdList(){
std::vector<int> list;
for (std::map<Gui::Animation::Depth, std::vector<Util::ReferenceCount<Gui::Animation> > >::iterator i = animations.begin(); i != animations.end(); ++i){
std::vector<Util::ReferenceCount<Gui::Animation> > & animations = i->second;
for (std::vector<Util::ReferenceCount<Gui::Animation> >::iterator j = animations.begin(); j != animations.end(); ++j){
Util::ReferenceCount<Gui::Animation> animation = *j;
if (animation != NULL){
list.push_back(animation->getID());
}
}
}
return list;
}
diff --git a/src/gui/box.cpp b/src/gui/box.cpp
index ea3cd41c..c38fa5a3 100644
--- a/src/gui/box.cpp
+++ b/src/gui/box.cpp
@@ -1,71 +1,71 @@
-#include "util/graphics/bitmap.h"
-#include "box.h"
+#include "r-tech1/graphics/bitmap.h"
+#include "r-tech1/gui/box.h"
-#include "util/font.h"
+#include "r-tech1/font.h"
using namespace Gui;
Box::Box(){
- // Nothing yet
+ // Nothing yet
}
Box::Box( const Box & b ){
this->location = b.location;
this->transforms = b.transforms;
}
Box::~Box(){
- // Nothing yet
+ // Nothing yet
}
Box &Box::operator=( const Box &copy){
location = copy.location;
transforms = copy.transforms;
return *this;
}
// Logic
void Box::act(const Font & font){
- // Nothing yet
+ // Nothing yet
}
// Render
void Box::render(const Graphics::Bitmap & work){
Util::ReferenceCount<Graphics::Bitmap> workArea = checkWorkArea(work);
if (workArea != NULL){
Graphics::Bitmap::transBlender(0, 0, 0, colors.bodyAlpha);
const Graphics::TranslucentBitmap area = workArea->translucent();
// Check if we are using a rounded box
if (transforms.getRadius() > 0){
area.roundRectFill((int)transforms.getRadius(), 0, 0, area.getWidth() - 1, area.getHeight()-1, colors.body);
area.roundRect((int)transforms.getRadius(), 0, 0, area.getWidth()-1, area.getHeight()-1, colors.border);
} else {
area.rectangleFill(0, 0, area.getWidth()-1, area.getHeight()-1, colors.body);
area.rectangle(0, 0, area.getWidth()-1, location.getHeight()-1, colors.border);
}
// workArea->translucent().draw(location.getX(), location.getY(), work);
}
}
void Box::messageDialog(int centerWidth, int centerHeight, const std::string & message, int radius){
/* FIXME Get rid of this */
#if 0
const Font &vFont = Font::getFont(OldMenu::Menu::getFont(),OldMenu::Menu::getFontWidth(),OldMenu::Menu::getFontHeight());
const int width = vFont.textLength(message.c_str()) + 10;
const int height = vFont.getHeight() + 10;
const int x = (centerWidth/2) - (width/2);
const int y = (centerHeight/2) - (height/2);
Box dialog;
dialog.location.setDimensions(width, height);
dialog.location.setRadius(radius);
dialog.colors.body = Bitmap::makeColor(0,0,0);
dialog.colors.bodyAlpha = 200;
dialog.colors.border = Bitmap::makeColor(255,255,255);
dialog.colors.borderAlpha = 255;
Bitmap temp = Bitmap::temporaryBitmap(width,height);
dialog.render(temp);
vFont.printf( 5, 5, Bitmap::makeColor(255,255,255), temp, message, -1);
temp.BlitToScreen(x,y);
#endif
}
diff --git a/src/gui/container.cpp b/src/gui/container.cpp
index 5293dcf6..7a26e2f2 100644
--- a/src/gui/container.cpp
+++ b/src/gui/container.cpp
@@ -1,50 +1,50 @@
-#include "container.h"
+#include "r-tech1/gui/container.h"
-#include "util/graphics/bitmap.h"
-#include "widget.h"
+#include "r-tech1/graphics/bitmap.h"
+#include "r-tech1/gui/widget.h"
using namespace Gui;
Container::Container()
{
- // Nothing yet
+ // Nothing yet
}
Container::~Container()
{
- // Nothing yet
+ // Nothing yet
}
// Add widget
void Container::add(Widget *widget)
{
- widgets.push_back(widget);
+ widgets.push_back(widget);
}
// Remove widget
void Container::remove(Widget *widget)
{
- widgets.remove(widget);
+ widgets.remove(widget);
}
// Logic
void Container::act(const Font & font){
std::list<Widget *>::iterator i = widgets.begin(), end = widgets.end();
while(i!=end){
(*i)->act(font);
i++;
}
}
// Render
void Container::render(const Graphics::Bitmap & work)
{
- work.setClipRect(position.x,position.y,position.getX2(),position.getY2());
- std::list<Widget *>::iterator i = widgets.begin(), end = widgets.end();
- while(i!=end)
- {
- (*i)->render(work);
- i++;
- }
- work.setClipRect(0,0,work.getWidth(),work.getHeight());
+ work.setClipRect(position.x,position.y,position.getX2(),position.getY2());
+ std::list<Widget *>::iterator i = widgets.begin(), end = widgets.end();
+ while(i!=end)
+ {
+ (*i)->render(work);
+ i++;
+ }
+ work.setClipRect(0,0,work.getWidth(),work.getHeight());
}
diff --git a/src/gui/context-box.cpp b/src/gui/context-box.cpp
index 9566241d..8be277a0 100644
--- a/src/gui/context-box.cpp
+++ b/src/gui/context-box.cpp
@@ -1,359 +1,359 @@
-#include "util/graphics/bitmap.h"
+#include "r-tech1/graphics/bitmap.h"
-#include "context-box.h"
-#include "util/font.h"
+#include "r-tech1/gui/context-box.h"
+#include "r-tech1/font.h"
#include <math.h>
-#include "util/token.h"
+#include "r-tech1/token.h"
static const double FONT_SPACER = 1.3;
static const int GradientMax = 50;
static Graphics::Color selectedGradientStart(){
static Graphics::Color color = Graphics::makeColor(19, 167, 168);
return color;
}
static Graphics::Color selectedGradientEnd(){
static Graphics::Color color = Graphics::makeColor(27, 237, 239);
return color;
}
using namespace std;
namespace Gui{
Effects::Gradient standardGradient(int max){
Effects::Gradient standard(max, selectedGradientStart(), selectedGradientEnd());
return standard;
}
Effects::Gradient modifiedGradient(Graphics::Color low, Graphics::Color high, int max){
Effects::Gradient modified(max, low, high);
return modified;
}
ListValues::ListValues():
interpolate(true),
lowColor(selectedGradientStart()),
highColor(selectedGradientEnd()),
maxGradient(GradientMax),
selectedColor(selectedGradientStart()),
selectedAlpha(255),
otherColor(Graphics::makeColor(255, 255, 255)),
otherAlpha(255),
distanceFadeMultiplier(35),
fade(true){
}
ListValues::ListValues(const ListValues & copy):
interpolate(copy.interpolate),
lowColor(copy.lowColor),
highColor(copy.highColor),
maxGradient(copy.maxGradient),
selectedColor(copy.selectedColor),
selectedAlpha(copy.selectedAlpha),
otherColor(copy.otherColor),
otherAlpha(copy.otherAlpha),
distanceFadeMultiplier(copy.distanceFadeMultiplier),
fade(copy.fade){
}
ListValues::~ListValues(){
}
const ListValues & ListValues::operator=(const ListValues & copy){
interpolate = copy.interpolate;
lowColor = copy.lowColor;
highColor = copy.highColor;
maxGradient = copy.maxGradient;
selectedColor = copy.selectedColor;
selectedAlpha = copy.selectedAlpha;
otherColor = copy.otherColor;
otherAlpha = copy.otherAlpha;
distanceFadeMultiplier = copy.distanceFadeMultiplier;
fade = copy.fade;
return *this;
}
static int clamp(int in, int low = 0, int high = 255){
if (in < low){
return low;
}
if (in > high){
return high;
}
return in;
}
void ListValues::getValues(const Token * token){
TokenView view = token->view();
while (view.hasMore()){
const Token * token;
view >> token;
try{
int red = 0, green = 0, blue = 0, alpha = 0, gradient=1;
if (token->match("interpolate-selected", interpolate)){
} else if (token->match("color-low", red, green, blue)){
lowColor = Graphics::makeColor(clamp(red), clamp(green), clamp(blue));
} else if (token->match("color-high", red, green, blue)){
highColor = Graphics::makeColor(clamp(red), clamp(green), clamp(blue));
} else if (token->match("interpolate-distance", gradient)){
maxGradient = clamp(gradient, 1, 1000);
} else if (token->match("selected-color", red, green, blue)){
selectedColor = Graphics::makeColor(clamp(red), clamp(green), clamp(blue));
} else if (token->match("selected-color-alpha", alpha)){
selectedAlpha = clamp(alpha);
} else if (token->match("other-color", red, green, blue)){
otherColor = Graphics::makeColor(clamp(red), clamp(green), clamp(blue));
} else if (token->match("other-color-alpha", alpha)){
otherAlpha = clamp(alpha);
} else if (token->match("distance-fade-multiplier", distanceFadeMultiplier)){
} else if (token->match("distance-fade", fade)){
}
} catch (const TokenException & ex){
// Output something
}
}
}
ContextItem::ContextItem(const std::string & name, const ContextBox & parent):
text(name),
parent(parent){
}
ContextItem::~ContextItem(){
}
void ContextItem::draw(int x, int y, const Graphics::Bitmap & where, const Font & font, int distance) const {
if (distance == 0){
if (parent.getListValues().getInterpolate()){
Graphics::Bitmap::transBlender(0, 0, 0, parent.getFadeAlpha());
font.printf(x, y, parent.getSelectedColor(), where.translucent(), getText(), 0);
} else {
Graphics::Bitmap::transBlender(0, 0, 0, parent.getListValues().getSelectedAlpha());
font.printf(x, y, parent.getListValues().getSelectedColor(), where.translucent(), getText(), 0);
}
} else {
if (parent.getListValues().getDistanceFade()){
int alpha = parent.getListValues().getOtherAlpha() - fabs((double) distance) * parent.getListValues().getDistanceFadeMultiplier();
alpha = clamp(alpha);
Graphics::Bitmap::transBlender(0, 0, 0, alpha);
font.printf(x, y, parent.getListValues().getOtherColor(), where.translucent(), getText(), 0);
} else {
Graphics::Bitmap::transBlender(0, 0, 0, parent.getListValues().getOtherAlpha());
font.printf(x, y, parent.getListValues().getOtherColor(), where.translucent(), getText(), 0);
}
}
}
void ContextItem::setText(const LanguageString & t){
text = t;
}
int ContextItem::size(const Font & font) const {
return font.textLength(getText().c_str());
}
ContextBox::ContextBox():
fadeState(NotActive),
list(new ScrollList()),
fadeSpeed(12),
fadeAlpha(0),
cursorCenter(0),
cursorLocation(0),
scrollWait(4),
selectedGradient(standardGradient(GradientMax)),
renderOnlyText(false){
}
ContextBox::ContextBox( const ContextBox & copy ):
fadeState(NotActive),
list(new ScrollList()),
selectedGradient(standardGradient(GradientMax)),
renderOnlyText(false){
this->list = copy.list;
this->fadeSpeed = copy.fadeSpeed;
this->fadeAlpha = copy.fadeAlpha;
this->cursorCenter = copy.cursorCenter;
this->cursorLocation = copy.cursorLocation;
this->scrollWait = copy.scrollWait;
this->renderOnlyText = copy.renderOnlyText;
}
ContextBox::~ContextBox(){
}
ContextBox & ContextBox::operator=( const ContextBox & copy){
this->fadeState = NotActive;
this->list = copy.list;
this->fadeSpeed = copy.fadeSpeed;
this->fadeAlpha = copy.fadeAlpha;
this->cursorCenter = copy.cursorCenter;
this->cursorLocation = copy.cursorLocation;
this->scrollWait = copy.scrollWait;
this->renderOnlyText = copy.renderOnlyText;
return *this;
}
void ContextBox::act(const Font & font){
// update board
board.act(font);
// Calculate text info
list->act();
// do fade
doFade();
// Update gradient
selectedGradient.update();
}
void ContextBox::render(const Graphics::Bitmap & work){
}
void ContextBox::render(const Graphics::Bitmap & work, const Font & font){
if (!renderOnlyText){
- board.render(work);
+ board.render(work);
}
drawText(work, font);
}
bool ContextBox::next(const Font & font){
if (fadeState == FadeOut){
return false;
}
list->next();
return true;
}
bool ContextBox::previous(const Font & font){
if (fadeState == FadeOut){
return false;
}
list->previous();
return true;
}
Graphics::Color ContextBox::getSelectedColor() const {
return values.getInterpolate() ? selectedGradient.current() : values.getSelectedColor();
}
void ContextBox::setListValues(const Gui::ListValues & values){
this->values = values;
selectedGradient = modifiedGradient(values.getLowColor(), values.getHighColor(), values.getMaxGradient());
}
void ContextBox::adjustLeft(){
}
void ContextBox::adjustRight(){
}
void ContextBox::open(){
// Set the fade stuff
fadeState = FadeIn;
//board.position = position;
board.location = location;
board.transforms = transforms;
board.colors = colors;
board.open();
fadeAlpha = 0;
cursorLocation = 0;
}
void ContextBox::close(){
fadeState = FadeOut;
board.close();
fadeAlpha = 255;
cursorLocation = 480;
}
void ContextBox::doFade(){
switch (fadeState){
case FadeIn: {
if (fadeAlpha < 255){
fadeAlpha += (fadeSpeed+2);
}
if (fadeAlpha >= 255){
fadeAlpha = 255;
if (board.isActive()){
fadeState = Active;
}
}
break;
}
case FadeOut: {
if (fadeAlpha > 0){
fadeAlpha -= (fadeSpeed+2);
}
if (fadeAlpha <= 0){
fadeAlpha = 0;
if (!board.isActive()){
fadeState = NotActive;
}
}
break;
}
case Active:
case NotActive:
default:
break;
}
}
void ContextBox::setList(const std::vector<Util::ReferenceCount<ContextItem> > & list){
this->list->clearItems();
for (vector<Util::ReferenceCount<ContextItem> >::const_iterator it = list.begin(); it != list.end(); it++){
const Util::ReferenceCount<ContextItem> & item = *it;
this->list->addItem(item);
}
}
void ContextBox::addItem(const Util::ReferenceCount<ContextItem> & item){
this->list->addItem(item);
}
void ContextBox::setListType(const ListType & type){
switch (type){
case Normal:{
Util::ReferenceCount<ScrollListInterface> newList(new NormalList());
newList->addItems(list->getItems());
list = newList;
break;
}
case Scroll:{
Util::ReferenceCount<ScrollListInterface> newList(new ScrollList());
newList->addItems(list->getItems());
list = newList;
break;
}
default:
break;
}
}
void ContextBox::setListWrap(bool wrap){
list->setWrap(wrap);
}
void ContextBox::drawText(const Graphics::Bitmap & bmp, const Font & font){
const int x1 = board.getArea().getX()+(int)(board.getTransforms().getRadius()/2);
const int y1 = board.getArea().getY()+2;//(board.getArea().radius/2);
const int x2 = board.getArea().getX2()-(int)(board.getTransforms().getRadius()/2);
const int y2 = board.getArea().getY2()-2;//(board.getArea().radius/2);
if (x2 > x1 && y2 > y1){
Graphics::Bitmap area(bmp, x1, y1, x2 - x1, y2 - y1);
list->render(area, font);
}
}
}
diff --git a/src/gui/coordinate.cpp b/src/gui/coordinate.cpp
index 6358c720..6ab3f76a 100644
--- a/src/gui/coordinate.cpp
+++ b/src/gui/coordinate.cpp
@@ -1,534 +1,534 @@
-#include "util/graphics/bitmap.h"
-#include "coordinate.h"
-#include "util/funcs.h"
-#include "util/exceptions/load_exception.h"
+#include "r-tech1/graphics/bitmap.h"
+#include "r-tech1/gui/coordinate.h"
+#include "r-tech1/funcs.h"
+#include "r-tech1/exceptions/load_exception.h"
#include <sstream>
#include <math.h>
using namespace Gui;
namespace Gui{
namespace Space{
static double translate(double x, double amount){
return x + amount;
}
static double scale(double x, double amount){
return x * amount;
}
/* convert a point in a space with the given width to a new space with the given width
* 1. translate relative original origin
* 2. scale it to the range -1, 1
* 3. scale it to the new width
* 4. translate relative to the new origin
*/
static double convertSpace(double original, double originalMinimum, double originalWidth, double newMinimum, double newWidth){
return translate(scale(scale(translate(original, -originalMinimum),
1.0 / originalWidth),
newWidth),
newMinimum);
}
/* hard coded for now */
static double physicalWidth = 640;
static double physicalHeight = 480;
Point::Point(double x, double y, const Space & space):
x(x),
y(y),
space(space){
}
Point::Point(const Point & point, const Space & space):
space(space){
x = space.getLocalX(point.physicalX());
y = space.getLocalY(point.physicalY());
}
Point::Point(const Point & point):
x(point.x),
y(point.y),
space(point.space){
}
static bool close(double a, double b){
return fabs(a - b) < 0.0001;
}
bool Point::operator==(const Point & him) const {
if (this == &him){
return true;
}
return close(physicalX(), him.physicalX()) &&
close(physicalY(), him.physicalY());
}
bool Point::operator!=(const Point & him) const {
return !(*this == him);
}
Point & Point::operator=(const Point & point){
if (*this == point){
this->x = point.x;
this->y = point.y;
} else {
this->x = space.getLocalX(point.physicalX());
this->y = space.getLocalY(point.physicalY());
}
return *this;
}
Point & Point::operator+=(const Point & point){
*this = *this + point;
return *this;
}
Point Point::operator+(const Point & point){
if (sameSpace(point)){
x = space.boundX(x + point.x);
y = space.boundY(y + point.y);
return *this;
} else {
return *this + Point(point, space);
}
}
bool Point::sameSpace(const Point & point) const {
return space == point.space;
}
double Point::physicalX() const {
return convertSpace(x, space.getMinimumX(), space.sizeX(), 0, physicalWidth);
}
double Point::physicalY() const {
return convertSpace(y, space.getMinimumY(), space.sizeY(), 0, physicalHeight);
}
Space::Space(double minX, double minY, double maxX, double maxY):
minX(minX),
minY(minY),
maxX(maxX),
maxY(maxY){
}
bool Space::operator==(const Space & space) const {
if (this == &space){
return true;
}
return minX == space.minX &&
minY == space.minY &&
maxX == space.maxX &&
maxY == space.maxY;
}
Point Space::fromPhysical(int x, int y){
return Point(getLocalX(x), getLocalY(y), *this);
}
Point Space::fromLocal(double x, double y){
return Point(boundX(x), boundY(y), *this);
}
double Space::sizeX() const {
return maxX - minX;
}
double Space::sizeY() const {
return maxY - minY;
}
double Space::boundX(double x) const {
return Util::clamp(x, minX, maxX);
}
double Space::boundY(double y) const {
return Util::clamp(y, minY, maxY);
}
double Space::centerX() const {
return (maxX - minX) / 2;
}
double Space::centerY() const {
return (maxY - minY) / 2;
}
double Space::getLocalX(double physicalX) const {
return convertSpace(physicalX, 0, physicalWidth, minX, sizeX());
}
double Space::getLocalY(double physicalY) const {
return convertSpace(physicalY, 0, physicalHeight, minY, sizeY());
}
double Space::getMinimumX() const {
return minX;
}
double Space::getMinimumY() const {
return minY;
}
}
}
static int relativeToAbsolute(double x, int center){
return (int)(center + (center * x));
}
static int amountFromCenterX(int x){
return x - (640 / 2);
}
static int amountFromCenterY(int y){
return y - (480 / 2);
}
/* scale an absolute distance to a relative distance
* distance / absolute = X / relative
* absolute space = 0 to 640
* relative space = -1 to 1
* X = distance * relative / absolute
*/
static double scaleAbsoluteToRelativeDistanceX(int distance){
return distance * (1.0 - (-1.0)) / (640.0 - 0);
}
static double scaleAbsoluteToRelativeDistanceY(int distance){
return distance * (1.0 - (-1.0)) / (480.0 - 0);
}
/* convert a point in absolute space to relative space */
static double absoluteToRelative(int x, int center){
return (double)(x-center)/center;
}
static double relativeToAbsoluteX(double x){
// return relativeToAbsolute(x, Global::getScreenWidth() / 2);
return relativeToAbsolute(x, 640 / 2);
}
static double relativeToAbsoluteY(double y){
// return relativeToAbsolute(y, Global::getScreenHeight() / 2);
return relativeToAbsolute(y, 480 / 2);
}
static double absoluteToRelativeX(int x){
return absoluteToRelative(x, 640/2);
}
static double absoluteToRelativeY(int y){
return absoluteToRelative(y, 480/2);
}
AbsolutePoint::AbsolutePoint():
x(0),
y(0){
}
AbsolutePoint::AbsolutePoint(int x, int y):
x(x),
y(y){
}
AbsolutePoint::AbsolutePoint(const AbsolutePoint & copy):
x(copy.x),
y(copy.y){
}
AbsolutePoint::~AbsolutePoint(){
}
const AbsolutePoint & AbsolutePoint::operator=(const AbsolutePoint & copy){
this->x = copy.x;
this->y = copy.y;
return *this;
}
int AbsolutePoint::getX() const {
return x;
}
int AbsolutePoint::getY() const {
return y;
}
RelativePoint::RelativePoint():
x(0),
y(0){
}
RelativePoint::RelativePoint(double x, double y):
x(x),
y(y){
}
RelativePoint::RelativePoint(const RelativePoint & copy):
x(copy.x),
y(copy.y){
}
RelativePoint::RelativePoint(const AbsolutePoint & point):
x(absoluteToRelativeX(point.getX())),
y(absoluteToRelativeY(point.getY())){
}
RelativePoint::~RelativePoint(){
}
const RelativePoint & RelativePoint::operator=(const RelativePoint & copy){
this->x = copy.x;
this->y = copy.y;
return *this;
}
const RelativePoint & RelativePoint::operator=(const AbsolutePoint & point){
this->x = absoluteToRelativeX(point.getX());
this->y = absoluteToRelativeY(point.getY());
return *this;
}
bool RelativePoint::operator==(const RelativePoint & point){
return (this->x == point.x && this->y == point.y);
}
bool RelativePoint::operator!=(const RelativePoint & point){
return !(*this == point);
}
int RelativePoint::getX() const{
return relativeToAbsoluteX(x);
}
int RelativePoint::getY() const{
return relativeToAbsoluteY(y);
}
int RelativePoint::getDistanceFromCenterX() const {
return amountFromCenterX(getX());
}
int RelativePoint::getDistanceFromCenterY() const {
return amountFromCenterY(getY());
}
void RelativePoint::moveX(double percent){
x += percent;
}
void RelativePoint::moveY(double percent){
y += percent;
}
void RelativePoint::moveBy(double x, double y){
moveX(x);
moveY(y);
}
AbsolutePoint RelativePoint::getAbsolute(){
return AbsolutePoint(relativeToAbsoluteX(x), relativeToAbsoluteY(y));
}
double RelativePoint::getRelativeX() const{
return x;
}
double RelativePoint::getRelativeY() const{
return y;
}
Coordinate::Coordinate():
z(0){
}
Coordinate::Coordinate(AbsolutePoint & position, AbsolutePoint & position2):
position(position),
position2(position2),
z(0){
}
Coordinate::Coordinate(const RelativePoint & position, const RelativePoint & position2):
position(position),
position2(position2),
z(0){
}
Coordinate::Coordinate(const Coordinate & copy):
position(copy.position),
position2(copy.position2),
z(copy.z){
}
Coordinate::~Coordinate(){
}
const Coordinate & Coordinate::operator=(const Coordinate & copy){
this->position = copy.position;
this->position2 = copy.position2;
this->z = copy.z;
return *this;
}
int Coordinate::getX() const{
return position.getX();
}
int Coordinate::getY() const{
return position.getY();
}
int Coordinate::getWidth() const {
return position2.getX() - position.getX();
}
int Coordinate::getHeight() const {
return position2.getY() - position.getY();
}
int Coordinate::getX2() const{
return position2.getX();
}
int Coordinate::getY2() const{
return position2.getY();
}
void Coordinate::growHorizontal(double by){
position.moveX(-(by));
position2.moveX(by);
}
void Coordinate::growHorizontalAbsolute(int distance){
growHorizontal(scaleAbsoluteToRelativeDistanceX(distance));
}
void Coordinate::growVerticalAbsolute(int distance){
growVertical(scaleAbsoluteToRelativeDistanceY(distance));
}
void Coordinate::growVertical(double by){
position.moveY(-(by));
position2.moveY(by);
}
void Coordinate::growTo(const Coordinate & coord, double percent){
if (position.getRelativeX() > coord.position.getRelativeX()){
position.moveX(-(percent));
if (position.getRelativeX() < coord.position.getRelativeX()){
position.setX(coord.position.getRelativeX());
}
} else if (position.getRelativeX() < coord.position.getRelativeX()){
position.moveX(percent);
if (position.getRelativeX() > coord.position.getRelativeX()){
position.setX(coord.position.getRelativeX());
}
}
if (position.getRelativeY() > coord.position.getRelativeY()){
position.moveY(-(percent));
if (position.getRelativeY() < coord.position.getRelativeY()){
position.setY(coord.position.getRelativeY());
}
} else if (position.getRelativeY() < coord.position.getRelativeY()){
position.moveY(percent);
if (position.getRelativeY() > coord.position.getRelativeY()){
position.setY(coord.position.getRelativeY());
}
}
if (position2.getRelativeX() > coord.position2.getRelativeX()){
position2.moveX(-(percent));
if (position2.getRelativeX() < coord.position2.getRelativeX()){
position2.setX(coord.position2.getRelativeX());
}
} else if (position2.getRelativeX() < coord.position2.getRelativeX()){
position2.moveX(percent);
if (position2.getRelativeX() > coord.position2.getRelativeX()){
position2.setX(coord.position2.getRelativeX());
}
}
if (position2.getRelativeY() > coord.position2.getRelativeY()){
position2.moveY(-(percent));
if (position2.getRelativeY() < coord.position2.getRelativeY()){
position2.setY(coord.position2.getRelativeY());
}
} else if (position2.getRelativeY() < coord.position2.getRelativeY()){
position2.moveY(percent);
if (position2.getRelativeY() > coord.position2.getRelativeY()){
position2.setY(coord.position2.getRelativeY());
}
}
}
void Coordinate::center(const Coordinate & coord){
const double centerx = (coord.getRelativeX1() + coord.getRelativeX2())/2;
const double centery = (coord.getRelativeY1() + coord.getRelativeY2())/2;
set(centerx, centery, centerx, centery);
}
void Coordinate::moveBy(double x, double y){
position.moveBy(x, y);
position2.moveBy(x, y);
}
bool Coordinate::operator==( const Coordinate & coord){
return ( (position == coord.position) &&
(position2 == coord.position2));
}
bool Coordinate::operator!=( const Coordinate & coord){
return ( !(position == coord.position) ||
!(position2 == coord.position2));
}
bool Coordinate::operator==( const Graphics::Bitmap & bmp){
return ( (getWidth() == bmp.getWidth()) &&
(getHeight() == bmp.getHeight()));
}
bool Coordinate::operator!=( const Graphics::Bitmap & bmp){
return !(*this == bmp);
}
void Coordinate::setPosition(const RelativePoint & point){
position = point;
}
void Coordinate::setPosition(const AbsolutePoint & point){
position = RelativePoint(point);
}
void Coordinate::setPosition2(const RelativePoint & point){
position2 = point;
}
void Coordinate::setPosition2(const AbsolutePoint & point){
position2 = RelativePoint(point);
}
void Coordinate::moveTo(const AbsolutePoint & where){
double dx = position2.getRelativeX() - position.getRelativeX();
double dy = position2.getRelativeY() - position.getRelativeY();
setPosition(where);
/* sort of ugly, use operator+ for RelativePosition */
setPosition2(RelativePoint(position.getRelativeX() + dx, position.getRelativeY() + dy));
}
void Coordinate::checkDimensions(){
if (getWidth() < 0 || getHeight() < 0){
std::ostringstream out;
out << "Cannot have a negative coordinate dimension " << getWidth() << ", " << getHeight();
throw LoadException(__FILE__, __LINE__, out.str());
}
}
void Coordinate::setDimensions(int width, int height){
position2 = RelativePoint(AbsolutePoint(getX() + width, getY() + height));
}
void Coordinate::setCenterPosition(const RelativePoint & center){
int width = getWidth();
int height = getHeight();
this->position = center;
this->position2 = center;
growHorizontalAbsolute(width / 2.0);
growVerticalAbsolute(height / 2.0);
}
diff --git a/src/gui/cutscene.cpp b/src/gui/cutscene.cpp
index 6d206b86..f121532b 100644
--- a/src/gui/cutscene.cpp
+++ b/src/gui/cutscene.cpp
@@ -1,326 +1,326 @@
-#include "cutscene.h"
-
-#include "util/graphics/bitmap.h"
-#include "util/init.h"
-#include "util/input/input-map.h"
-#include "util/exceptions/load_exception.h"
-#include "util/input/input-manager.h"
-#include "util/input/input-source.h"
-#include "util/token.h"
-#include "util/tokenreader.h"
-#include "util/file-system.h"
-#include "util/configuration.h"
+#include "r-tech1/gui/cutscene.h"
+
+#include "r-tech1/graphics/bitmap.h"
+#include "r-tech1/init.h"
+#include "r-tech1/input/input-map.h"
+#include "r-tech1/exceptions/load_exception.h"
+#include "r-tech1/input/input-manager.h"
+#include "r-tech1/input/input-source.h"
+#include "r-tech1/token.h"
+#include "r-tech1/tokenreader.h"
+#include "r-tech1/file-system.h"
+#include "r-tech1/configuration.h"
using namespace Gui;
Scene::Scene(const Token * token):
ticks(0),
endTicks(-1){
parseScene(token);
}
Scene::~Scene(){
}
void Scene::parseScene(const Token * token){
if (*token != "scene"){
throw LoadException(__FILE__, __LINE__, "Not a Scene");
}
TokenView view = token->view();
while (view.hasMore()){
try{
const Token * tok;
view >> tok;
if (*tok == "time"){
tok->view() >> endTicks;
} else if (*tok == "animation" || *tok == "anim"){
addAnimation(Util::ReferenceCount<Gui::Animation>(new Gui::Animation(tok)));
} else if (*tok == "fade"){
fader.parseDefaults(tok);
} else if (*tok == "file"){
std::string file;
tok->view() >> file;
TokenReader reader;
parseScene(reader.readTokenFromFile(Storage::instance().find(Filesystem::RelativePath(file)).path()));
} else {
Global::debug(3) << "Unhandled Scene attribute: " << std::endl;
if (Global::getDebug() >= 3){
tok->print(" ");
}
}
} catch ( const TokenException & ex ) {
throw LoadException(__FILE__, __LINE__, ex, "Scene parse error");
} catch ( const LoadException & ex ) {
throw ex;
}
}
}
void Scene::forward(int tickCount){
backgrounds.forward(tickCount);
fader.act();
// Increment ticks
ticks += tickCount;
// Fade out
if (endTicks >= 0){
const int check = endTicks - ticks;
if (check <= fader.getFadeOutTime() && fader.getState() != Gui::FadeTool::FadeOut){
fader.setState(Gui::FadeTool::FadeOut);
}
}
}
void Scene::reverse(int tickCount){
backgrounds.reverse(tickCount);
fader.act();
// Increment ticks
ticks -= tickCount;
// Fade out
if (ticks <= fader.getFadeInTime() && fader.getState() != Gui::FadeTool::FadeOut){
fader.setState(Gui::FadeTool::FadeOut);
}
}
void Scene::act(){
forward();
}
void Scene::render(const Graphics::Bitmap & work){
// Backgrounds
backgrounds.render(Gui::Animation::BackgroundBottom, work);
backgrounds.render(Gui::Animation::BackgroundMiddle, work);
backgrounds.render(Gui::Animation::BackgroundTop, work);
// Foregrounds
backgrounds.render(Gui::Animation::ForegroundBottom, work);
backgrounds.render(Gui::Animation::ForegroundMiddle, work);
backgrounds.render(Gui::Animation::ForegroundTop, work);
fader.draw(work);
}
void Scene::addAnimation(const Util::ReferenceCount<Gui::Animation> & animation){
backgrounds.add(animation);
}
void Scene::reset(){
ticks = 0;
backgrounds.reset();
fader.setState(Gui::FadeTool::FadeIn);
}
void Scene::setToEnd(){
if (endTicks >= 0){
ticks = endTicks;
} else {
if (backgrounds.totalTicks() != -1){
ticks = backgrounds.totalTicks();
}
}
backgrounds.setToEnd();
fader.setState(Gui::FadeTool::FadeIn);
}
bool Scene::done() const {
if (ticks <= 0){
return true;
}
if (endTicks >= 0){
if (ticks >= endTicks){
return true;
}
} else {
if (backgrounds.totalTicks() != -1){
if (ticks >= backgrounds.totalTicks()){
return true;
}
}
}
return false;
}
CutScene::CutScene():
width(640),
height(480),
current(0){
}
CutScene::CutScene(const Filesystem::AbsolutePath & path):
width(640),
height(480),
current(0){
TokenReader reader;
load(reader.readTokenFromFile(path.path().c_str()));
}
CutScene::CutScene(const Token * token):
width(640),
height(480),
current(0){
load(token);
}
CutScene::~CutScene(){
}
void CutScene::load(const Token * token){
if (*token != "cutscene"){
throw LoadException(__FILE__, __LINE__, "Not a CutScene");
}
TokenView view = token->view();
while (view.hasMore()){
try{
const Token * tok;
view >> tok;
if (*tok == "name"){
tok->view() >> name;
} else if (*tok == "resolution"){
int x = 640;
int y = 480;
tok->view() >> x >> y;
setResolution(x, y);
} else if (*tok == "scene"){
scenes.push_back(Util::ReferenceCount<Scene>(new Scene(tok)));
} else {
Global::debug(3) << "Unhandled Cutscene attribute: " << std::endl;
if (Global::getDebug() >= 3){
tok->print(" ");
}
}
} catch ( const TokenException & ex ) {
throw LoadException(__FILE__, __LINE__, ex, "Cutscene parse error");
} catch ( const LoadException & ex ) {
throw ex;
}
}
}
void CutScene::setName(const std::string & n){
name = n;
}
void CutScene::setResolution(int w, int h){
width = w;
height = h;
}
void CutScene::setScene(unsigned int scene){
if (scene >= scenes.size()){
current = scenes.size()-1;
} else {
current = scene;
}
}
enum Keys{
Esc
};
Util::ReferenceCount<Scene> CutScene::getCurrent(){
if (scenes.empty()){
return Util::ReferenceCount<Scene>(NULL);
}
return scenes[current];
}
void CutScene::playAll(){
for (unsigned int i = 0; i < scenes.size(); i++){
playScene(i);
}
}
void CutScene::playScene(unsigned int scene){
class Logic: public Util::Logic {
public:
Logic(InputMap<Keys> & input, Util::ReferenceCount<Scene> scene):
is_done(false),
input(input),
scene(scene){
}
bool is_done;
InputMap<Keys> & input;
Util::ReferenceCount<Scene> scene;
bool done(){
return is_done;
}
void run(){
std::vector<InputMap<Keys>::InputEvent> out = InputManager::getEvents(input, InputSource(true));
for (std::vector<InputMap<Keys>::InputEvent>::iterator it = out.begin(); it != out.end(); it++){
const InputMap<Keys>::InputEvent & event = *it;
if (event.enabled){
if (event.out == Esc){
is_done = true;
}
}
}
scene->act();
if (scene->done()){
is_done = true;
}
}
double ticks(double system){
return system * Global::ticksPerSecond(90);
}
};
class Draw: public Util::Draw {
public:
Draw(const Logic & logic, Util::ReferenceCount<Scene> scene, int width, int height):
logic(logic),
scene(scene),
width(width),
height(height){
}
const Logic & logic;
Util::ReferenceCount<Scene> scene;
int width, height;
void draw(const Graphics::Bitmap & buffer){
Graphics::StretchedBitmap work(width, height, buffer);
work.start();
scene->render(work);
work.finish();
buffer.BlitToScreen();
}
};
if (scene < scenes.size()){
InputMap<Keys> input;
input.set(Keyboard::Key_ESC, 0, true, Esc);
input.set(Joystick::Quit, 0, true, Esc);
input.set(Configuration::getAttack1(0), Esc);
input.set(Joystick::Button1, Esc);
Logic logic(input, scenes[scene]);
Draw draw(logic, scenes[scene], width, height);
Util::standardLoop(logic, draw);
}
}
void CutScene::playScene(){
if (current < scenes.size()){
playScene(current);
}
}
void CutScene::next(){
if (current <= scenes.size()){
current += 1;
}
}
bool CutScene::hasMore(){
return (current < scenes.size());
}
diff --git a/src/gui/fadetool.cpp b/src/gui/fadetool.cpp
index cd761768..5bf842a0 100644
--- a/src/gui/fadetool.cpp
+++ b/src/gui/fadetool.cpp
@@ -1,149 +1,149 @@
-#include "fadetool.h"
-#include "util/graphics/bitmap.h"
-#include "../token.h"
-#include "util/exceptions/load_exception.h"
+#include "r-tech1/gui/fadetool.h"
+#include "r-tech1/graphics/bitmap.h"
+#include "r-tech1/token.h"
+#include "r-tech1/exceptions/load_exception.h"
-#include "util/debug.h"
+#include "r-tech1/debug.h"
using namespace Gui;
FadeTool::FadeTool():
currentState(FadeIn),
lastState(FadeIn),
fadeTime(255),
fadeInTime(0),
fadeOutTime(0),
fadeInColor(Graphics::makeColor(0,0,0)),
fadeOutColor(Graphics::makeColor(0,0,0)){
}
FadeTool::~FadeTool(){
}
void FadeTool::parseDefaults(const Token * token){
if ( *token != "fade" ){
throw LoadException(__FILE__, __LINE__, "Not a fader");
}
/*!
* (fade
(in (color 0 0 0) (time 0) )
(out (color 0 0 0) (time 0) ))
*/
const Token & ourToken = *token;
TokenView view = ourToken.view();
while (view.hasMore()){
try{
const Token * tok;
view >> tok;
if (*tok == "in"){
readFade(tok, FadeIn);
} else if (*tok == "out"){
readFade(tok, FadeOut);
}
} catch ( const TokenException & ex ) {
throw LoadException(__FILE__, __LINE__, ex, "Fade tool parse error");
} catch ( const LoadException & ex ) {
throw ex;
}
}
}
void FadeTool::setState( const State & f){
lastState = currentState;
currentState = f;
switch (currentState){
case FadeIn:
fadeTime = 255;
break;
case FadeOut:
fadeTime = 0;
break;
case NoFade:
case EndFade:
default:
fadeTime = 0;
break;
}
}
void FadeTool::act(){
switch (currentState){
case FadeIn:
fadeTime -= (255/(fadeInTime <= 0 ? 1 : fadeInTime));
if (fadeTime<=0){
setState(NoFade);
}
break;
case FadeOut:
fadeTime += (255/(fadeOutTime <= 0 ? 1 : fadeOutTime));
if (fadeTime>=255){
setState(EndFade);
}
break;
case NoFade:
case EndFade:
default:
break;
}
}
void FadeTool::draw(const Graphics::Bitmap &bmp){
switch (currentState){
case FadeIn:
Graphics::Bitmap::transBlender(0,0,0, fadeTime);
bmp.translucent().rectangleFill(0, 0, bmp.getWidth(), bmp.getHeight(), fadeInColor);
break;
case FadeOut:
Graphics::Bitmap::transBlender(0,0,0, fadeTime);
bmp.translucent().rectangleFill(0, 0, bmp.getWidth(), bmp.getHeight(), fadeOutColor);
break;
case NoFade:
case EndFade:
default:
break;
}
}
void FadeTool::readFade(const Token * token, const State & type){
TokenView view = token->view();
while (view.hasMore()){
try{
const Token * tok;
view >> tok;
if (*tok == "color"){
int red = 0, green = 0, blue = 0;
try {
tok->view() >> red >> green >> blue;
} catch (const TokenException & ex){
}
if (type == FadeIn){
setFadeInColor(Graphics::makeColor(red, green, blue));
} else if (type == FadeOut){
setFadeOutColor(Graphics::makeColor(red, green, blue));
}
} else if ( *tok == "time" ){
int time=0;
try {
tok->view() >> time;
} catch (const TokenException & ex){
}
if (type == FadeIn){
setFadeInTime(time);
} else if (type == FadeOut){
setFadeOutTime(time);
}
} else {
Global::debug(3) << "Unhandled FadeTool attribute: " << std::endl;
if (Global::getDebug() >= 3){
tok->print(" ");
}
}
} catch ( const TokenException & ex ) {
throw LoadException(__FILE__, __LINE__, ex, "FadeTool parse error");
} catch ( const LoadException & ex ) {
throw ex;
}
}
}
diff --git a/src/gui/lineedit.cpp b/src/gui/lineedit.cpp
index 25132573..c8c181e5 100644
--- a/src/gui/lineedit.cpp
+++ b/src/gui/lineedit.cpp
@@ -1,100 +1,100 @@
-#include "util/graphics/bitmap.h"
-#include "util/font.h"
-#include "lineedit.h"
-#include "util/debug.h"
+#include "r-tech1/graphics/bitmap.h"
+#include "r-tech1/font.h"
+#include "r-tech1/gui/lineedit.h"
+#include "r-tech1/debug.h"
#include <iostream>
using namespace Gui;
static Global::stream_type & debug(int level){
Global::debug(level) << "[line edit] ";
return Global::debug(level);
}
LineEdit::LineEdit():
blinkRate(30),
cursorTime(0),
changed(false){
colors.body = Graphics::makeColor(0,0,60);
colors.border = Graphics::makeColor(0,0,20);
colors.bodyAlpha = colors.borderAlpha = 150;
textColor = Graphics::makeColor(255,255,255);
cursorColor = Graphics::makeColor(128,128,128);
transforms.setRadius(10);
input.enable();
}
LineEdit::~LineEdit(){
}
void LineEdit::setTextColor(const Graphics::Color color){
textColor = color;
}
void LineEdit::setCursorColor(const Graphics::Color color){
cursorColor = color;
}
void LineEdit::act(const Font &){
if (input.doInput()){
changed = true;
} else {
changed = false;
}
cursorTime++;
if (cursorTime > blinkRate*2){
cursorTime = 0;
}
}
void LineEdit::draw(const Font & font, const Graphics::Bitmap & work){
Graphics::Bitmap temp = Graphics::Bitmap(work, location.getX(), location.getY(), location.getWidth(), location.getHeight());
drawBox(transforms.getRadius(), 0, 0, location.getWidth(), location.getHeight(), colors, temp);
const int modifier = (temp.getWidth() * (transforms.getRadius()*.001)) == 0 ? 2 : (temp.getWidth() * (transforms.getRadius()*.001));
Graphics::Bitmap textTemp = Graphics::Bitmap(temp, modifier, 0, temp.getWidth()-(modifier * 2), temp.getHeight());
const int fontLength = font.textLength(input.getText().c_str());
if (fontLength >= textTemp.getWidth()){
font.printf(textTemp.getWidth() - modifier - fontLength, 0, textColor, textTemp, input.getText(), 0);
renderCursor(textTemp.getWidth() - modifier - 1, 0, font, textTemp);
} else {
font.printf(0, 0, textColor, textTemp, input.getText(), 0);
renderCursor(fontLength+1, 0, font, textTemp);
}
}
void LineEdit::render(const Graphics::Bitmap &){
}
void LineEdit::toggleEnabled(){
if (input.isEnabled()){
input.disable();
} else {
input.enable();
}
}
void LineEdit::setFocused(bool enabled){
if (enabled){
input.enable();
} else {
input.disable();
}
}
void LineEdit::addHook(int key, void (*callback)(void *), void * arg){
input.addBlockingHandle(key, callback, arg);
}
bool LineEdit::didChanged(unsigned long long &){
return changed;
}
void LineEdit::renderCursor(int x, int y, const Font & font, const Graphics::Bitmap & work){
if (cursorTime <= blinkRate){
font.printf(x, y, cursorColor, work, "|", 0);
}
}
diff --git a/src/gui/list.cpp b/src/gui/list.cpp
index 86733150..b99069ee 100644
--- a/src/gui/list.cpp
+++ b/src/gui/list.cpp
@@ -1,90 +1,90 @@
-#include "list.h"
+#include "r-tech1/gui/list.h"
namespace Gui{
ListItem::ListItem(){
}
ListItem::~ListItem(){
}
ListInterface::ListInterface(){
}
ListInterface::~ListInterface(){
}
void ListInterface::render(const Graphics::Bitmap &){
}
void ListInterface::render(const Graphics::Bitmap &, const Font &){
}
SimpleList::SimpleList(){
}
SimpleList::~SimpleList(){
}
void SimpleList::act(const Font &){
}
void SimpleList::draw(const Font & font, const Graphics::Bitmap & work){
Graphics::Bitmap temp = Graphics::Bitmap(work, location.getX(), location.getY(), location.getWidth(), location.getHeight());
drawBox(transforms.getRadius(), 0, 0, location.getWidth(), location.getHeight(), colors, temp);
const int modifier = (temp.getWidth() * (transforms.getRadius()*.001)) == 0 ? 2 : (temp.getWidth() * (transforms.getRadius()*.001));
int y = 2;
for (std::vector< Util::ReferenceCount<ListItem> >::iterator i = list.begin(); i != list.end(); ++i){
Graphics::Bitmap listTemp = Graphics::Bitmap(temp, modifier, y, temp.getWidth()-(modifier*2), y);
Util::ReferenceCount<ListItem> item = *i;
item->draw(font, listTemp);
y += font.getHeight()+2;
}
}
void SimpleList::add(const Util::ReferenceCount<ListItem> item){
//list.push_back(item);
// Keep list sorted
std::vector< Util::ReferenceCount<ListItem> >::iterator position = list.begin();
while (position != list.end() && (*position)->compareTo(item) < 0){
position++;
}
list.insert(position, item);
}
void SimpleList::add(const std::vector< Util::ReferenceCount<ListItem> > & more){
/*list.insert(list.end(),more.begin(),more.end());*/
for (std::vector< Util::ReferenceCount<ListItem> >::const_iterator i = more.begin(); i != more.end(); i++){
Util::ReferenceCount<ListItem> item = *i;
add(item);
}
}
void SimpleList::remove(const Util::ReferenceCount<ListItem> removable){
for (std::vector< Util::ReferenceCount<ListItem> >::iterator i = list.begin(); i != list.end(); i++){
Util::ReferenceCount<ListItem> item = *i;
if (removable->equals(item)){
list.erase(i);
return;
}
}
}
void SimpleList::replace(const std::vector< Util::ReferenceCount<ListItem> > & newList){
list = newList;
}
void SimpleList::clear(){
list.clear();
}
const std::vector< Util::ReferenceCount<ListItem> > & SimpleList::getList() const{
return list;
}
}
diff --git a/src/gui/popup-box.cpp b/src/gui/popup-box.cpp
index 43bb8892..53c9a04b 100644
--- a/src/gui/popup-box.cpp
+++ b/src/gui/popup-box.cpp
@@ -1,99 +1,99 @@
-#include "util/graphics/bitmap.h"
-#include "popup-box.h"
+#include "r-tech1/graphics/bitmap.h"
+#include "r-tech1/gui/popup-box.h"
using namespace std;
using namespace Gui;
PopupBox::PopupBox():
fadeState(Closed),
fadeSpeed(12){
}
PopupBox::PopupBox( const PopupBox & copy ):
fadeState(Closed){
this->fadeSpeed = copy.fadeSpeed;
}
PopupBox::~PopupBox(){
}
PopupBox & PopupBox::operator=( const PopupBox & copy){
this->fadeState = Closed;
this->fadeSpeed = copy.fadeSpeed;
return *this;
}
void PopupBox::act(const Font & font){
// do fade
doFade();
}
void PopupBox::render(const Graphics::Bitmap & work){
board.render(work);
}
void PopupBox::open(){
// Set the fade stuff
fadeState = FadeIn;
board.location = location;
board.transforms = transforms;
board.colors = colors;
board.location.center(location);
board.colors.borderAlpha = board.colors.bodyAlpha = 0;
}
void PopupBox::close(){
fadeState = FadeOut;
}
void PopupBox::doFade(){
switch (fadeState){
case FadeIn: {
board.location.growTo(location, 0.0025 * fadeSpeed);
if (board.colors.borderAlpha < colors.borderAlpha){
board.colors.borderAlpha += (int)(fadeSpeed/2);
if (board.colors.borderAlpha >= colors.borderAlpha){
board.colors.borderAlpha = colors.borderAlpha;
}
}
if (board.colors.bodyAlpha < colors.bodyAlpha){
board.colors.bodyAlpha += (int)(fadeSpeed/2);
if (board.colors.bodyAlpha >= colors.bodyAlpha){
board.colors.bodyAlpha = colors.bodyAlpha;
}
}
if (board.location == location && board.colors.bodyAlpha == colors.bodyAlpha && board.colors.borderAlpha == colors.borderAlpha){
fadeState = Open;
}
break;
}
case FadeOut: {
Coordinate coord;
coord.center(location);
board.location.growTo(coord, 0.0025 * fadeSpeed);
if (board.colors.borderAlpha > 0){
board.colors.borderAlpha -= (int)(fadeSpeed/2);
if (board.colors.borderAlpha <= 0){
board.colors.borderAlpha = 0;
}
}
if (board.colors.bodyAlpha > 0){
board.colors.bodyAlpha -= (int)(fadeSpeed/2);
if (board.colors.bodyAlpha <= 0){
board.colors.bodyAlpha = 0;
}
}
if (board.location.empty() && board.colors.borderAlpha == 0 && board.colors.bodyAlpha == 0){
fadeState = Closed;
}
break;
}
case Open:
case Closed:
default:
break;
}
}
diff --git a/src/gui/rectarea.cpp b/src/gui/rectarea.cpp
index cc29047c..0a6cd050 100644
--- a/src/gui/rectarea.cpp
+++ b/src/gui/rectarea.cpp
@@ -1,51 +1,51 @@
-#include "util/graphics/bitmap.h"
-#include "rectarea.h"
+#include "r-tech1/graphics/bitmap.h"
+#include "r-tech1/gui/rectarea.h"
using namespace Gui;
RectArea::RectArea():
x(0),
y(0),
width(0),
height(0),
radius(0){
}
RectArea::RectArea(int x, int y, int w, int h):
x(x),
y(y),
width(w),
height(h),
radius(0){
}
bool RectArea::empty(){
// return (x==0 && y==0 && width==0 && height==0);
return width == 0 && height == 0;
}
bool RectArea::operator==( const RectArea &rect){
return ( (x == rect.x) &&
(y == rect.y) &&
(width == rect.width) &&
(height == rect.height));
}
bool RectArea::operator!=( const RectArea &rect){
return ( (x != rect.x) ||
(y != rect.y) ||
(width != rect.width) ||
(height != rect.height));
}
bool RectArea::operator==( const Graphics::Bitmap &bmp){
return ( (width == bmp.getWidth()) &&
(height == bmp.getHeight()));
}
bool RectArea::operator!=( const Graphics::Bitmap &bmp){
return ( (width != bmp.getWidth()) ||
(height != bmp.getHeight()));
}
diff --git a/src/gui/scroll-list.cpp b/src/gui/scroll-list.cpp
index 2033bcb4..54b9392e 100644
--- a/src/gui/scroll-list.cpp
+++ b/src/gui/scroll-list.cpp
@@ -1,364 +1,364 @@
-#include "util/graphics/bitmap.h"
-#include "../funcs.h"
-#include "scroll-list.h"
-#include "../font.h"
+#include "r-tech1/graphics/bitmap.h"
+#include "r-tech1/funcs.h"
+#include "r-tech1/gui/scroll-list.h"
+#include "r-tech1/font.h"
#include <math.h>
-#include "../debug.h"
+#include "r-tech1/debug.h"
using namespace Gui;
static const double FONT_SPACER = 1.3;
// static const int GradientMax = 50;
const double EPSILON = 0.01;
/*
static int selectedGradientStart(){
static int color = Graphics::makeColor(19, 167, 168);
return color;
}
static int selectedGradientEnd(){
static int color = Graphics::makeColor(27, 237, 239);
return color;
}
*/
int justify(Justify justification, int left, int right, int size){
switch (justification){
case LeftJustify: return left;
case RightJustify: return right - size;
case CenterJustify: return (left + right) / 2 - size / 2;
}
return 0;
}
ScrollListInterface::ScrollListInterface():
allowWrap(true){
}
ScrollListInterface::~ScrollListInterface(){
}
ScrollItem::ScrollItem(){
}
ScrollItem::~ScrollItem(){
}
ScrollList::ScrollList():
currentIndex(0),
fontSpacingX(0),
fontSpacingY(0),
currentPosition(0),
scrollWait(0),
scrollWaitTime(4),
scrollMotion(1.2),
// selectedGradient(GradientMax, selectedGradientStart(), selectedGradientEnd()),
// useGradient(false),
useHighlight(false),
scroll(0),
justification(CenterJustify){}
ScrollList::ScrollList(const ScrollList & copy):
currentIndex(copy.currentIndex),
fontSpacingX(copy.fontSpacingX),
fontSpacingY(copy.fontSpacingY),
currentPosition(copy.currentPosition),
scrollWait(copy.scrollWait),
// selectedGradient(GradientMax, selectedGradientStart(), selectedGradientEnd()),
// useGradient(copy.useGradient),
useHighlight(copy.useHighlight),
scroll(0){}
ScrollList::~ScrollList(){}
ScrollList & ScrollList::operator=(const ScrollList & copy){
return *this;
}
void ScrollList::act(){
if (scrollWait == 0){
if (scroll > EPSILON){
// scroll -= SCROLL_MOTION;
scroll /= scrollMotion;
} else if (scroll < -EPSILON){
// scroll += SCROLL_MOTION;
scroll /= scrollMotion;
} else {
scroll = 0;
currentPosition = currentIndex;
}
} else {
scrollWait -= 1;
}
/*
if (scrollWait > 0){
scrollWait -= 1;
} else {
currentPosition = currentIndex;
}
*/
}
/* this is the smooth scroll stuff from context-box */
void ScrollList::doDraw(int x, int y, int min_y, int max_y, const Font & font, int current, int selected, const Graphics::Bitmap & area, int direction) const {
/* sanity check */
if (text.size() == 0){
return;
}
while (y < max_y && y > min_y){
/* circuluar */
int pick = current;
while (pick < 0){
pick += text.size();
}
pick = pick % text.size();
Util::ReferenceCount<ScrollItem> option = text[pick];
/* center justification */
const int startx = justify(justification, 1, area.getWidth() - 1, option->size(font));
/* the selected option will have a distance of 0 */
int distance = current - selected;
option->draw(x + startx, y, area, font, distance);
if (text.size() == 1){
return;
}
current += direction;
y += direction * font.getHeight() / FONT_SPACER;
}
}
void ScrollList::render(const Graphics::Bitmap & where, const Font & font) const {
/* middle of the bitmap offset by the scroll amount. */
int y = where.getHeight() / 2 + scroll * font.getHeight() / 2 - font.getHeight() / 2;
/* allow options to be drawn a little off the bitmap */
int min_y = 0 - font.getHeight() / FONT_SPACER;
int max_y = where.getHeight();
/* draw down starting from the current selection */
doDraw(0, y, min_y, max_y, font, currentIndex, currentIndex, where, 1);
/* then draw up, skipping the current selection */
doDraw(0, y - font.getHeight() / FONT_SPACER, min_y, max_y, font, (int) currentIndex - 1, currentIndex, where, -1);
}
void ScrollList::addItem(const Util::ReferenceCount<ScrollItem> item){
this->text.push_back(item);
}
void ScrollList::addItems(const std::vector<Util::ReferenceCount<ScrollItem> > & texts){
this->text.insert(text.end(), texts.begin(), texts.end());
}
const std::vector<Util::ReferenceCount<ScrollItem> > & ScrollList::getItems() const{
return this->text;
}
void ScrollList::clearItems(){
this->text.clear();
}
void ScrollList::setPosition(const Gui::Coordinate & location){
this->position = location;
}
bool ScrollList::next(){
/* FIXME: probably if the current index goes past the boundary we shouldn't scroll */
currentIndex++;
scroll = 1;
if (scrollWait == 0){
scrollWait = scrollWaitTime;
}
if (currentIndex >= text.size()){
if (allowWrap){
currentIndex = 0;
return true;
} else {
currentIndex = text.size()-1;
return false;
}
}
return true;
}
bool ScrollList::previous(){
scroll = -1;
if (scrollWait == 0){
scrollWait = scrollWaitTime;
}
if (currentIndex > 0){
currentIndex--;
} else if (currentIndex == 0){
if (allowWrap){
currentIndex = text.size()-1;
return true;
} else {
return false;
}
}
return true;
}
bool ScrollList::setCurrentIndex(unsigned int index){
if (index >= text.size()){
return false;
}
currentIndex = index;
return true;
}
NormalList::NormalList():
position(0),
endPosition(0),
first(-1),
last(-1),
justification(CenterJustify),
fontHeight(0),
moveToX(0),
moveToY(0),
currentX(0),
currentY(0),
fontBeginOffsetX(0),
fontBeginOffsetY(0),
fontSpaceX(0),
fontSpaceY(0),
visibleItems(0){
}
NormalList::~NormalList(){
}
void NormalList::act(){
/* FIXME smooth scrolling needed (location/current?) */
const int speed = fontHeight/2;
if (currentY < moveToY){
currentY += speed;
if (currentY > moveToY){
currentY = moveToY;
}
} else if (currentY > moveToY){
currentY -= speed;
if (currentY < moveToY){
currentY = moveToY;
}
}
}
void NormalList::render(const Graphics::Bitmap & work, const Font & font) const {
/* FIXME
* - Get spacing somewhere else, for now update it here
* - Get visible items properly elsewhere */
fontHeight = (font.getHeight() / FONT_SPACER) + fontSpaceY;
visibleItems = (work.getHeight() / fontHeight);
if (first == -1){
first = 0;
last = Util::min(visibleItems, text.size());
}
if (position < first){
int difference = first - position;
first = 0;
last -= difference;
}
if (position > last){
int difference = position - last;
last = position;
first += difference;
}
first = 0;
last = text.size();
double y = currentY;
for (int index = first; index < last; index += 1){
int distance = position - index;
Util::ReferenceCount<ScrollItem> option = text[index];
const int x = justify(justification, 1, work.getWidth() - 1, option->size(font));
option->draw(x, y, work, font, distance);
y += fontHeight;
}
}
void NormalList::addItem(const Util::ReferenceCount<ScrollItem> item){
text.push_back(item);
}
void NormalList::addItems(const std::vector<Util::ReferenceCount<ScrollItem> > & texts){
this->text.insert(text.end(), texts.begin(), texts.end());
}
const std::vector<Util::ReferenceCount<ScrollItem> > & NormalList::getItems() const{
return this->text;
}
void NormalList::clearItems(){
this->text.clear();
}
unsigned int NormalList::getCurrentIndex() const {
return position;
}
bool NormalList::next(){
// First move forward check if endpostition has been set
checkEndPosition();
if ((unsigned int)position < text.size() - 1){
position += 1;
if (allItemsViewable()){
if (position > endPosition){
moveToY-=fontHeight;
endPosition++;
}
}
return true;
} else {
if (allowWrap){
position = 0;
if (allItemsViewable()){
endPosition = visibleItems-1;
moveToY = 0;
}
return false;
}
}
return false;
}
bool NormalList::previous(){
if (position > 0){
position -= 1;
if (allItemsViewable()){
if (position < (endPosition - visibleItems+1)){
moveToY+=fontHeight;
endPosition--;
}
}
return true;
} else {
if (allowWrap){
position = text.size()-1;
if (allItemsViewable()){
endPosition = position;
moveToY = ((position - visibleItems+1) * fontHeight) * -1;
}
return false;
}
}
return false;
}
void NormalList::checkEndPosition(){
if (endPosition == 0){
endPosition = visibleItems-1;
}
}
bool NormalList::allItemsViewable(){
return ((unsigned int)visibleItems < text.size());
}
diff --git a/src/gui/select-list.cpp b/src/gui/select-list.cpp
index 9b17c45a..d170fd63 100644
--- a/src/gui/select-list.cpp
+++ b/src/gui/select-list.cpp
@@ -1,1095 +1,1095 @@
-#include "select-list.h"
+#include "r-tech1/gui/select-list.h"
-#include "util/graphics/bitmap.h"
-#include "util/font.h"
-#include "util/debug.h"
+#include "r-tech1/graphics/bitmap.h"
+#include "r-tech1/font.h"
+#include "r-tech1/debug.h"
#include <math.h>
using namespace Gui;
SelectItem::SelectItem(){
}
SelectItem::~SelectItem(){
}
SelectListInterface::SelectListInterface():
accessEmpty(true),
drawEmpty(false),
allowWrap(true){
}
SelectListInterface::~SelectListInterface(){
}
Cursor::Cursor(unsigned int index, const SelectListInterface::CursorState & state):
index(index),
state(state){
}
Cursor::~Cursor(){
}
Cursor::Cursor(const Cursor & cursor):
index(cursor.index),
state(cursor.state){
}
const Cursor & Cursor::operator=(const Cursor & copy){
this->index = copy.index;
this->state = copy.state;
return *this;
}
void Cursor::setIndex(unsigned int index){
this->index = index;
}
unsigned int Cursor::getIndex() const{
return index;
}
void Cursor::increment(){
index++;
}
void Cursor::decrement(){
if (index > 0){
index--;
}
}
void Cursor::setState(const SelectListInterface::CursorState & state){
this->state = state;
}
const SelectListInterface::CursorState & Cursor::getState() const{
return state;
}
SimpleSelect::SimpleSelect():
layout(Horizontal),
viewable(3),
currentTop(0),
scrollOffset(0),
cellWidth(100),
cellHeight(100),
cellSpacingX(0),
cellSpacingY(0),
cellMarginX(0),
cellMarginY(0),
startOffsetX(0),
startOffsetY(0){
}
SimpleSelect::~SimpleSelect(){
}
void SimpleSelect::act(){
/* Check if viewable is larger than the current items */
if (viewable >= items.size()){
viewable = items.size()-1;
}
}
void SimpleSelect::getDrawLocation(const Util::ReferenceCount<SelectItem> & item, int * x, int * y) const {
/* TODO */
*x = 0;
*y = 0;
}
void SimpleSelect::render(const Graphics::Bitmap & work, const Font & font) const{
int x = startOffsetX + cellMarginX;
int y = startOffsetY + cellMarginY;
const int stop = currentTop + viewable;
int count = currentTop;
for (std::vector<Util::ReferenceCount<SelectItem> >::const_iterator i = items.begin() + currentTop; i != items.end() && count != stop; ++i, ++count){
const Util::ReferenceCount<SelectItem> item = *i;
if (item->isEmpty()){
if (drawEmpty){
item->draw(x, y, cellWidth, cellHeight, work, font);
}
} else {
item->draw(x, y, cellWidth, cellHeight, work, font);
}
x+=cellSpacingX + (layout == Horizontal ? cellWidth + cellMarginX : 0);
y+=cellSpacingY + (layout == Vertical ? cellHeight + cellMarginY : 0);
}
}
void SimpleSelect::addItem(const Util::ReferenceCount<SelectItem> & item){
items.push_back(item);
}
void SimpleSelect::addItems(const std::vector<Util::ReferenceCount<SelectItem> > & itemList){
items.insert(items.begin(), itemList.begin(), itemList.end());
}
const std::vector<Util::ReferenceCount<SelectItem> > & SimpleSelect::getItems() const{
return items;
}
const Util::ReferenceCount<SelectItem> SimpleSelect::getItem(unsigned int index) const{
if (index >= items.size()){
return Util::ReferenceCount<SelectItem>();
}
return items[index];
}
const Util::ReferenceCount<SelectItem> SimpleSelect::getItemByCursor(unsigned int cursor) const{
if (getCurrentIndex(cursor) >= items.size()){
return Util::ReferenceCount<SelectItem>();
}
return items[getCurrentIndex(cursor)];
}
void SimpleSelect::clearItems(){
items.clear();
}
void SimpleSelect::setCellDimensions(int width, int height){
cellWidth = width;
cellHeight = height;
}
void SimpleSelect::setCellSpacing(int x, int y){
cellSpacingX = x;
cellSpacingY = y;
}
void SimpleSelect::setCellMargins(int x, int y){
cellMarginX = x;
cellMarginY = y;
}
void SimpleSelect::setStartingOffset(int x, int y){
startOffsetX = x;
startOffsetY = y;
}
void SimpleSelect::setCursors(int total){
cursors.clear();
for (int i = 0; i < total; ++i){
cursors.push_back(Cursor(i, SelectListInterface::Active));
}
}
int SimpleSelect::totalCursors() const{
return cursors.size();
}
void SimpleSelect::setCurrentIndex(unsigned int cursor, unsigned int location){
if (checkCursor(cursor) && location >= items.size()){
return;
}
cursors[cursor].setIndex(location);
}
unsigned int SimpleSelect::getCurrentIndex(unsigned int cursor) const{
if (checkCursor(cursor)){
return 0;
}
return cursors[cursor].getIndex();
}
void SimpleSelect::setCurrentState(unsigned int cursor, const SelectListInterface::CursorState & state){
if (checkCursor(cursor)){
return;
}
cursors[cursor].setState(state);
}
const SelectListInterface::CursorState SimpleSelect::getCurrentState(unsigned int cursor) const{
if (checkCursor(cursor)){
return Invalid;
}
return cursors[cursor].getState();
}
/* NOTE This doesn't account for other cursors and viewable areas */
bool SimpleSelect::up(unsigned int cursor){
if (checkCursor(cursor)){
return false;
}
if (cursors[cursor].getIndex() > 0){
cursors[cursor].decrement();
calculateLeft(cursor);
return true;
} else if (allowWrap){
cursors[cursor].setIndex(items.size()-1);
currentTop = cursors[cursor].getIndex() - viewable+1;
return true;
}
return false;
}
bool SimpleSelect::down(unsigned int cursor){
if (checkCursor(cursor)){
return false;
}
if (cursors[cursor].getIndex() < items.size()-1){
cursors[cursor].increment();
calculateRight(cursor);
return true;
} else if (allowWrap){
cursors[cursor].setIndex(0);
currentTop = 0;
return true;
}
return false;
}
bool SimpleSelect::left(unsigned int cursor){
if (checkCursor(cursor)){
return false;
}
if (cursors[cursor].getIndex() > 0){
cursors[cursor].decrement();
calculateLeft(cursor);
return true;
} else if (allowWrap){
cursors[cursor].setIndex(items.size()-1);
currentTop = cursors[cursor].getIndex() - viewable + 1;
return true;
}
return false;
}
bool SimpleSelect::right(unsigned int cursor){
if (checkCursor(cursor)){
return false;
}
if (cursors[cursor].getIndex() < items.size()-1){
cursors[cursor].increment();
calculateRight(cursor);
return true;
} else if (allowWrap){
cursors[cursor].setIndex(0);
currentTop = 0;
return true;
}
return false;
}
bool SimpleSelect::hasMoreLow() const{
return (currentTop > 0);
}
bool SimpleSelect::hasMoreHigh() const{
return ((currentTop + viewable) < items.size());
}
int SimpleSelect::getWidth(){
int x = startOffsetX + cellMarginX;
const int stop = currentTop + viewable;
int count = currentTop;
for (std::vector<Util::ReferenceCount<SelectItem> >::const_iterator i = items.begin() + currentTop; i != items.end() && count != stop; ++i, ++count){
x+=cellSpacingX + (layout == Horizontal ? cellWidth + cellMarginX : 0);
}
x+=cellSpacingX + (layout == Horizontal ? cellWidth + cellMarginX : 0);
return x;
}
int SimpleSelect::getHeight(){
int y = startOffsetY + cellMarginY;
const int stop = currentTop + viewable;
int count = currentTop;
for (std::vector<Util::ReferenceCount<SelectItem> >::const_iterator i = items.begin() + currentTop; i != items.end() && count != stop; ++i, ++count){
y+=cellSpacingY + (layout == Vertical ? cellHeight + cellMarginY : 0);
}
y+=cellSpacingY + (layout == Vertical ? cellHeight + cellMarginY : 0);
return y;
}
bool SimpleSelect::checkCursor(unsigned int cursor) const {
return ((unsigned int)cursor >= cursors.size());
}
void SimpleSelect::calculateLeft(unsigned int cursor){
if (currentTop == 0){
//currentTop = cursors[cursor];
} else if (cursors[cursor].getIndex() < currentTop + scrollOffset){
currentTop = cursors[cursor].getIndex() - scrollOffset;
}
}
void SimpleSelect::calculateRight(unsigned int cursor){
const unsigned int view = viewable-1;
if ((currentTop + view) == items.size()-1){
//currentTop = right;
} else if (cursors[cursor].getIndex() >= (currentTop + view - scrollOffset)){
currentTop = cursors[cursor].getIndex() - view + scrollOffset;
}
}
GridSelect::GridSelect():
layout(Static),
gridX(0),
gridY(0),
cellWidth(100),
cellHeight(100),
cellSpacingX(0),
cellSpacingY(0),
cellMarginX(0),
cellMarginY(0),
startOffsetX(0),
startOffsetY(0),
offset(0){
}
GridSelect::~GridSelect(){
}
void GridSelect::act(){
}
void GridSelect::getDrawLocation(const Util::ReferenceCount<SelectItem> & find, int * findX, int * findY) const {
/* FIXME: this code is a direct copy/paste of render. share some code */
std::vector<Util::ReferenceCount<SelectItem> >::const_iterator item_iterator = items.begin();
switch (layout){
case Static:{
int x = startOffsetX + (cellSpacingX * gridY < 0 ? abs(cellSpacingX * gridY) : 0);
int y = startOffsetY + (cellSpacingY * gridX < 0 ? abs(cellSpacingY * gridX) : 0);
for (int row = 0; row < gridY; ++row){
int x_spacing_mod = x;
int y_spacing_mod = y;
for (int column = 0; column < gridX; ++column){
if (item_iterator != items.end()){
Util::ReferenceCount<SelectItem> item = *item_iterator;
if (item == find){
*findX = x_spacing_mod;
*findY = y_spacing_mod;
return;
}
item_iterator++;
}
x_spacing_mod+= cellSpacingX + cellWidth + cellMarginX;
y_spacing_mod+= cellSpacingY;
}
x+= cellSpacingX;
y+= cellHeight + cellMarginY;
}
break;
}
case InfiniteHorizontal:{
int x = startOffsetX + (cellSpacingX * gridY < 0 ? abs(cellSpacingX * gridY) : 0);
int y = startOffsetY + (cellSpacingY * gridX < 0 ? abs(cellSpacingY * gridX) : 0);
// Start off on offset
item_iterator += offset * gridY;
for (int column = 0; column < gridX; ++column){
int x_spacing_mod = x;
int y_spacing_mod = y;
for (int row = 0; row < gridY; ++row){
if (item_iterator != items.end()){
Util::ReferenceCount<SelectItem> item = *item_iterator;
if (item == find){
*findX = x_spacing_mod;
*findY = y_spacing_mod;
return;
}
item_iterator++;
}
x_spacing_mod+= cellSpacingX;
y_spacing_mod+= cellSpacingY + cellHeight + cellMarginY;
}
x+= cellWidth + cellMarginX;
y+= cellSpacingY;
}
break;
}
case InfiniteVertical:{
int x = startOffsetX + (cellSpacingX * gridY < 0 ? abs(cellSpacingX * gridY) : 0);
int y = startOffsetY + (cellSpacingY * gridX < 0 ? abs(cellSpacingY * gridX) : 0);
// Start off on offset
item_iterator += offset * gridX;
for (int row = 0; row < gridY; ++row){
int x_spacing_mod = x;
int y_spacing_mod = y;
for (int column = 0; column < gridX; ++column){
if (item_iterator != items.end()){
Util::ReferenceCount<SelectItem> item = *item_iterator;
if (item == find){
*findX = x_spacing_mod;
*findY = y_spacing_mod;
return;
}
item_iterator++;
}
x_spacing_mod+=cellSpacingX + cellWidth + cellMarginX;
y_spacing_mod+=cellSpacingY;
}
x+= cellSpacingX;
y+= cellHeight + cellMarginY;
}
break;
}
default:
break;
}
}
void GridSelect::render(const Graphics::Bitmap & where, const Font & font) const {
std::vector<Util::ReferenceCount<SelectItem> >::const_iterator item_iterator = items.begin();
switch (layout){
case Static:{
int x = startOffsetX + (cellSpacingX * gridY < 0 ? abs(cellSpacingX * gridY) : 0);
int y = startOffsetY + (cellSpacingY * gridX < 0 ? abs(cellSpacingY * gridX) : 0);
for (int row = 0; row < gridY; ++row){
int x_spacing_mod = x;
int y_spacing_mod = y;
for (int column = 0; column < gridX; ++column){
if (item_iterator != items.end()){
Util::ReferenceCount<SelectItem> item = *item_iterator;
if (item->isEmpty()){
if (drawEmpty){
item->draw(x_spacing_mod, y_spacing_mod, cellWidth, cellHeight, where, font);
}
} else {
item->draw(x_spacing_mod, y_spacing_mod, cellWidth, cellHeight, where, font);
}
item_iterator++;
}
x_spacing_mod+= cellSpacingX + cellWidth + cellMarginX;
y_spacing_mod+= cellSpacingY;
}
x+= cellSpacingX;
y+= cellHeight + cellMarginY;
}
break;
}
case InfiniteHorizontal:{
int x = startOffsetX + (cellSpacingX * gridY < 0 ? abs(cellSpacingX * gridY) : 0);
int y = startOffsetY + (cellSpacingY * gridX < 0 ? abs(cellSpacingY * gridX) : 0);
// Start off on offset
item_iterator += offset * gridY;
for (int column = 0; column < gridX; ++column){
int x_spacing_mod = x;
int y_spacing_mod = y;
for (int row = 0; row < gridY; ++row){
if (item_iterator != items.end()){
Util::ReferenceCount<SelectItem> item = *item_iterator;
if (item->isEmpty()){
if (drawEmpty){
item->draw(x_spacing_mod, y_spacing_mod, cellWidth, cellHeight, where, font);
}
} else {
item->draw(x_spacing_mod, y_spacing_mod, cellWidth, cellHeight, where, font);
}
item_iterator++;
}
x_spacing_mod+= cellSpacingX;
y_spacing_mod+= cellSpacingY + cellHeight + cellMarginY;
}
x+= cellWidth + cellMarginX;
y+= cellSpacingY;
}
break;
}
case InfiniteVertical:{
int x = startOffsetX + (cellSpacingX * gridY < 0 ? abs(cellSpacingX * gridY) : 0);
int y = startOffsetY + (cellSpacingY * gridX < 0 ? abs(cellSpacingY * gridX) : 0);
// Start off on offset
item_iterator += offset * gridX;
for (int row = 0; row < gridY; ++row){
int x_spacing_mod = x;
int y_spacing_mod = y;
for (int column = 0; column < gridX; ++column){
if (item_iterator != items.end()){
Util::ReferenceCount<SelectItem> item = *item_iterator;
if (item->isEmpty()){
if (drawEmpty){
item->draw(x_spacing_mod, y_spacing_mod, cellWidth, cellHeight, where, font);
}
} else {
item->draw(x_spacing_mod, y_spacing_mod, cellWidth, cellHeight, where, font);
}
item_iterator++;
}
x_spacing_mod += cellSpacingX + cellWidth + cellMarginX;
y_spacing_mod += cellSpacingY;
}
x += cellSpacingX;
y += cellHeight + cellMarginY;
}
break;
}
default:
break;
}
}
void GridSelect::addItem(const Util::ReferenceCount<SelectItem> & item){
items.push_back(item);
}
void GridSelect::addItems(const std::vector<Util::ReferenceCount<SelectItem> > & itemList){
items.insert(items.begin(), itemList.begin(), itemList.end());
}
const std::vector<Util::ReferenceCount<SelectItem> > & GridSelect::getItems() const{
return items;
}
const Util::ReferenceCount<SelectItem> GridSelect::getItem(unsigned int index) const{
if (index >= items.size()){
return Util::ReferenceCount<SelectItem>();
}
return items[index];
}
const Util::ReferenceCount<SelectItem> GridSelect::getItemByCursor(unsigned int cursor) const{
if (getCurrentIndex(cursor) >= items.size()){
return Util::ReferenceCount<SelectItem>();
}
return items[getCurrentIndex(cursor)];
}
void GridSelect::clearItems(){
items.clear();
}
void GridSelect::setCellDimensions(int width, int height){
cellWidth = width;
cellHeight = height;
}
void GridSelect::setCellSpacing(int x, int y){
cellSpacingX = x;
cellSpacingY = y;
}
void GridSelect::setCellMargins(int x, int y){
cellMarginX = x;
cellMarginY = y;
}
void GridSelect::setStartingOffset(int x, int y){
startOffsetX = x;
startOffsetY = y;
}
void GridSelect::setCursors(int total){
cursors.clear();
for (int i = 0; i < total; ++i){
cursors.push_back(Cursor(i, SelectListInterface::Active));
}
}
int GridSelect::totalCursors() const{
return cursors.size();
}
void GridSelect::setCurrentIndex(unsigned int cursor, unsigned int location){
if (checkCursor(cursor) && location >= items.size()){
return;
}
cursors[cursor].setIndex(location);
}
unsigned int GridSelect::getCurrentIndex(unsigned int cursor) const{
if (checkCursor(cursor)){
return 0;
}
return cursors[cursor].getIndex();
}
void GridSelect::setCurrentState(unsigned int cursor, const SelectListInterface::CursorState & state){
if (checkCursor(cursor)){
return;
}
cursors[cursor].setState(state);
}
const SelectListInterface::CursorState GridSelect::getCurrentState(unsigned int cursor) const{
if (checkCursor(cursor)){
return Invalid;
}
return cursors[cursor].getState();
}
static bool inRange(int check, int start, int end){
return (check >= start && check <= end);
}
static bool endPoint(int check, int start, int end, int increment){
for (int i = start; i <= end; i+=increment){
if (check == i){
return true;
}
}
return false;
}
static int computeOffset(int location, int width, int height){
int large = 0;
int small = 0;
if (width == height){
large = small = width;
} else if (width > height){
small = width;
large = height;
} else if (width < height){
small = height;
large = width;
}
int offset = (location/large - small) + 1;
if (offset < 0){
return 0;
}
return offset;
}
bool GridSelect::moveUp(unsigned int cursor){
switch (layout){
case Static:{
if (inRange(cursors[cursor].getIndex(), 0, gridX-1)){
if (allowWrap){
unsigned int location = (gridX * (gridY-1)) + cursors[cursor].getIndex();
if (location >= items.size()){
location = items.size()-1;
}
cursors[cursor].setIndex(location);
/*
if (!items[location]->isEmpty() || (items[location]->isEmpty() && accessEmpty)){
cursors[cursor].setIndex(location);
return true;
} else {
return false;
}
*/
} else {
return false;
}
} else {
unsigned int location = cursors[cursor].getIndex() - gridX;
cursors[cursor].setIndex(location);
/*
if (!items[location]->isEmpty() || (items[location]->isEmpty() && accessEmpty)){
cursors[cursor].setIndex(location);
return true;
} else {
return false;
}
*/
}
break;
}
case InfiniteHorizontal:{
int location = cursors[cursor].getIndex();
location--;
if (location < 0){
if (allowWrap){
location = items.size()-1;
offset = computeOffset(location, gridX, gridY);
} else {
location = 0;
}
} else {
if ((unsigned int)location < offset * gridY){
offset--;
}
}
cursors[cursor].setIndex(location);
break;
}
case InfiniteVertical:{
int location = cursors[cursor].getIndex();
location-=gridX;
if (location < 0){
if (allowWrap){
location = items.size()-1;
offset = computeOffset(location, gridX, gridY);
} else {
location = cursors[cursor].getIndex();
}
} else {
if ((unsigned int)location < offset * gridX){
offset--;
}
}
cursors[cursor].setIndex(location);
break;
}
default:
break;
}
return true;
}
bool GridSelect::up(unsigned int cursor){
if (checkCursor(cursor)){
return false;
}
int place = cursors[cursor].getIndex();
bool ok = moveUp(cursor);
if (!ok){
return ok;
}
if (!accessEmpty && getItemByCursor(cursor)->isEmpty()){
while (ok && getItemByCursor(cursor)->isEmpty() && place != cursors[cursor].getIndex()){
ok = moveUp(cursor);
}
}
/* We tried to move but failed and wrapping doesn't work, so the only alternative
* is to revert to our original place.
*/
if (!ok && !allowWrap){
cursors[cursor].setIndex(place);
}
return ok;
}
bool GridSelect::moveDown(unsigned int cursor){
switch (layout){
case Static:{
if (inRange(cursors[cursor].getIndex(), gridX * (gridY-1), gridX * gridY)){
if (allowWrap){
unsigned int location = cursors[cursor].getIndex() - (gridX * (gridY-1));
cursors[cursor].setIndex(location);
/*
if (!items[location]->isEmpty() || (items[location]->isEmpty() && accessEmpty)){
cursors[cursor].setIndex(location);
return true;
} else {
return false;
}
*/
} else {
return false;
}
} else {
unsigned int location = cursors[cursor].getIndex() + gridX;
if (location >= items.size()){
location = items.size()-1;
}
cursors[cursor].setIndex(location);
/*
if (!items[location]->isEmpty() || (items[location]->isEmpty() && accessEmpty)){
cursors[cursor].setIndex(location);
return true;
} else {
return false;
}
*/
}
break;
}
case InfiniteHorizontal:{
int location = cursors[cursor].getIndex();
location++;
if ((unsigned int)location >= items.size()){
if (allowWrap){
location = offset = 0;
}
} else {
if ((unsigned int)location > ((offset+gridX) * gridY)-1){
offset++;
}
}
cursors[cursor].setIndex(location);
break;
}
case InfiniteVertical:{
int location = cursors[cursor].getIndex();
location+=gridX;
if ((unsigned int)location >= items.size()){
if (cursors[cursor].getIndex() < items.size()-1){
location = items.size()-1;
offset = computeOffset(location, gridX, gridY);
} else if (allowWrap){
location = offset = 0;
}
} else {
if ((unsigned int)location > ((offset+gridY) * gridX)-1){
offset++;
}
}
cursors[cursor].setIndex(location);
break;
}
default:
break;
}
return true;
}
bool GridSelect::down(unsigned int cursor){
if (checkCursor(cursor)){
return false;
}
int place = cursors[cursor].getIndex();
bool ok = moveDown(cursor);
if (!ok){
return ok;
}
if (!accessEmpty && getItemByCursor(cursor)->isEmpty()){
while (ok && getItemByCursor(cursor)->isEmpty() && place != cursors[cursor].getIndex()){
ok = moveDown(cursor);
}
}
if (!ok && !allowWrap){
cursors[cursor].setIndex(place);
}
return ok;
}
bool GridSelect::moveLeft(unsigned int cursor){
switch (layout){
case Static:{
if (endPoint(cursors[cursor].getIndex(), 0, gridX * gridY, gridX)){
if (allowWrap){
unsigned int location = cursors[cursor].getIndex() + gridX-1;
if (location >= items.size()){
location = items.size()-1;
}
cursors[cursor].setIndex(location);
/*
if (!items[location]->isEmpty() || (items[location]->isEmpty() && accessEmpty)){
cursors[cursor].setIndex(location);
return true;
} else {
return false;
}
*/
} else {
return false;
}
} else {
/* FIXME: I think this is wrong.. */
cursors[cursor].decrement();
/*
if (items[cursors[cursor].getIndex()]->isEmpty() && !accessEmpty){
cursors[cursor].increment();
return false;
}
return true;
*/
}
break;
}
case InfiniteHorizontal:{
int location = cursors[cursor].getIndex();
location-=gridY;
if (location < 0){
if (allowWrap){
location = items.size()-1;
offset = computeOffset(location, gridX, gridY);
} else {
location = cursors[cursor].getIndex();
}
} else {
if ((unsigned int)location < offset * gridY){
offset--;
}
}
cursors[cursor].setIndex(location);
break;
}
case InfiniteVertical:{
int location = cursors[cursor].getIndex();
location--;
if (location < 0){
if (allowWrap){
location = items.size()-1;
offset = computeOffset(location, gridX, gridY);
} else {
location = 0;
}
} else {
if ((unsigned int)location < offset * gridX){
offset--;
}
}
cursors[cursor].setIndex(location);
break;
}
default:
break;
}
return true;
}
bool GridSelect::left(unsigned int cursor){
if (checkCursor(cursor)){
return false;
}
int place = cursors[cursor].getIndex();
bool ok = moveLeft(cursor);
if (!ok){
return ok;
}
if (!accessEmpty && getItemByCursor(cursor)->isEmpty()){
while (ok && getItemByCursor(cursor)->isEmpty() && place != cursors[cursor].getIndex()){
ok = moveLeft(cursor);
}
}
if (!ok && !allowWrap){
cursors[cursor].setIndex(place);
}
return ok;
}
bool GridSelect::moveRight(unsigned int cursor){
switch (layout){
case Static:{
if (endPoint(cursors[cursor].getIndex(), gridX-1, gridX * gridY, gridX)){
if (allowWrap){
int location = cursors[cursor].getIndex() - gridX+1;
if (location < 0){
location = 0;
}
cursors[cursor].setIndex(location);
/*
if (!items[location]->isEmpty() || (items[location]->isEmpty() && accessEmpty)){
cursors[cursor].setIndex(location);
return true;
} else {
return false;
}
*/
} else {
return false;
}
} else {
unsigned int location = cursors[cursor].getIndex()+1;
if (location >= items.size()){
if (allowWrap){
location = (gridX * gridY) - gridX;
} else {
location = items.size()-1;
}
}
cursors[cursor].setIndex(location);
/*
if (!items[location]->isEmpty() || (items[location]->isEmpty() && accessEmpty)){
cursors[cursor].setIndex(location);
return true;
} else {
return false;
}
*/
}
break;
}
case InfiniteHorizontal:{
int location = cursors[cursor].getIndex();
location+=gridY;
if ((unsigned int)location >= items.size()){
if (cursors[cursor].getIndex() < items.size()-1){
location = items.size()-1;
offset = computeOffset(location, gridX, gridY);
} else if (allowWrap){
location = offset = 0;
}
} else {
if ((unsigned int)location > ((offset+gridX) * gridY)-1){
offset++;
}
}
cursors[cursor].setIndex(location);
break;
}
case InfiniteVertical:{
int location = cursors[cursor].getIndex();
location++;
if ((unsigned int)location >= items.size()){
if (allowWrap){
location = offset = 0;
}
} else {
if ((unsigned int)location > ((offset+gridY) * gridX)-1){
offset++;
}
}
cursors[cursor].setIndex(location);
break;
}
default:
break;
}
return true;
}
bool GridSelect::right(unsigned int cursor){
if (checkCursor(cursor)){
return false;
}
int place = cursors[cursor].getIndex();
bool ok = moveRight(cursor);
if (!ok){
return ok;
}
if (!accessEmpty && getItemByCursor(cursor)->isEmpty()){
while (ok && getItemByCursor(cursor)->isEmpty() && place != cursors[cursor].getIndex()){
ok = moveRight(cursor);
}
}
if (!ok && !allowWrap){
cursors[cursor].setIndex(place);
}
return ok;
}
bool GridSelect::hasMoreLow() const{
return (offset > 0);
}
bool GridSelect::hasMoreHigh() const{
if (!cursors.empty()){
switch (layout){
case InfiniteHorizontal:{
const unsigned int location = (offset * gridY) + (gridX * gridY);
if (location < items.size() && location > ((offset+gridX) * gridY)-1){
return true;
}
break;
}
case InfiniteVertical:{
const unsigned int location = (offset * gridX) + (gridX * gridY);
if (location < items.size() && location > ((offset+gridY) * gridX)-1){
return true;
}
break;
}
case Static:
default:
break;
}
}
return false;
}
int GridSelect::getWidth(){
return (cellWidth+cellMarginX+cellSpacingX) * gridX;
}
int GridSelect::getHeight(){
return (cellHeight+cellMarginY+cellSpacingY) * gridY;
}
bool GridSelect::checkCursor(unsigned int cursor) const {
return ((unsigned int)cursor >= cursors.size());
}
diff --git a/src/gui/tab-container.cpp b/src/gui/tab-container.cpp
index 591f9aaf..6c4be790 100644
--- a/src/gui/tab-container.cpp
+++ b/src/gui/tab-container.cpp
@@ -1,228 +1,228 @@
-#include "tab-container.h"
+#include "r-tech1/gui/tab-container.h"
-#include "util/font.h"
-#include "util/debug.h"
+#include "r-tech1/font.h"
+#include "r-tech1/debug.h"
#include <stdexcept>
#include <sstream>
namespace Gui{
TabItem::TabItem():
active(false){
}
TabItem::TabItem(const std::string & name):
active(false),
name(name){
}
TabItem::~TabItem(){
}
void TabItem::inspectBody(const Graphics::Bitmap &){
}
DummyTab::DummyTab(const std::string & name):
TabItem(name){
}
DummyTab::~DummyTab(){
}
void DummyTab::act(const Font &){
}
void DummyTab::draw(const Font &, const Graphics::Bitmap & work){
work.fill(Graphics::makeColor(220, 220, 220));
}
TabContainer::TabContainer():
current(0),
body(640,480){
}
TabContainer::TabContainer(const TabContainer & copy):
tabs(copy.tabs),
current(copy.current),
body(copy.body){
}
TabContainer::~TabContainer(){
}
TabContainer & TabContainer::operator=(const TabContainer & copy){
tabs = copy.tabs;
current = copy.current;
body = copy.body;
return *this;
}
void TabContainer::act(const Font & font){
for (std::vector< Util::ReferenceCount<TabItem> >::iterator i = tabs.begin(); i != tabs.end(); ++i){
Util::ReferenceCount<TabItem> tab = *i;
tab->inspectBody(body);
tab->act(font);
}
}
void TabContainer::render(const Graphics::Bitmap &){
}
void TabContainer::draw(const Font & font, const Graphics::Bitmap & work){
const int tabHeight = font.getHeight();
const int height = location.getHeight() - tabHeight+1;
// Draw tabs
drawTabs(font, Graphics::Bitmap(work, location.getX(), location.getY(), location.getWidth(), tabHeight+1));
// Draw body
Graphics::Bitmap area(work, location.getX(), location.getY() + tabHeight+1, location.getWidth(), height);
drawBox(transforms.getRadius(), 0, -(tabHeight+1), location.getWidth(), height, colors, area);
// Draw body content
const int modifier = (area.getWidth() * (transforms.getRadius()*.001)) == 0 ? 2 : area.getWidth() * (transforms.getRadius()*.001);
body.drawStretched(modifier, modifier, area.getWidth() - modifier*2, area.getHeight() - modifier*2, area);
}
void TabContainer::add(Util::ReferenceCount<TabItem> tab){
tabs.push_back(tab);
if (tabs.size() == 1){
tab->toggleActive();
}
}
Util::ReferenceCount<TabItem> TabContainer::remove(unsigned int index){
try {
// Check
Util::ReferenceCount<TabItem> tab = tabs.at(index);
tabs.erase(tabs.begin() + index);
return tab;
} catch (const std::out_of_range & ex){
throw new TabContainer::NoSuchTab(index);
}
}
void TabContainer::removeCurrent(){
tabs.erase(tabs.begin() + current);
if (current > 0){
current--;
}
}
void TabContainer::setBodySize(int width, int height){
if (body.getWidth() == width && body.getHeight() == height){
return;
}
body = Graphics::Bitmap(width, height);
}
void TabContainer::next(){
tabs[current]->toggleActive();
current = (current + 1) % tabs.size();
tabs[current]->toggleActive();
}
void TabContainer::previous(){
tabs[current]->toggleActive();
if (current == 0){
current = tabs.size()-1;
} else {
current--;
}
tabs[current]->toggleActive();
}
void TabContainer::gotoTab(unsigned int index){
try {
// Check
Util::ReferenceCount<TabItem> tab = tabs.at(index);
tabs[current]->toggleActive();
current = index;
tabs[current]->toggleActive();
} catch (const std::out_of_range & ex){
throw new TabContainer::NoSuchTab(index);
}
}
void TabContainer::gotoTabByName(const std::string & name){
try {
gotoTab(findTab(name));
} catch (const TabContainer::NoSuchTab & ex){
throw ex;
}
}
TabContainer::NoSuchTab::NoSuchTab(const std::string & name) throw():
name(name){
}
TabContainer::NoSuchTab::NoSuchTab(unsigned int index) throw(){
std::ostringstream os;
os << index;
name = os.str();
}
TabContainer::NoSuchTab::~NoSuchTab() throw() {
}
const char* TabContainer::NoSuchTab::what() const throw() {
return name.c_str();
}
Util::ReferenceCount<TabItem> TabContainer::getTab(unsigned int index){
try {
return tabs.at(index);
} catch (const std::out_of_range & ex){
throw new TabContainer::NoSuchTab(index);
}
}
unsigned int TabContainer::findTab(const std::string & name){
for (unsigned int i = 0; i < tabs.size(); i++){
Util::ReferenceCount<TabItem> tab = tabs[i];
if (name == tab->getName()){
return i;
}
}
throw TabContainer::NoSuchTab(name);
}
Util::ReferenceCount<TabItem> TabContainer::getByName(const std::string & name){
return tabs[findTab(name)];
}
void TabContainer::drawTabs(const Font & font, const Graphics::Bitmap & work){
if (tabs.empty()){
drawBox(transforms.getRadius(), 0, 0, work.getWidth(), work.getHeight()*2, colors, work);
font.printf((work.getWidth()/2) - (font.textLength("Empty")/2), 0, Graphics::makeColor(255,255,255), work, "Empty", 0);
return;
}
const int width = work.getWidth() / tabs.size();
const int inactiveY = work.getHeight() * .25;
const int modifier = (width * (transforms.getRadius()*.005)) == 0 ? 2 : (width * (transforms.getRadius()*.005));
int currentX = 0;
for (std::vector< Util::ReferenceCount<TabItem> >::iterator i = tabs.begin(); i != tabs.end(); ++i){
Util::ReferenceCount<TabItem> tab = *i;
if (tab->isActive()){
drawBox(transforms.getRadius(), currentX, 0, currentX + width, work.getHeight()*2, colors, work);
Graphics::Bitmap fontArea(work, currentX + modifier, 0, width - (modifier*2), work.getHeight());
font.printf((fontArea.getWidth()/2) - (font.textLength(tab->getName().c_str())/2), 0, Graphics::makeColor(255,255,255), fontArea, tab->getName(), 0);
tab->draw(font, body);
} else {
drawBox(transforms.getRadius(), currentX, inactiveY, currentX + width, work.getHeight()*2, colors, work);
if (colors.bodyAlpha < 255){
Graphics::Bitmap::transBlender(0,0,0,colors.borderAlpha);
work.translucent().hLine(currentX,work.getHeight()-1,currentX + width,colors.border);
} else {
work.hLine(currentX,work.getHeight()-1,currentX + width,colors.border);
}
Graphics::Bitmap fontArea(work, currentX + modifier, inactiveY, width - (modifier*2), work.getHeight());
font.printf((fontArea.getWidth()/2) - (font.textLength(tab->getName().c_str())/2), 0, Graphics::makeColor(255,255,255), fontArea, tab->getName(), 0);
}
currentX += width;
}
}
}
diff --git a/src/gui/tabbed-box.cpp b/src/gui/tabbed-box.cpp
index 20b5015e..c406ea19 100644
--- a/src/gui/tabbed-box.cpp
+++ b/src/gui/tabbed-box.cpp
@@ -1,343 +1,343 @@
-#include "util/graphics/bitmap.h"
-#include "tabbed-box.h"
+#include "r-tech1/graphics/bitmap.h"
+#include "r-tech1/gui/tabbed-box.h"
-#include "util/font.h"
+#include "r-tech1/font.h"
-#include "context-box.h"
+#include "r-tech1/gui/context-box.h"
using namespace Gui;
Tab::Tab():
active(false){
// Set alpha to 0 as we are not interested in the box
context.setRenderOnlyText(true);
}
Tab::~Tab(){
}
void Tab::addOption(const Util::ReferenceCount<ContextItem> & item){
context.addItem(item);
}
void Tab::render(const Graphics::Bitmap & area, const Font & font){
context.render(area, font);
}
void Tab::act(const Font & font){
context.act(font);
}
void Tab::setList(const std::vector<Util::ReferenceCount<ContextItem> > & list){
context.setList(list);
}
void Tab::setName(const std::string & name){
this->name = name;
}
void Tab::close(){
context.close();
}
void Tab::open(){
context.open();
}
void Tab::previous(const Font & font){
context.previous(font);
}
void Tab::next(const Font & font){
context.next(font);
}
void Tab::adjustLeft(){
context.adjustLeft();
}
void Tab::adjustRight(){
context.adjustRight();
}
int Tab::getCurrentIndex(){
return context.getCurrentIndex();
}
TabbedBox::TabbedBox():
current(0),
fontWidth(24),
fontHeight(24),
inTab(false),
tabWidthMax(0),
tabFontColor(Graphics::makeColor(255,255,255)),
currentTabFontColor(Graphics::makeColor(0,0,255)){
activeTabFontColor = new Effects::Gradient(50, tabFontColor, currentTabFontColor);
}
TabbedBox::TabbedBox(const TabbedBox & b):
activeTabFontColor(NULL){
this->location = b.location;
}
TabbedBox::~TabbedBox(){
for (std::vector<Gui::Tab *>::iterator i = tabs.begin(); i != tabs.end(); ++i){
Gui::Tab * tab = *i;
if (tab){
delete tab;
}
}
if (activeTabFontColor){
delete activeTabFontColor;
}
}
TabbedBox &TabbedBox::operator=( const TabbedBox &copy){
location = copy.location;
return *this;
}
// Logic
void TabbedBox::act(const Font & font){
if (!tabs.empty()){
const int width = font.textLength(tabs[current]->name.c_str()) + 5;
if (tabs.size() > 1){
tabWidthMax = (location.getWidth() - width) / (tabs.size() - 1);
} else {
tabWidthMax = location.getWidth() - width;
}
} else {
return;
}
if (!tabs[current]->active){
tabs[current]->active = true;
}
tabs[current]->act(font);
if (inTab){
if (activeTabFontColor){
activeTabFontColor->update();
}
}
}
void TabbedBox::render(const Graphics::Bitmap & work){
/* nothing */
}
// Render
void TabbedBox::render(const Graphics::Bitmap & work, const Font & font){
const int tabHeight = fontHeight + 5;
// checkWorkArea();
Graphics::Bitmap area(work, location.getX(), location.getY(), location.getWidth(), location.getHeight());
// Check if we are using a rounded box
if (transforms.getRadius() > 0){
const int offset = transforms.getRadius() * 4;
Graphics::TranslucentBitmap temp(Graphics::Bitmap(area, 0, location.getHeight() - offset/2, location.getWidth(), offset/2));
temp.roundRectFill((int)transforms.getRadius(), 0, offset/2 * -1, location.getWidth()-1, (offset/2)-1, colors.body);
temp.roundRect((int)transforms.getRadius(), 0, offset/2 * -1, location.getWidth()-1, (offset/2)-1, colors.border);
/*
Graphics::Bitmap temp(location.getWidth(), offset/2);
temp.clearToMask();
temp.roundRectFill((int)transforms.getRadius(), 0, offset/2 * -1, location.getWidth()-1, (offset/2)-1, colors.body);
temp.roundRect((int)transforms.getRadius(), 0, offset/2 * -1, location.getWidth()-1, (offset/2)-1, colors.border);
temp.translucent().draw(0,location.getHeight() - offset/2, area);
*/
area.translucent().rectangleFill(0, tabHeight+1, location.getWidth()-1, location.getHeight()-1 - offset/2, colors.body );
area.translucent().vLine(tabHeight,0,location.getHeight()-1 - offset/2,colors.border);
area.translucent().vLine(tabHeight,location.getWidth()-1,location.getHeight()-1 - offset/2,colors.border);
} else {
area.translucent().rectangleFill(0, tabHeight+1, location.getWidth()-1, location.getHeight()-1, colors.body );
area.translucent().vLine(tabHeight,0,location.getHeight()-1,colors.border);
area.translucent().hLine(0,location.getHeight()-1,location.getWidth()-1,colors.border);
area.translucent().vLine(tabHeight,location.getWidth()-1,location.getHeight()-1,colors.border);
}
tabs[current]->render(area, font);
renderTabs(area, font);
/* FIXME: only render the background in translucent mode, the text should
* not be translucent
*/
// workArea->draw(location.getX(), location.getY(), work);
}
// Add tab
void TabbedBox::addTab(const std::string & name, const std::vector<Util::ReferenceCount<ContextItem> > & list){
for (std::vector<Tab *>::iterator i = tabs.begin(); i != tabs.end(); ++i){
Tab * tab = *i;
if (tab->name == name){
return;
}
}
Tab * tab = new Tab();
tab->name = name;
tab->setList(list);
addTab(tab);
}
void TabbedBox::addTab(Tab * tab){
const int modifier = fontHeight * .35;
tab->getContext().location.setPosition(Gui::AbsolutePoint(0, fontHeight + modifier));
tab->getContext().location.setPosition2(Gui::AbsolutePoint(location.getWidth(), location.getHeight()- modifier));
tab->open();
tabs.push_back(tab);
}
void TabbedBox::moveTab(int direction){
tabs[current]->close();
tabs[current]->active = false;
current = (unsigned int) ((int)current + direction + (int) tabs.size()) % tabs.size();
tabs[current]->open();
tabs[current]->active = true;
}
void TabbedBox::up(const Font & font){
if (tabs.size() == 0){
return;
}
if (!inTab){
moveTab(-1);
} else {
tabs[current]->previous(font);
}
}
void TabbedBox::down(const Font & font){
if (tabs.size() == 0){
return;
}
if (!inTab){
moveTab(1);
} else {
tabs[current]->next(font);
}
}
void TabbedBox::left(const Font & font){
if (tabs.size() == 0){
return;
}
if (!inTab){
moveTab(-1);
} else {
tabs[current]->adjustLeft();
}
}
void TabbedBox::right(const Font & font){
if (tabs.size() == 0){
return;
}
if (!inTab){
moveTab(1);
} else {
tabs[current]->adjustRight();
}
}
void TabbedBox::toggleTabSelect(){
inTab = !inTab;
}
unsigned int TabbedBox::getCurrentIndex() const {
if (tabs.size() == 0){
return 0;
}
return this->tabs[current]->getCurrentIndex();
}
void TabbedBox::setTabFontColor(Graphics::Color color){
tabFontColor = color;
if (activeTabFontColor){
delete activeTabFontColor;
}
activeTabFontColor = new Effects::Gradient(50, tabFontColor, currentTabFontColor);
}
void TabbedBox::setSelectedTabFontColor(Graphics::Color color){
currentTabFontColor = color;
if (activeTabFontColor){
delete activeTabFontColor;
}
activeTabFontColor = new Effects::Gradient(50, tabFontColor, currentTabFontColor);
}
void TabbedBox::renderTabs(const Graphics::Bitmap & bmp, const Font & vFont){
const int tabHeight = fontHeight + 5;
int x = 0;
Graphics::Bitmap::transBlender(0, 0, 0, colors.bodyAlpha);
for (std::vector<Gui::Tab *>::iterator i = tabs.begin(); i != tabs.end(); ++i){
Gui::Tab * tab = *i;
const int textWidth = vFont.textLength(tab->name.c_str()) + 5;
// for last tab
int modifier = 0;
// Check last tab so we can ensure proper sizing
if (i == (tabs.begin() + tabs.size() -1)){
if (((tabWidthMax * (tabs.size() - 1)) + textWidth) != (unsigned int) location.getWidth()){
modifier = location.getWidth() - x - (tab->active ? textWidth : tabWidthMax);
}
}
if (transforms.getRadius() > 0){
const int offset = transforms.getRadius() * 4;
if (tab->active){
Graphics::Bitmap area(bmp, x, 0, x+textWidth+modifier-1, tabHeight+1);
if (!inTab){
area.translucent().roundRectFill((int)transforms.getRadius(), 0, 0, textWidth+modifier-1, tabHeight*2, colors.body);
area.translucent().roundRect((int)transforms.getRadius(), 0, 0, textWidth+modifier-1, tabHeight*2, colors.border);
vFont.printf((((textWidth + modifier)/2)-(((textWidth + modifier) - 5)/2)), 0, currentTabFontColor, area, tab->name, 0 );
} else {
area.translucent().roundRectFill((int)transforms.getRadius(), 0, 0, textWidth+modifier-1, tabHeight*2, colors.body);
area.translucent().roundRect((int)transforms.getRadius(), 0, 0, textWidth+modifier-1, tabHeight*2, colors.border);
vFont.printf((((textWidth + modifier)/2)-(((textWidth + modifier) - 5)/2)), 0, activeTabFontColor->current(), area, tab->name, 0 );
}
x += textWidth + modifier;
} else {
const int heightMod = tabHeight * .15;
int width = x+tabWidthMax+modifier-1;
int height = tabHeight-heightMod;
if (width > 1 && height > 1){
Graphics::Bitmap area(bmp, x, 1 + heightMod, width, height);
area.translucent().roundRectFill((int)transforms.getRadius(),0,0,tabWidthMax+modifier-1,tabHeight*2,Graphics::makeColor(105, 105, 105));
area.translucent().roundRect((int)transforms.getRadius(),0,0,tabWidthMax+modifier-1,tabHeight*2,Graphics::makeColor(58, 58, 58));
area.translucent().hLine(0,tabHeight,tabWidthMax+modifier-1,colors.border);
vFont.printf((((tabWidthMax + modifier)/2)-((textWidth + modifier)/2)), 0, tabFontColor, area, tab->name, 0 );
}
x += tabWidthMax + modifier;
}
} else {
if (tab->active){
Graphics::Bitmap area(bmp, x, 0, x+textWidth+modifier-1, tabHeight+1);
if (!inTab){
area.translucent().rectangleFill(0, 0, textWidth+modifier-1, tabHeight*2, colors.body);
area.translucent().rectangle(0, 0, textWidth+modifier-1, tabHeight*2, colors.border);
vFont.printf((((textWidth + modifier)/2)-(((textWidth + modifier) - 5)/2)), 0, currentTabFontColor, area, tab->name, 0 );
} else {
area.translucent().rectangleFill(0, 0, textWidth+modifier-1, tabHeight*2, colors.body);
area.translucent().rectangle(0, 0, textWidth+modifier-1, tabHeight*2, colors.border);
vFont.printf((((textWidth + modifier)/2)-(((textWidth + modifier) - 5)/2)), 0, activeTabFontColor->current(), area, tab->name, 0 );
}
x += textWidth + modifier;
} else {
const int heightMod = tabHeight * .15;
Graphics::Bitmap area(bmp, x, 1 + heightMod, x+tabWidthMax+modifier-1, tabHeight-heightMod);
area.translucent().rectangleFill(0,0,tabWidthMax+modifier-1,tabHeight*2,Graphics::makeColor(105, 105, 105));
area.translucent().rectangle(0,0,tabWidthMax+modifier-1,tabHeight*2,Graphics::makeColor(58, 58, 58));
area.translucent().hLine(0,tabHeight,tabWidthMax+modifier-1,colors.border);
vFont.printf((((tabWidthMax + modifier)/2)-((textWidth + modifier)/2)), 0, tabFontColor, area, tab->name, 0 );
x += tabWidthMax + modifier;
}
}
}
}
diff --git a/src/gui/timer.cpp b/src/gui/timer.cpp
index 92523ec9..6c8c7229 100644
--- a/src/gui/timer.cpp
+++ b/src/gui/timer.cpp
@@ -1,141 +1,141 @@
/*
SAGGUI (Simplified All Gaming Graphical User Interface)
Copyright (c) 2005-2007, Miguel A. Gavidia
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 "SAGGUI" 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
THE COPYRIGHT OWNER OR CONTRIBUTORS 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 "timer.h"
-#include "util/funcs.h"
-#include "util/system.h"
+#include "r-tech1/gui/timer.h"
+#include "r-tech1/funcs.h"
+#include "r-tech1/system.h"
guiTimer::guiTimer(){
// Setup initial
reset();
}
guiTimer::~guiTimer(){
// nothing to be done
}
/*
- unsigned int guiTimer::usecs()
- {
+ unsigned int guiTimer::usecs()
+ {
#if defined (_WIN32)
- static bool onetime = 0;
- static unsigned long long freq = 0;
+ static bool onetime = 0;
+ static unsigned long long freq = 0;
- if(!onetime) {
- onetime = true;
- QueryPerformanceFrequency((LARGE_INTEGER*)&freq);
- }
+ if(!onetime) {
+ onetime = true;
+ QueryPerformanceFrequency((LARGE_INTEGER*)&freq);
+ }
- QueryPerformanceCounter((LARGE_INTEGER*)&currentTime);
+ QueryPerformanceCounter((LARGE_INTEGER*)&currentTime);
- currentTime *= 1000000;
- currentTime /= freq;
+ currentTime *= 1000000;
+ currentTime /= freq;
- return currentTime - startTime * 1000;
+ return currentTime - startTime * 1000;
#else
- gettimeofday(&currentTime, 0);
+ gettimeofday(&currentTime, 0);
- return (unsigned long)((currentTime.tv_sec - startTime.tv_sec) / 1000)
- + (unsigned long)((currentTime.tv_usec - startTime.tv_usec));
+ return (unsigned long)((currentTime.tv_sec - startTime.tv_sec) / 1000)
+ + (unsigned long)((currentTime.tv_usec - startTime.tv_usec));
#endif
- }
+ }
*/
- unsigned int guiTimer::msecs()
- {
+ unsigned int guiTimer::msecs()
+ {
return System::currentMilliseconds() - startTime;
/*
#if defined (_WIN32)
- currentTime = GetTickCount();
+ currentTime = GetTickCount();
- return currentTime - startTime;
+ return currentTime - startTime;
#else
- gettimeofday(&currentTime, 0);
+ gettimeofday(&currentTime, 0);
- return (unsigned long)((currentTime.tv_sec - startTime.tv_sec) * 1000)
- + (unsigned long)((currentTime.tv_usec - startTime.tv_usec) / 1000);
+ return (unsigned long)((currentTime.tv_sec - startTime.tv_sec) * 1000)
+ + (unsigned long)((currentTime.tv_usec - startTime.tv_usec) / 1000);
#endif
*/
- }
-
- unsigned int guiTimer::secs()
- {
+ }
+
+ unsigned int guiTimer::secs()
+ {
return msecs() / 1000;
/*
#if defined (_WIN32)
- currentTime = GetTickCount();
-
- return (currentTime - startTime) / 1000;
+ currentTime = GetTickCount();
+
+ return (currentTime - startTime) / 1000;
#else
- gettimeofday(&currentTime, 0);
+ gettimeofday(&currentTime, 0);
- return (unsigned long)(currentTime.tv_sec - startTime.tv_sec);
+ return (unsigned long)(currentTime.tv_sec - startTime.tv_sec);
#endif
*/
- }
-
- // Reset timer
- void guiTimer::reset()
- {
+ }
+
+ // Reset timer
+ void guiTimer::reset()
+ {
startTime = System::currentMilliseconds();
/*
#if defined (_WIN32)
- startTime = GetTickCount();
+ startTime = GetTickCount();
#else
- gettimeofday(&startTime, 0);
+ gettimeofday(&startTime, 0);
#endif
*/
- }
-
- // Provides a method to sleep
- void guiTimer::sleep(int msecs)
- {
+ }
+
+ // Provides a method to sleep
+ void guiTimer::sleep(int msecs)
+ {
Util::rest(msecs);
/*
#if defined (_WIN32)
- Sleep(msecs);
+ Sleep(msecs);
#else
- struct timespec timeOut;
- timeOut.tv_sec = 0;
- timeOut.tv_nsec = (msecs * 1000000);
- nanosleep(&timeOut, NULL);
+ struct timespec timeOut;
+ timeOut.tv_sec = 0;
+ timeOut.tv_nsec = (msecs * 1000000);
+ nanosleep(&timeOut, NULL);
#endif
*/
- }
+ }
diff --git a/src/gui/widget.cpp b/src/gui/widget.cpp
index ca8c8259..2a6ebc54 100644
--- a/src/gui/widget.cpp
+++ b/src/gui/widget.cpp
@@ -1,188 +1,188 @@
-#include "util/graphics/bitmap.h"
-#include "util/funcs.h"
-#include "widget.h"
+#include "r-tech1/graphics/bitmap.h"
+#include "r-tech1/funcs.h"
+#include "r-tech1/gui/widget.h"
#include <math.h>
-#include "util/token.h"
-#include "coordinate.h"
-#include "util/exceptions/load_exception.h"
+#include "r-tech1/token.h"
+#include "r-tech1/gui/coordinate.h"
+#include "r-tech1/exceptions/load_exception.h"
#include <sstream>
using namespace Gui;
static void round_double (double dbl_to_round , int &rounded_num) {
rounded_num = static_cast<int>(dbl_to_round);
if ((dbl_to_round - static_cast<double>(rounded_num)) >= 0.5) {rounded_num++;}
}
ColorInfo::ColorInfo():
body(Graphics::makeColor(0, 0, 0)),
/* alpha 0 is invisible, 255 is opaque. set something in the middle as default */
bodyAlpha(128),
border(Graphics::makeColor(0, 0, 0)),
borderAlpha(128){
}
Transformations::Transformations():
radius(0){
}
Transformations::Transformations(const Transformations & transforms):
radius(transforms.radius){
}
Transformations::~Transformations(){
}
Transformations & Transformations::operator=(const Transformations & transforms){
this->radius = transforms.radius;
return *this;
}
Widget::Widget(){
- // Nothing yet
+ // Nothing yet
}
-
+
Widget::Widget( const Widget & w ){
this->location = w.location;
this->transforms = w.transforms;
}
Widget::~Widget(){
}
// copy
Widget &Widget::operator=( const Widget &copy){
this->location = copy.location;
this->transforms = copy.transforms;
return *this;
}
void Widget::setCoordinates(const Token * token){
if ( *token == "position" ){
int x, y, width, height;
token->view() >> x >> y >> width >> height;
AbsolutePoint pos(x, y);
AbsolutePoint dimensions(x + width, y + height);
location.setPosition(pos);
location.setPosition2(dimensions);
} else if ( *token == "relative-position" ){
double x1, y1, x2, y2;
token->view() >> x1 >> y1 >> x2 >> y2;
RelativePoint pos(x1,y1);
RelativePoint dimensions(x2,y2);
location = Coordinate(pos, dimensions);
} else if ( *token == "coordinate" ){
TokenView view = token->view();
while (view.hasMore()){
const Token * coordToken;
view >> coordToken;
if (*coordToken == "absolute"){
int x, y, width, height;
coordToken->view() >> x >> y >> width >> height;
AbsolutePoint pos(x, y);
AbsolutePoint dimensions(x + width, y + height);
location = Coordinate(pos, dimensions);
} else if (*coordToken == "relative"){
double x1, y1, x2, y2;
coordToken->view() >> x1 >> y1 >> x2 >> y2;
RelativePoint pos(x1,y1);
RelativePoint dimensions(x2,y2);
location = Coordinate(pos, dimensions);
} else if (*coordToken == "z"){
double z;
coordToken->view() >> z;
location.setZ(z);
}
}
}
if (location.getWidth() < 0 || location.getHeight() < 0){
std::ostringstream out;
out << "Invalid location dimension (cannot have a negative size). Width " << location.getWidth() << " Height " << location.getHeight() << ". From token: ";
token->toString(out, "");
throw LoadException(__FILE__, __LINE__, out.str());
}
}
void Widget::setColors(const Token * token){
if ( *token == "position-body" ) {
// This handles the body color of the widget
int r,g,b;
token->view() >> r >> g >> b >> colors.bodyAlpha;
colors.body = Graphics::makeColor(r,g,b);
} else if ( *token == "position-border" ) {
// This handles the border color of the widget
int r,g,b;
token->view() >> r >> g >> b >> colors.borderAlpha;
colors.border = Graphics::makeColor(r,g,b);
}
}
void Widget::setTransforms(const Token * token){
try{
if ( *token != "transforms" ){
throw LoadException(__FILE__, __LINE__, "Not a Widget Transforms.");
}
TokenView view = token->view();
while (view.hasMore()){
const Token * tok;
view >> tok;
double radius = 0;
try{
if (tok->match("radius", radius)){
transforms.setRadius(radius);
} else {
Global::debug(0) << "Unknown Transforms property: " << tok->getName() << std::endl;
}
} catch (const TokenException & ex){
throw LoadException(__FILE__, __LINE__, ex, "Transforms parse error");
} catch ( const LoadException & ex ) {
throw ex;
}
}
} catch (const TokenException & e){
throw LoadException(__FILE__, __LINE__, e, "Error reading transforms.");
}
}
void Widget::render(const Graphics::Bitmap & bitmap, const Font & font){
render(bitmap);
}
void Widget::drawBox(int radius, int x1, int y1, int x2, int y2, const Gui::ColorInfo & colors, const Graphics::Bitmap & work){
// rounded body?
if (radius > 0){
if (colors.bodyAlpha < 255){
Graphics::Bitmap::transBlender(0,0,0,colors.bodyAlpha);
work.translucent().roundRectFill(radius, x1, y1, x2, y2, colors.body);
Graphics::Bitmap::transBlender(0,0,0,colors.borderAlpha);
work.translucent().roundRect(radius, x1, y1, x2-1, y2-1, colors.border);
} else {
work.roundRectFill(radius, x1, y1, x2, y2, colors.body);
work.roundRect(radius, x1, y1, x2-1, y2-1, colors.border);
}
} else {
if (colors.bodyAlpha < 255){
Graphics::Bitmap::transBlender(0,0,0,colors.bodyAlpha);
work.translucent().rectangleFill(x1, y1, x2, y2, colors.body );
Graphics::Bitmap::transBlender(0,0,0,colors.borderAlpha);
work.translucent().vLine(y1,x1,y2-1,colors.border);
work.translucent().hLine(x1,y2-1,x2,colors.border);
work.translucent().vLine(y1,x2-1,y2-1,colors.border);
} else {
work.rectangleFill(x1, y1, x2, y2, colors.body );
work.vLine(y1,x1,y2-1,colors.border);
work.hLine(x1,y2-1,x2,colors.border);
work.vLine(y1,x2-1,y2-1,colors.border);
}
}
}
Util::ReferenceCount<Graphics::Bitmap> Widget::checkWorkArea(const Graphics::Bitmap & parent){
if (location.getWidth() <= 0 || location.getHeight() <= 0){
return Util::ReferenceCount<Graphics::Bitmap>(NULL);
}
return Util::ReferenceCount<Graphics::Bitmap>(new Graphics::Bitmap(parent, location.getX(), location.getY(), location.getWidth(), location.getHeight()));
}
diff --git a/src/init.cpp b/src/init.cpp
index 328e97d4..47b94cc9 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -1,437 +1,443 @@
#ifdef USE_ALLEGRO
#include <allegro.h>
#ifdef ALLEGRO_WINDOWS
#include <winalleg.h>
#endif
#endif
/*
#ifdef USE_ALLEGRO5
#include <allegro5/allegro.h>
#include <allegro5/allegro_image.h>
#include <allegro5/allegro_primitives.h>
#endif
*/
#ifdef USE_SDL
#include <SDL.h>
#endif
#ifndef WINDOWS
#include <signal.h>
#include <string.h>
#include <unistd.h>
#endif
#if defined(LINUX) && !defined(UCLIBC)
#include <execinfo.h>
#endif
/* don't be a boring tuna */
// #warning you are ugly
-#include "system/init.h"
-#include "init.h"
-#include "network/network.h"
-#include "thread.h"
+/**
+ *
+ * FIXME No System, this outside util directory
+ *
+ */
+
+//#include "system/init.h"
+#include "r-tech1/init.h"
+#include "r-tech1/network/network.h"
+#include "r-tech1/thread.h"
#include <time.h>
-#include "system/timer.h"
+//#include "system/timer.h"
#include <ostream>
-#include "sound/dumb/include/dumb.h"
+#include "libs/dumb/include/dumb.h"
/*
#ifdef USE_ALLEGRO
#include "sound/dumb/include/aldumb.h"
#include "graphics/allegro/loadpng/loadpng.h"
#include "graphics/allegro/gif/algif.h"
#endif
*/
-#include "graphics/bitmap.h"
-#include "funcs.h"
-#include "file-system.h"
-#include "font.h"
-#include "events.h"
-#include "sound/sound.h"
-#include "configuration.h"
-#include "sound/music.h"
-#include "resource.h"
-#include "loading.h"
-#include "input/keyboard.h"
-#include "message-queue.h"
+#include "r-tech1/graphics/bitmap.h"
+#include "r-tech1/funcs.h"
+#include "r-tech1/file-system.h"
+#include "r-tech1/font.h"
+#include "r-tech1/events.h"
+#include "r-tech1/sound/sound.h"
+#include "r-tech1/configuration.h"
+#include "r-tech1/sound/music.h"
+#include "r-tech1/resource.h"
+#include "r-tech1/loading.h"
+#include "r-tech1/input/keyboard.h"
+#include "r-tech1/message-queue.h"
#ifdef WII
#include <fat.h>
#endif
-#include "xenon/xenon.h"
+#include "r-tech1/xenon/xenon.h"
using namespace std;
volatile int Global::speed_counter4 = 0;
bool Global::rateLimit = true;
/* enough seconds for 136 years */
volatile unsigned int Global::second_counter = 0;
/* the original engine was running at 90 ticks per second, but we dont
* need to render that fast, so TICS_PER_SECOND is really fps and
* LOGIC_MULTIPLIER will be used to adjust the speed counter to its
* original value.
*/
int Global::TICS_PER_SECOND = 40;
// const double Global::LOGIC_MULTIPLIER = (double) 90 / (double) Global::TICS_PER_SECOND;
double Global::ticksPerSecond(int ticks){
return (double) ticks / (double) TICS_PER_SECOND;
}
#ifdef USE_ALLEGRO
const int Global::WINDOWED = GFX_AUTODETECT_WINDOWED;
const int Global::FULLSCREEN = GFX_AUTODETECT_FULLSCREEN;
#else
/* FIXME: use enums here or something */
const int Global::WINDOWED = 0;
const int Global::FULLSCREEN = 1;
#endif
#if !defined(WINDOWS) && !defined(WII) && !defined(MINPSPW) && !defined(PS3) && !defined(NDS) && !defined(NACL) && !defined(XENON) && !defined(UCLIBC)
#ifdef LINUX
static void print_stack_trace(){
/* use addr2line on these addresses to get a filename and line number */
void *trace[128];
int frames = backtrace(trace, 128);
printf("Stack trace\n");
for (int i = 0; i < frames; i++){
printf(" %p\n", trace[i]);
}
}
#endif
static void handleSigSegV(int i, siginfo_t * sig, void * data){
const char * message = "Bug! Caught a memory violation. Shutting down..\n";
int dont_care = write(1, message, 48);
dont_care = dont_care;
#if defined(LINUX) && !defined(UCLIBC)
print_stack_trace();
#endif
// Global::shutdown_message = "Bug! Caught a memory violation. Shutting down..";
Graphics::setGfxModeText();
#ifdef USE_ALLEGRO
allegro_exit();
#endif
#ifdef USE_SDL
SDL_Quit();
#endif
/* write to a log file or something because sigsegv shouldn't
* normally happen.
*/
exit(1);
}
#else
#endif
/* catch a socket being closed prematurely on unix */
#if !defined(WINDOWS) && !defined(WII) && !defined(MINPSPW) && !defined(PS3) && !defined(NDS) && !defined(NACL) && !defined(XENON) && !defined(UCLIBC)
static void handleSigPipe( int i, siginfo_t * sig, void * data ){
}
/*
static void handleSigUsr1( int i, siginfo_t * sig, void * data ){
- pthread_exit( NULL );
+ pthread_exit( NULL );
}
*/
#endif
static void registerSignals(){
#if !defined(WINDOWS) && !defined(WII) && !defined(MINPSPW) && !defined(PS3) && !defined(NDS) && !defined(NACL) && !defined(XENON) && !defined(UCLIBC)
- struct sigaction action;
- memset( &action, 0, sizeof(struct sigaction) );
- action.sa_sigaction = handleSigPipe;
- sigaction( SIGPIPE, &action, NULL );
-
- memset( &action, 0, sizeof(struct sigaction) );
- action.sa_sigaction = handleSigSegV;
- sigaction( SIGSEGV, &action, NULL );
-
- /*
- action.sa_sigaction = handleSigUsr1;
- sigaction( SIGUSR1, &action, NULL );
- */
+ struct sigaction action;
+ memset( &action, 0, sizeof(struct sigaction) );
+ action.sa_sigaction = handleSigPipe;
+ sigaction( SIGPIPE, &action, NULL );
+
+ memset( &action, 0, sizeof(struct sigaction) );
+ action.sa_sigaction = handleSigSegV;
+ sigaction( SIGSEGV, &action, NULL );
+
+ /*
+ action.sa_sigaction = handleSigUsr1;
+ sigaction( SIGUSR1, &action, NULL );
+ */
#endif
}
/* mostly used for testing purposes */
#if 0
bool Global::initNoGraphics(){
/* copy/pasting the init code isn't ideal, maybe fix it later */
Global::stream_type & out = Global::debug(0);
out << "-- BEGIN init --" << endl;
out << "Data path is " << Util::getDataPath2().path() << endl;
out << "Build date " << __DATE__ << " " << __TIME__ << endl;
#ifdef WII
/* <WinterMute> fatInitDefault will set working dir to argv[0] passed by launcher,
* or root of first device mounted
*/
out << "Fat init " << (fatInitDefault() == true ? "Ok" : "Failed") << endl;
#endif
/*
char buffer[512];
if (getcwd(buffer, 512) != 0){
printf("Working directory '%s'\n", buffer);
}
*/
if (!Storage::instance().exists(Util::getDataPath2())){
Global::debug(0) << "Cannot find data path '" << Util::getDataPath2().path() << "'! Either use the -d switch to specify the data directory or find the data directory and move it to that path" << endl;
return false;
}
/* do implementation specific setup */
System::initSystem(out);
dumb_register_stdfiles();
// Sound::initialize();
// Filesystem::initialize();
/*
Graphics::SCALE_X = GFX_X;
Graphics::SCALE_Y = GFX_Y;
*/
Configuration::loadConfigurations();
const int sx = Configuration::getScreenWidth();
const int sy = Configuration::getScreenHeight();
Graphics::Bitmap::setFakeGraphicsMode(sx, sy);
/* music */
atexit(&dumb_exit);
out << "Initialize random number generator" << endl;
/* initialize random number generator */
srand(time(NULL));
registerSignals();
#ifdef HAVE_NETWORKING
out << "Initialize network" << endl;
Network::init();
atexit(Network::closeAll);
#endif
/* this mutex is used to show the loading screen while the game loads */
// Util::Thread::initializeLock(&Loader::loading_screen_mutex);
out << "-- END init --" << endl;
return true;
}
#endif
#ifdef PS3
extern "C" int SDL_JoystickInit();
static void ps3JoystickHack(){
/* FIXME: hack for the ps3. at the start of the program only 1 joystick is enabled
* even if more than 1 is connected, so we force another call to JoystickInit
* to pick up all joysticks.
*/
SDL_JoystickInit();
}
#endif
#if defined(USE_SDL) && defined(MACOSX)
#include <CoreFoundation/CoreFoundation.h>
#endif
static void maybeSetWorkingDirectory(){
#if defined(USE_SDL) && defined(MACOSX)
CFBundleRef mainBundle = CFBundleGetMainBundle();
if (mainBundle != NULL){
CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL(mainBundle);
char path[PATH_MAX];
if (CFURLGetFileSystemRepresentation(resourcesURL, TRUE, (UInt8 *)path, PATH_MAX)){
chdir(path);
} else {
Global::debug(0) << "Could not set working directory to Resources" << std::endl;
}
CFRelease(resourcesURL);
}
#endif
}
Global::InitConditions::InitConditions():
graphics(Default),
sound(true),
fullscreen(false),
networking(true){
}
bool Global::init(const InitConditions & conditions){
/* Can xenon_init be moved lower? Probably.. */
#ifdef XENON
xenon_init();
#endif
Global::stream_type & out = Global::debug(0);
out << "-- BEGIN init --" << endl;
out << "Data path is " << Util::getDataPath2().path() << endl;
out << "Build date " << __DATE__ << " " << __TIME__ << endl;
maybeSetWorkingDirectory();
#ifdef WII
/* <WinterMute> fatInitDefault will set working dir to argv[0] passed by launcher,
* or root of first device mounted
*/
out << "Fat init " << (fatInitDefault() == 0 ? "Ok" : "Failed") << endl;
#endif
/*
char buffer[512];
if (getcwd(buffer, 512) != 0){
printf("Working directory '%s'\n", buffer);
}
*/
#ifndef NACL
/* do implementation specific setup */
System::initSystem(conditions, out);
#endif
dumb_register_stdfiles();
if (conditions.sound){
Sound::initialize();
}
// Filesystem::initialize();
/*
Graphics::SCALE_X = GFX_X;
Graphics::SCALE_Y = GFX_Y;
*/
Configuration::loadConfigurations();
if (conditions.graphics != InitConditions::Disabled){
const int sx = Configuration::getScreenWidth();
const int sy = Configuration::getScreenHeight();
InitConditions::WindowMode gfx = conditions.graphics;
if (conditions.graphics == InitConditions::Default){
gfx = Configuration::getFullscreen() ? InitConditions::Fullscreen : InitConditions::Window;
} else {
Configuration::setFullscreen(conditions.graphics == InitConditions::Fullscreen);
}
/* set up the screen */
int mode = WINDOWED;
switch (gfx){
case InitConditions::Disabled: break; /* won't happen */
case InitConditions::Default: break; /* already handled */
case InitConditions::Window: mode = WINDOWED; break;
case InitConditions::Fullscreen: mode = FULLSCREEN; break;
}
int gfxCode = Graphics::setGraphicsMode(mode, sx, sy);
if (gfxCode == 0){
out << "Set graphics mode: Ok" << endl;
} else {
out << "Set graphics mode: Failed! (" << gfxCode << ")" << endl;
return false;
}
}
/* music */
atexit(&dumb_exit);
out << "Initialize random number generator" << endl;
/* initialize random number generator */
srand(time(NULL));
registerSignals();
#ifdef HAVE_NETWORKING
if (conditions.networking){
out << "Initialize network" << endl;
Network::init();
atexit(Network::closeAll);
}
#endif
/* this mutex is used to show the loading screen while the game loads */
Util::Thread::initializeLock(&MessageQueue::messageLock);
Resource::initialize();
Util::Thread::initializeLock(&System::run_timer_lock);
System::run_timer = true;
Global::TICS_PER_SECOND = Configuration::getFps();
System::startTimers();
out << "-- END init --" << endl;
/*
const Font & font = Font::getDefaultFont();
// font.setSize(30, 30);
Bitmap temp(font.textLength("Loading") + 1, font.getHeight("Loading") + 1);
font.printf(0, 0, Bitmap::makeColor(255, 255, 255), temp, "Loading", 0);
temp.BlitToScreen(sx / 2, sy / 2);
*/
#ifdef PS3
// ps3JoystickHack();
#endif
return true;
}
/* Checks for the data path and blinks the screen a specific color based on its findings:
* grey: still looking
* red: failed
* white: found it
*/
bool Global::dataCheck(){
Graphics::Bitmap white(*Graphics::getScreenBuffer());
/* for nacl which takes a while to run exists(), we just want
* to show some progress
*/
white.fill(Graphics::makeColor(128, 128, 128));
white.BlitToScreen();
if (!Storage::instance().exists(Util::getDataPath2())){
white.fill(Graphics::makeColor(255, 0, 0));
white.BlitToScreen();
Global::debug(0) << "Cannot find data path '" << Util::getDataPath2().path() << "'! Either use the -d switch to specify the data directory or find the data directory and move it to that path" << endl;
/* The program is probably going to exit immediately, so allow the user some time
* to see that the red screen occured.
*/
Util::restSeconds(1);
return false;
} else {
white.fill(Graphics::makeColor(255, 255, 255));
white.BlitToScreen();
}
return true;
}
/* Restarts the timers */
void Global::setTicksPerSecond(int ticks){
if (ticks < 1){
ticks = 1;
}
if (ticks > 90){
ticks = 90;
}
if (ticks != TICS_PER_SECOND){
TICS_PER_SECOND = ticks;
System::closeTimers();
System::startTimers();
}
}
void Global::close(){
System::closeTimers();
}
diff --git a/src/input/allegro5/joystick.cpp b/src/input/allegro5/joystick.cpp
index 8f08b34b..38791868 100644
--- a/src/input/allegro5/joystick.cpp
+++ b/src/input/allegro5/joystick.cpp
@@ -1,389 +1,389 @@
#ifdef USE_ALLEGRO5
-#include "../joystick.h"
-#include "joystick.h"
-#include "util/debug.h"
+#include "r-tech1/input/joystick.h"
+#include "r-tech1/input/allegro5/joystick.h"
+#include "r-tech1/debug.h"
#include <allegro5/allegro.h>
using std::vector;
using std::string;
using std::map;
class ButtonMapping{
public:
ButtonMapping(){
}
virtual ~ButtonMapping(){
}
virtual int toNative(Joystick::Key key) = 0;
virtual Joystick::Key toKey(int button) = 0;
virtual void axisMotionEvents(int stick, int axis, float position, vector<Joystick::Event> & events) = 0;
virtual void hatMotionEvents(int motion, vector<Joystick::Event> & events) = 0;
};
class DefaultMapping: public ButtonMapping {
public:
DefaultMapping(){
}
virtual int toNative(Joystick::Key key){
switch (key){
case Joystick::Button1: return 0;
case Joystick::Button2: return 1;
case Joystick::Button3: return 2;
case Joystick::Button4: return 3;
case Joystick::Button5: return 4;
case Joystick::Button6: return 5;
case Joystick::Start: return 6;
case Joystick::Quit: return 7;
case Joystick::Up: return 8;
case Joystick::Down: return 9;
case Joystick::Left: return 10;
case Joystick::Right: return 11;
case Joystick::Invalid: return -1;
}
return -1;
}
virtual Joystick::Key toKey(int button){
switch (button){
case 0: return Joystick::Button1;
case 1: return Joystick::Button2;
case 2: return Joystick::Button3;
case 3: return Joystick::Button4;
case 4: return Joystick::Button5;
case 5: return Joystick::Button6;
case 6: return Joystick::Start;
case 7: return Joystick::Quit;
case 8: return Joystick::Up;
case 9: return Joystick::Down;
case 10: return Joystick::Left;
case 11: return Joystick::Right;
}
return Joystick::Invalid;
}
virtual void axisMotionEvents(int stick, int axis, float position, vector<Joystick::Event> & events){
}
virtual void hatMotionEvents(int motion, vector<Joystick::Event> & events){
}
virtual ~DefaultMapping(){
}
};
class LogitechPrecision: public ButtonMapping {
public:
enum Buttons{
Button1 = 0,
Button2 = 1,
Button3 = 2,
Button4 = 3,
Start = 8,
Select = 9,
R2 = 7,
R1 = 5,
L2 = 6,
L1 = 4
};
int toNative(Joystick::Key key){
switch (key){
case Joystick::Button1: return Button1;
case Joystick::Button2: return Button2;
case Joystick::Button3: return Button3;
case Joystick::Button4: return Button4;
case Joystick::Button5: return L1;
case Joystick::Button6: return R1;
case Joystick::Start: return Start;
case Joystick::Quit: return Select;
case Joystick::Invalid: return -1;
case Joystick::Left:
case Joystick::Right:
case Joystick::Up:
case Joystick::Down: return -1;
}
return -1;
}
Joystick::Key toKey(int button){
switch (button){
case Button1: return Joystick::Button1;
case Button2: return Joystick::Button2;
case Button3: return Joystick::Button3;
case Button4: return Joystick::Button4;
case L1: return Joystick::Button5;
case R1: return Joystick::Button6;
case Start: return Joystick::Start;
case Select: return Joystick::Quit;
}
return Joystick::Invalid;
}
/* axis 1. negative up, positive down
* axis 0, negative left, positive right
*/
void axisMotionEvents(int stick, int axis, float position, vector<Joystick::Event> & events){
int tolerance = 10;
const int LeftRightAxis = 0;
const int UpDownAxis = 1;
switch (stick){
case 0: {
switch (axis){
case UpDownAxis: {
if (position == -1){
events.push_back(Joystick::Event(Joystick::Up, true));
events.push_back(Joystick::Event(Joystick::Down, false));
} else if (position == 1){
events.push_back(Joystick::Event(Joystick::Up, false));
events.push_back(Joystick::Event(Joystick::Down, true));
} else if (position == 0){
events.push_back(Joystick::Event(Joystick::Up, false));
events.push_back(Joystick::Event(Joystick::Down, false));
}
break;
}
case LeftRightAxis: {
if (position == -1){
events.push_back(Joystick::Event(Joystick::Left, true));
events.push_back(Joystick::Event(Joystick::Right, false));
} else if (position == 1){
events.push_back(Joystick::Event(Joystick::Left, false));
events.push_back(Joystick::Event(Joystick::Right, true));
} else if (position == 0){
events.push_back(Joystick::Event(Joystick::Left, false));
events.push_back(Joystick::Event(Joystick::Right, false));
}
break;
}
default: {
}
}
}
default: {
break;
}
}
#if 0
if (axis == 0){
if (position == 0){
events.push_back(Joystick::Event(Joystick::Left, false));
events.push_back(Joystick::Event(Joystick::Right, false));
} else if (motion == -32768){
events.push_back(Joystick::Event(Joystick::Left, true));
} else if (motion == 32767){
events.push_back(Joystick::Event(Joystick::Right, true));
} else if (motion == 128){
events.push_back(Joystick::Event(Joystick::Up, false));
events.push_back(Joystick::Event(Joystick::Down, false));
} else if (motion == 1){
events.push_back(Joystick::Event(Joystick::Up, true));
} else if (motion == 255){
events.push_back(Joystick::Event(Joystick::Down, true));
}
/*
if (motion < -tolerance){
events.push_back(Joystick::Event(Joystick::Left, true));
} else if (motion > tolerance){
events.push_back(Joystick::Event(Joystick::Right, true));
} else {
/ * fake a release for left and right * /
events.push_back(Joystick::Event(Joystick::Left, false));
events.push_back(Joystick::Event(Joystick::Right, false));
}
*/
} else if (axis == 1){
if (motion < -tolerance){
events.push_back(Joystick::Event(Joystick::Up, true));
} else if (motion > tolerance){
events.push_back(Joystick::Event(Joystick::Down, true));
} else {
events.push_back(Joystick::Event(Joystick::Up, false));
events.push_back(Joystick::Event(Joystick::Down, false));
}
}
#endif
}
virtual void hatMotionEvents(int motion, vector<Joystick::Event> & events){
}
};
static Util::ReferenceCount<ButtonMapping> createMapping(ALLEGRO_JOYSTICK * joystick){
string name = al_get_joystick_name(joystick);
if (name.find("Logitech(R) Precision(TM) Gamepad") != string::npos){
return Util::ReferenceCount<ButtonMapping>(new LogitechPrecision());
}
return Util::ReferenceCount<ButtonMapping>(new DefaultMapping());
}
Allegro5Joystick::Allegro5Joystick(int id):
id(id){
queue = al_create_event_queue();
if (al_is_joystick_installed()){
al_register_event_source(queue, al_get_joystick_event_source());
}
buttons = createMapping(al_get_joystick(id));
readCustomButtons();
readCustomAxes();
}
void Allegro5Joystick::axis(int stick, int axis, float position){
/*
if (stick == 9){
Global::debug(0) << "stick " << stick << " axis " << axis << " position " << position << std::endl;
}
*/
const std::set<JoystickListener*> & listeners = getListeners();
for (std::set<JoystickListener*>::const_iterator it = listeners.begin(); it != listeners.end(); it++){
(*it)->axisMotion(this, stick, axis, position);
}
bool handled = false;
for (std::map<Key, Axis>::iterator it = customAxis.begin(); it != customAxis.end(); it++){
Key key = it->first;
Axis & use = it->second;
if (use.stick == stick && use.axis == axis){
handled = true;
bool output = false;
/* Only output an event if the new axis position is different from the last one */
if (position >= use.low && position <= use.high){
if (use.on == false){
use.on = true;
output = true;
}
} else {
/* Not in range, so if we output an event before then output a false event */
if (use.on == true){
use.on = false;
output = true;
}
}
if (output){
events.push_back(Joystick::Event(key, use.on));
}
}
}
/* If no custom axis then use the default joystick handler */
if (!handled){
buttons->axisMotionEvents(stick, axis, position, events);
}
}
Joystick::Key Allegro5Joystick::getKey(int button){
if (customButton.find(button) != customButton.end()){
return customButton[button];
}
return buttons->toKey(button);
}
int Allegro5Joystick::getButton(Key key){
for (std::map<int, Key>::iterator it = customButton.begin(); it != customButton.end(); it++){
if (it->second == key){
return it->first;
}
}
return buttons->toNative(key);
}
void Allegro5Joystick::buttonDown(int button){
// Global::debug(0) << "Button down " << button << std::endl;
const std::set<JoystickListener*> & listeners = getListeners();
for (std::set<JoystickListener*>::const_iterator it = listeners.begin(); it != listeners.end(); it++){
(*it)->pressButton(this, button);
}
Key event = getKey(button);
if (event != Invalid){
events.push_back(Event(event, true));
}
}
void Allegro5Joystick::buttonUp(int button){
// Global::debug(0) << "Button up " << button << std::endl;
for (std::set<JoystickListener*>::iterator it = listeners.begin(); it != listeners.end(); it++){
(*it)->releaseButton(this, button);
}
Key event = getKey(button);
if (event != Invalid){
events.push_back(Event(event, false));
}
}
void Allegro5Joystick::poll(){
events.clear();
ALLEGRO_EVENT event;
while (al_get_next_event(queue, &event)){
switch (event.type){
case ALLEGRO_EVENT_JOYSTICK_AXIS: {
if (event.joystick.id == al_get_joystick(id)){
axis(event.joystick.stick, event.joystick.axis, event.joystick.pos);
}
break;
}
case ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN: {
if (event.joystick.id == al_get_joystick(id)){
buttonDown(event.joystick.button);
}
break;
}
case ALLEGRO_EVENT_JOYSTICK_BUTTON_UP: {
if (event.joystick.id == al_get_joystick(id)){
buttonUp(event.joystick.button);
}
break;
}
}
}
}
std::map<int, std::map<int, double> > Allegro5Joystick::getCurrentAxisValues() const {
ALLEGRO_JOYSTICK_STATE state;
ALLEGRO_JOYSTICK * joystick = al_get_joystick(id);
al_get_joystick_state(joystick, &state);
map<int, map<int, double> > out;
int sticks = al_get_joystick_num_sticks(joystick);
for (int stick = 0; stick < sticks; stick++){
int axis = al_get_joystick_num_axes(joystick, stick);
for (int i = 0; i < axis; i++){
out[stick][i] = state.stick[stick].axis[i];
}
}
return out;
}
int Allegro5Joystick::getDeviceId() const {
return id;
}
std::string Allegro5Joystick::getName() const {
return al_get_joystick_name(al_get_joystick(id));
}
Allegro5Joystick::~Allegro5Joystick(){
al_destroy_event_queue(queue);
queue = NULL;
}
int Joystick::numberOfJoysticks(){
return al_get_num_joysticks();
}
#endif
diff --git a/src/input/allegro5/keyboard.cpp b/src/input/allegro5/keyboard.cpp
index 219af47d..9bfa5508 100644
--- a/src/input/allegro5/keyboard.cpp
+++ b/src/input/allegro5/keyboard.cpp
@@ -1,170 +1,170 @@
-#include "../keyboard.h"
+#include "r-tech1/input/keyboard.h"
#include <allegro5/keycodes.h>
const Keyboard::KeyType Keyboard::Key_A = ALLEGRO_KEY_A;
const Keyboard::KeyType Keyboard::Key_B = ALLEGRO_KEY_B;
const Keyboard::KeyType Keyboard::Key_C = ALLEGRO_KEY_C;
const Keyboard::KeyType Keyboard::Key_D = ALLEGRO_KEY_D;
const Keyboard::KeyType Keyboard::Key_E = ALLEGRO_KEY_E;
const Keyboard::KeyType Keyboard::Key_F = ALLEGRO_KEY_F;
const Keyboard::KeyType Keyboard::Key_G = ALLEGRO_KEY_G;
const Keyboard::KeyType Keyboard::Key_H = ALLEGRO_KEY_H;
const Keyboard::KeyType Keyboard::Key_I = ALLEGRO_KEY_I;
const Keyboard::KeyType Keyboard::Key_J = ALLEGRO_KEY_J;
const Keyboard::KeyType Keyboard::Key_K = ALLEGRO_KEY_K;
const Keyboard::KeyType Keyboard::Key_L = ALLEGRO_KEY_L;
const Keyboard::KeyType Keyboard::Key_M = ALLEGRO_KEY_M;
const Keyboard::KeyType Keyboard::Key_N = ALLEGRO_KEY_N;
const Keyboard::KeyType Keyboard::Key_O = ALLEGRO_KEY_O;
const Keyboard::KeyType Keyboard::Key_P = ALLEGRO_KEY_P;
const Keyboard::KeyType Keyboard::Key_Q = ALLEGRO_KEY_Q;
const Keyboard::KeyType Keyboard::Key_R = ALLEGRO_KEY_R;
const Keyboard::KeyType Keyboard::Key_S = ALLEGRO_KEY_S;
const Keyboard::KeyType Keyboard::Key_T = ALLEGRO_KEY_T;
const Keyboard::KeyType Keyboard::Key_U = ALLEGRO_KEY_U;
const Keyboard::KeyType Keyboard::Key_V = ALLEGRO_KEY_V;
const Keyboard::KeyType Keyboard::Key_W = ALLEGRO_KEY_W;
const Keyboard::KeyType Keyboard::Key_X = ALLEGRO_KEY_X;
const Keyboard::KeyType Keyboard::Key_Y = ALLEGRO_KEY_Y;
const Keyboard::KeyType Keyboard::Key_Z = ALLEGRO_KEY_Z;
const Keyboard::KeyType Keyboard::Key_0 = ALLEGRO_KEY_0;
const Keyboard::KeyType Keyboard::Key_1 = ALLEGRO_KEY_1;
const Keyboard::KeyType Keyboard::Key_2 = ALLEGRO_KEY_2;
const Keyboard::KeyType Keyboard::Key_3 = ALLEGRO_KEY_3;
const Keyboard::KeyType Keyboard::Key_4 = ALLEGRO_KEY_4;
const Keyboard::KeyType Keyboard::Key_5 = ALLEGRO_KEY_5;
const Keyboard::KeyType Keyboard::Key_6 = ALLEGRO_KEY_6;
const Keyboard::KeyType Keyboard::Key_7 = ALLEGRO_KEY_7;
const Keyboard::KeyType Keyboard::Key_8 = ALLEGRO_KEY_8;
const Keyboard::KeyType Keyboard::Key_9 = ALLEGRO_KEY_9;
const Keyboard::KeyType Keyboard::Key_0_PAD = ALLEGRO_KEY_PAD_0;
const Keyboard::KeyType Keyboard::Key_1_PAD = ALLEGRO_KEY_PAD_1;
const Keyboard::KeyType Keyboard::Key_2_PAD = ALLEGRO_KEY_PAD_2;
const Keyboard::KeyType Keyboard::Key_3_PAD = ALLEGRO_KEY_PAD_3;
const Keyboard::KeyType Keyboard::Key_4_PAD = ALLEGRO_KEY_PAD_4;
const Keyboard::KeyType Keyboard::Key_5_PAD = ALLEGRO_KEY_PAD_5;
const Keyboard::KeyType Keyboard::Key_6_PAD = ALLEGRO_KEY_PAD_6;
const Keyboard::KeyType Keyboard::Key_7_PAD = ALLEGRO_KEY_PAD_7;
const Keyboard::KeyType Keyboard::Key_8_PAD = ALLEGRO_KEY_PAD_8;
const Keyboard::KeyType Keyboard::Key_9_PAD = ALLEGRO_KEY_PAD_9;
const Keyboard::KeyType Keyboard::Key_F1 = ALLEGRO_KEY_F1;
const Keyboard::KeyType Keyboard::Key_F2 = ALLEGRO_KEY_F2;
const Keyboard::KeyType Keyboard::Key_F3 = ALLEGRO_KEY_F3;
const Keyboard::KeyType Keyboard::Key_F4 = ALLEGRO_KEY_F4;
const Keyboard::KeyType Keyboard::Key_F5 = ALLEGRO_KEY_F5;
const Keyboard::KeyType Keyboard::Key_F6 = ALLEGRO_KEY_F6;
const Keyboard::KeyType Keyboard::Key_F7 = ALLEGRO_KEY_F7;
const Keyboard::KeyType Keyboard::Key_F8 = ALLEGRO_KEY_F8;
const Keyboard::KeyType Keyboard::Key_F9 = ALLEGRO_KEY_F9;
const Keyboard::KeyType Keyboard::Key_F10 = ALLEGRO_KEY_F10;
const Keyboard::KeyType Keyboard::Key_F11 = ALLEGRO_KEY_F11;
const Keyboard::KeyType Keyboard::Key_F12 = ALLEGRO_KEY_F12;
const Keyboard::KeyType Keyboard::Key_ESC = ALLEGRO_KEY_ESCAPE;
const Keyboard::KeyType Keyboard::Key_TILDE = ALLEGRO_KEY_TILDE;
const Keyboard::KeyType Keyboard::Key_MINUS = ALLEGRO_KEY_MINUS;
const Keyboard::KeyType Keyboard::Key_EQUALS = ALLEGRO_KEY_EQUALS;
const Keyboard::KeyType Keyboard::Key_BACKSPACE = ALLEGRO_KEY_BACKSPACE;
const Keyboard::KeyType Keyboard::Key_TAB = ALLEGRO_KEY_TAB;
const Keyboard::KeyType Keyboard::Key_OPENBRACE = ALLEGRO_KEY_OPENBRACE;
const Keyboard::KeyType Keyboard::Key_CLOSEBRACE = ALLEGRO_KEY_CLOSEBRACE;
const Keyboard::KeyType Keyboard::Key_ENTER = ALLEGRO_KEY_ENTER;
const Keyboard::KeyType Keyboard::Key_COLON = ALLEGRO_KEY_SEMICOLON2;
const Keyboard::KeyType Keyboard::Key_QUOTE = ALLEGRO_KEY_QUOTE;
const Keyboard::KeyType Keyboard::Key_BACKSLASH = ALLEGRO_KEY_BACKSLASH;
const Keyboard::KeyType Keyboard::Key_BACKSLASH2 = ALLEGRO_KEY_BACKSLASH2;
const Keyboard::KeyType Keyboard::Key_COMMA = ALLEGRO_KEY_COMMA;
const Keyboard::KeyType Keyboard::Key_STOP = ALLEGRO_KEY_FULLSTOP;
const Keyboard::KeyType Keyboard::Key_SLASH = ALLEGRO_KEY_SLASH;
const Keyboard::KeyType Keyboard::Key_SPACE = ALLEGRO_KEY_SPACE;
const Keyboard::KeyType Keyboard::Key_INSERT = ALLEGRO_KEY_INSERT;
const Keyboard::KeyType Keyboard::Key_DEL = ALLEGRO_KEY_DELETE;
const Keyboard::KeyType Keyboard::Key_HOME = ALLEGRO_KEY_HOME;
const Keyboard::KeyType Keyboard::Key_END = ALLEGRO_KEY_END;
const Keyboard::KeyType Keyboard::Key_PGUP = ALLEGRO_KEY_PGUP;
const Keyboard::KeyType Keyboard::Key_PGDN = ALLEGRO_KEY_PGDN;
const Keyboard::KeyType Keyboard::Key_LEFT = ALLEGRO_KEY_LEFT;
const Keyboard::KeyType Keyboard::Key_RIGHT = ALLEGRO_KEY_RIGHT;
const Keyboard::KeyType Keyboard::Key_UP = ALLEGRO_KEY_UP;
const Keyboard::KeyType Keyboard::Key_DOWN = ALLEGRO_KEY_DOWN;
const Keyboard::KeyType Keyboard::Key_SLASH_PAD = ALLEGRO_KEY_PAD_SLASH;
const Keyboard::KeyType Keyboard::Key_ASTERISK = ALLEGRO_KEY_PAD_ASTERISK;
const Keyboard::KeyType Keyboard::Key_MINUS_PAD = ALLEGRO_KEY_PAD_MINUS;
const Keyboard::KeyType Keyboard::Key_PLUS_PAD = ALLEGRO_KEY_PAD_PLUS;
const Keyboard::KeyType Keyboard::Key_DEL_PAD = ALLEGRO_KEY_PAD_DELETE;
const Keyboard::KeyType Keyboard::Key_ENTER_PAD = ALLEGRO_KEY_PAD_ENTER;
const Keyboard::KeyType Keyboard::Key_PRTSCR = ALLEGRO_KEY_PRINTSCREEN;
const Keyboard::KeyType Keyboard::Key_PAUSE = ALLEGRO_KEY_PAUSE;
const Keyboard::KeyType Keyboard::Key_ABNT_C1 = ALLEGRO_KEY_ABNT_C1;
const Keyboard::KeyType Keyboard::Key_YEN = ALLEGRO_KEY_YEN;
const Keyboard::KeyType Keyboard::Key_KANA = ALLEGRO_KEY_KANA;
const Keyboard::KeyType Keyboard::Key_CONVERT = ALLEGRO_KEY_CONVERT;
const Keyboard::KeyType Keyboard::Key_NOCONVERT = ALLEGRO_KEY_NOCONVERT;
const Keyboard::KeyType Keyboard::Key_AT = ALLEGRO_KEY_AT;
const Keyboard::KeyType Keyboard::Key_CIRCUMFLEX = ALLEGRO_KEY_CIRCUMFLEX;
const Keyboard::KeyType Keyboard::Key_COLON2 = ALLEGRO_KEY_COLON2;
const Keyboard::KeyType Keyboard::Key_KANJI = ALLEGRO_KEY_KANJI;
const Keyboard::KeyType Keyboard::Key_EQUALS_PAD = ALLEGRO_KEY_PAD_EQUALS;
const Keyboard::KeyType Keyboard::Key_BACKQUOTE = ALLEGRO_KEY_BACKQUOTE;
const Keyboard::KeyType Keyboard::Key_SEMICOLON = ALLEGRO_KEY_SEMICOLON;
const Keyboard::KeyType Keyboard::Key_COMMAND = ALLEGRO_KEY_COMMAND;
/*
const int Keyboard::Key_UNKNOWN1 = ALLEGRO_KEY_UNKNOWN1;
const int Keyboard::Key_UNKNOWN2 = ALLEGRO_KEY_UNKNOWN2;
const int Keyboard::Key_UNKNOWN3 = ALLEGRO_KEY_UNKNOWN3;
const int Keyboard::Key_UNKNOWN4 = ALLEGRO_KEY_UNKNOWN4;
const int Keyboard::Key_UNKNOWN5 = ALLEGRO_KEY_UNKNOWN5;
const int Keyboard::Key_UNKNOWN6 = ALLEGRO_KEY_UNKNOWN6;
const int Keyboard::Key_UNKNOWN7 = ALLEGRO_KEY_UNKNOWN7;
const int Keyboard::Key_UNKNOWN8 = ALLEGRO_KEY_UNKNOWN8;
*/
const Keyboard::KeyType Keyboard::Key_MODIFIERS = ALLEGRO_KEY_MODIFIERS;
const Keyboard::KeyType Keyboard::Key_LSHIFT = ALLEGRO_KEY_LSHIFT;
const Keyboard::KeyType Keyboard::Key_RSHIFT = ALLEGRO_KEY_RSHIFT;
const Keyboard::KeyType Keyboard::Key_LCONTROL = ALLEGRO_KEY_LCTRL;
const Keyboard::KeyType Keyboard::Key_RCONTROL = ALLEGRO_KEY_RCTRL;
const Keyboard::KeyType Keyboard::Key_ALT = ALLEGRO_KEY_ALT;
const Keyboard::KeyType Keyboard::Key_ALTGR = ALLEGRO_KEY_ALTGR;
const Keyboard::KeyType Keyboard::Key_LWIN = ALLEGRO_KEY_LWIN;
const Keyboard::KeyType Keyboard::Key_RWIN = ALLEGRO_KEY_RWIN;
const Keyboard::KeyType Keyboard::Key_MENU = ALLEGRO_KEY_MENU;
const Keyboard::KeyType Keyboard::Key_SCRLOCK = ALLEGRO_KEY_SCROLLLOCK;
const Keyboard::KeyType Keyboard::Key_NUMLOCK = ALLEGRO_KEY_NUMLOCK;
const Keyboard::KeyType Keyboard::Key_CAPSLOCK = ALLEGRO_KEY_CAPSLOCK;
Keyboard::Keyboard():
enableBuffer(false){
}
void Keyboard::disableKeyRepeat(){
/* TODO */
}
void Keyboard::enableKeyRepeat(){
/* TODO */
}
void Keyboard::readKeys(std::vector<int> & all_keys){
for (std::map<KeyType, KeyData>::iterator it = keyState.begin(); it != keyState.end(); it++){
KeyType key = it->first;
const KeyData & data = it->second;
if (data.enabled){
all_keys.push_back(key);
}
}
}
bool Keyboard::keypressed(){
/* TODO */
return false;
}
void Keyboard::poll(){
buffer.clear();
}
void Keyboard::clear(){
buffer.clear();
keyState.clear();
}
diff --git a/src/input/input-manager.cpp b/src/input/input-manager.cpp
index f2686879..380f7a51 100644
--- a/src/input/input-manager.cpp
+++ b/src/input/input-manager.cpp
@@ -1,152 +1,152 @@
-#include "input-manager.h"
-#include "util/configuration.h"
-#include "joystick.h"
-#include "util/events.h"
-#include "util/debug.h"
+#include "r-tech1/input/input-manager.h"
+#include "r-tech1/configuration.h"
+#include "r-tech1/input/joystick.h"
+#include "r-tech1/events.h"
+#include "r-tech1/debug.h"
#include <stdlib.h>
#include <vector>
using namespace std;
InputManager * InputManager::manager = 0;
InputManager::InputManager():
capture(0){
manager = this;
if (Configuration::isJoystickEnabled()){
installJoysticks();
}
}
void InputManager::installJoysticks(){
joysticks.clear();
for (int i = 0; i < Joystick::numberOfJoysticks(); i++){
joysticks[i] = Joystick::create(i);
}
}
const std::map<int, Util::ReferenceCount<Joystick> > & InputManager::getJoysticks(){
if (manager != NULL){
return manager->joysticks;
}
Global::debug(0) << "*BUG* Input manager not set up" << endl;
exit(0);
}
#ifdef PS3
#include <io/pad.h>
extern "C" int SDL_JoystickInit();
extern "C" int SDL_JoystickQuit();
#endif
static bool needJoystickUpdate(){
#ifdef PS3
padInfo pad;
if (ioPadGetInfo(&pad) == 0){
/* re-initialize the joystick stuff if we have a different
* number of joysticks according to lv2
*/
if (pad.connected != (unsigned) SDL_NumJoysticks()){
SDL_JoystickQuit();
SDL_JoystickInit();
return true;
}
}
#endif
return false;
}
void InputManager::checkJoysticks(){
if (needJoystickUpdate()){
installJoysticks();
}
}
InputManager::~InputManager(){
}
void InputManager::deferResizeEvents(bool defer){
if (manager != NULL){
manager->eventManager.deferResizeEvents(defer);
}
}
bool InputManager::anyInput(){
if (manager == 0){
Global::debug(0) << "*BUG* Input manager not set up" << endl;
exit(0);
}
return manager->_anyInput();
}
bool InputManager::_anyInput(){
if (keyboard.keypressed()){
return true;
}
for (map<int, Util::ReferenceCount<Joystick> >::iterator it = joysticks.begin(); it != joysticks.end(); it++){
Util::ReferenceCount<Joystick> joystick = it->second;
if (joystick != NULL){
return joystick->pressed();
}
}
return false;
}
void InputManager::waitForClear(){
manager->keyboard.clear();
while (anyInput()){
poll();
Util::rest(1);
}
}
void InputManager::waitForKeys(int key1, int key2, const InputSource & source){
InputMap<int> wait;
wait.set(key1, 0, false, 1);
wait.set(key2, 0, false, 1);
InputManager::waitForRelease(wait, source, 1);
InputManager::waitForPress(wait, source, 1);
InputManager::waitForRelease(wait, source, 1);
}
void InputManager::waitForKeys(int key, const InputSource & source){
InputMap<int> wait;
wait.set(key, 0, false, 1);
InputManager::waitForRelease(wait, source, 1);
InputManager::waitForPress(wait, source, 1);
InputManager::waitForRelease(wait, source, 1);
}
void InputManager::poll(){
if (manager == 0){
Global::debug(0) << "*BUG* Input manager not set up" << endl;
exit(0);
}
return manager->_poll();
}
int InputManager::readKey(){
return manager->_readKey();
}
int InputManager::_readKey(){
std::vector<int> keys;
do{
keyboard.readKeys(keys);
if (keys.size() == 0){
Util::rest(1);
poll();
}
} while (keys.size() == 0);
return keys.front();
}
void InputManager::_poll(){
#ifdef PS3
checkJoysticks();
#endif
eventManager.run(keyboard, joysticks);
}
diff --git a/src/input/input-source.cpp b/src/input/input-source.cpp
index a57c5695..a804cbf2 100644
--- a/src/input/input-source.cpp
+++ b/src/input/input-source.cpp
@@ -1,61 +1,61 @@
-#include "input-source.h"
+#include "r-tech1/input/input-source.h"
using std::vector;
InputSource::InputSource(bool default_){
if (default_){
keyboard.push_back(0);
keyboard.push_back(1);
joystick.push_back(0);
joystick.push_back(1);
}
}
InputSource::InputSource(const InputSource & copy):
keyboard(copy.keyboard),
joystick(copy.joystick){
}
InputSource::InputSource(const vector<int> & keyboard, const vector<int> & joystick):
keyboard(keyboard),
joystick(joystick){
}
InputSource & InputSource::operator=(const InputSource & copy){
this->keyboard = copy.keyboard;
this->joystick = copy.joystick;
return *this;
}
InputSource InputSource::addKeyboard(int keyboard){
vector<int> keyboardCopy(this->keyboard);
keyboardCopy.push_back(keyboard);
return InputSource(keyboardCopy, joystick);
}
InputSource InputSource::addJoystick(int joystick){
vector<int> joystickCopy(this->joystick);
joystickCopy.push_back(joystick);
return InputSource(keyboard, joystickCopy);
}
InputSource::~InputSource(){
}
bool InputSource::useKeyboard() const {
return keyboard.size() > 0;
}
bool InputSource::useJoystick() const {
return joystick.size() > 0;
}
const vector<int> & InputSource::getKeyboard() const {
return keyboard;
}
const vector<int> & InputSource::getJoystick() const {
return joystick;
}
diff --git a/src/input/joystick.cpp b/src/input/joystick.cpp
index 0421952d..cb839730 100644
--- a/src/input/joystick.cpp
+++ b/src/input/joystick.cpp
@@ -1,222 +1,209 @@
#include <stdlib.h>
-#include "util/configuration.h"
-#include "joystick.h"
+#include "r-tech1/configuration.h"
+#include "r-tech1/input/joystick.h"
/*
#ifdef LINUX
#include "linux_joystick.h"
#endif
*/
-#ifdef USE_ALLEGRO
-#include "allegro/allegro-joystick.h"
-#endif
#ifdef USE_ALLEGRO5
-#include "allegro5/joystick.h"
-#endif
-#ifdef USE_SDL
-#ifdef WII
-#include "wii/joystick.h"
-#include "sdl/joystick.h"
-#elif MINPSPW
-#include "psp/joystick.h"
-#else
-#include "sdl/joystick.h"
-#endif
+#include "r-tech1/input/allegro5/joystick.h"
#endif
JoystickListener::JoystickListener(){
}
JoystickListener::~JoystickListener(){
}
Joystick * Joystick::create(int i){
#ifdef USE_ALLEGRO
return new AllegroJoystick();
#endif
#ifdef USE_SDL
#ifdef WII
return new SDLJoystick(i);
// return new WiiJoystick();
#elif MINPSPW
return new PSPJoystick();
#else
return new SDLJoystick(i);
#endif
#endif
#ifdef USE_ALLEGRO5
return new Allegro5Joystick(i);
#endif
/* TODO: support allegro5 joystick */
/*
#ifdef LINUX
return new LinuxJoystick();
#endif
return NULL;
*/
return NULL;
}
Joystick::Joystick(){
}
Joystick::~Joystick(){
}
void Joystick::readCustomButton(Key key){
int button;
if (Configuration::getCustomButton(key, getDeviceId(), getName(), button)){
customButton[button] = key;
if (customAxis.find(key) != customAxis.end()){
customAxis.erase(key);
}
}
}
void Joystick::readCustomButtons(){
readCustomButton(Up);
readCustomButton(Down);
readCustomButton(Left);
readCustomButton(Right);
readCustomButton(Button1);
readCustomButton(Button2);
readCustomButton(Button3);
readCustomButton(Button4);
readCustomButton(Button5);
readCustomButton(Button6);
readCustomButton(Quit);
readCustomButton(Start);
}
void Joystick::readCustomAxis(Key key){
int stick, axis;
double low, high;
if (Configuration::getCustomAxis(key, getDeviceId(), getName(), stick, axis, low, high)){
Axis & use = customAxis[key];
use.stick = stick;
use.axis = axis;
use.low = low;
use.high = high;
use.on = false;
eraseCustomButton(key);
}
}
void Joystick::readCustomAxes(){
readCustomAxis(Up);
readCustomAxis(Down);
readCustomAxis(Left);
readCustomAxis(Right);
readCustomAxis(Button1);
readCustomAxis(Button2);
readCustomAxis(Button3);
readCustomAxis(Button4);
readCustomAxis(Button5);
readCustomAxis(Button6);
readCustomAxis(Quit);
readCustomAxis(Start);
}
const char * Joystick::keyToName(Key key){
switch (key){
case Invalid: return "Invalid";
case Up: return "Up";
case Down: return "Down";
case Left: return "Left";
case Right: return "Right";
case Button1: return "Button1";
case Button2: return "Button2";
case Button3: return "Button3";
case Button4: return "Button4";
- case Button5: return "Button5";
- case Button6: return "Button6";
- case Start: return "Start";
+ case Button5: return "Button5";
+ case Button6: return "Button6";
+ case Start: return "Start";
case Quit: return "Quit";
}
return "Unknown";
}
bool Joystick::pressed() const {
return events.size() > 0;
}
void Joystick::pressButton(int button){
}
void Joystick::releaseButton(int button){
}
void Joystick::axisMotion(int axis, int motion){
}
void Joystick::hatMotion(int motion){
}
void Joystick::setCustomButton(int button, Key key){
Configuration::setCustomButton(key, getDeviceId(), getName(), button);
customButton[button] = key;
/* Can only have one unique button/axis */
if (customAxis.find(key) != customAxis.end()){
customAxis.erase(key);
}
}
void Joystick::eraseCustomButton(Key key){
std::vector<int> keys;
for (std::map<int, Key>::iterator it = customButton.begin(); it != customButton.end(); it++){
if (it->second == key){
keys.push_back(it->first);
}
}
for (std::vector<int>::iterator it = keys.begin(); it != keys.end(); it++){
customButton.erase(*it);
}
}
void Joystick::setCustomAxis(Key key, int stick, int axis, double low, double high){
Configuration::setCustomAxis(key, getDeviceId(), getName(), stick, axis, low, high);
Axis & use = customAxis[key];
use.stick = stick;
use.axis = axis;
use.low = low;
use.high = high;
use.on = false;
/* Can only have one unique button/axis */
eraseCustomButton(key);
}
bool Joystick::getAxis(Key key, int & stick, int & axis, double & low, double & high) const {
std::map<Key, Axis>::const_iterator find = customAxis.find(key);
if (find != customAxis.end()){
const Axis & use = find->second;
stick = use.stick;
axis = use.axis;
low = use.low;
high = use.high;
return true;
} else {
return false;
}
}
void Joystick::addListener(JoystickListener * listener){
listeners.insert(listener);
}
void Joystick::removeListener(JoystickListener * listener){
listeners.erase(listener);
}
std::set<JoystickListener*> Joystick::listeners;
const std::set<JoystickListener*> & Joystick::getListeners(){
return listeners;
}
diff --git a/src/input/keyboard.cpp b/src/input/keyboard.cpp
index 71a3489b..b5d1af73 100644
--- a/src/input/keyboard.cpp
+++ b/src/input/keyboard.cpp
@@ -1,477 +1,471 @@
-#ifdef USE_ALLEGRO
-#include "allegro/keyboard.cpp"
-#endif
-#ifdef USE_SDL
-#include "sdl/keyboard.cpp"
-#endif
#ifdef USE_ALLEGRO5
#include "allegro5/keyboard.cpp"
#endif
std::vector<bool> Keyboard::repeatState;
std::set<KeyboardListener*> Keyboard::listeners;
bool Keyboard::isNumber( int key ){
- return key == Key_0 ||
- key == Key_1 ||
- key == Key_2 ||
- key == Key_3 ||
- key == Key_4 ||
- key == Key_5 ||
- key == Key_6 ||
- key == Key_7 ||
- key == Key_8 ||
- key == Key_9;
+ return key == Key_0 ||
+ key == Key_1 ||
+ key == Key_2 ||
+ key == Key_3 ||
+ key == Key_4 ||
+ key == Key_5 ||
+ key == Key_6 ||
+ key == Key_7 ||
+ key == Key_8 ||
+ key == Key_9;
}
bool Keyboard::isChar( int key ){
- return key == Key_A ||
- key == Key_B ||
- key == Key_C ||
- key == Key_D ||
- key == Key_E ||
- key == Key_F ||
- key == Key_G ||
- key == Key_H ||
- key == Key_I ||
- key == Key_J ||
- key == Key_K ||
- key == Key_L ||
- key == Key_M ||
- key == Key_N ||
- key == Key_O ||
- key == Key_P ||
- key == Key_Q ||
- key == Key_R ||
- key == Key_S ||
- key == Key_T ||
- key == Key_U ||
- key == Key_V ||
- key == Key_W ||
- key == Key_X ||
- key == Key_Y ||
- key == Key_Z ||
+ return key == Key_A ||
+ key == Key_B ||
+ key == Key_C ||
+ key == Key_D ||
+ key == Key_E ||
+ key == Key_F ||
+ key == Key_G ||
+ key == Key_H ||
+ key == Key_I ||
+ key == Key_J ||
+ key == Key_K ||
+ key == Key_L ||
+ key == Key_M ||
+ key == Key_N ||
+ key == Key_O ||
+ key == Key_P ||
+ key == Key_Q ||
+ key == Key_R ||
+ key == Key_S ||
+ key == Key_T ||
+ key == Key_U ||
+ key == Key_V ||
+ key == Key_W ||
+ key == Key_X ||
+ key == Key_Y ||
+ key == Key_Z ||
key == Key_MINUS;
}
bool Keyboard::isAlpha( int key ){
- return isNumber( key ) || isChar( key );
+ return isNumber( key ) || isChar( key );
}
const char * Keyboard::keyToName( int key ){
- switch ( key ){
- case Keyboard::Key_A : return "A";
- case Keyboard::Key_B : return "B";
- case Keyboard::Key_C : return "C";
- case Keyboard::Key_D : return "D";
- case Keyboard::Key_E : return "E";
- case Keyboard::Key_F : return "F";
- case Keyboard::Key_G : return "G";
- case Keyboard::Key_H : return "H";
- case Keyboard::Key_I : return "I";
- case Keyboard::Key_J : return "J";
- case Keyboard::Key_K : return "K";
- case Keyboard::Key_L : return "L";
- case Keyboard::Key_M : return "M";
- case Keyboard::Key_N : return "N";
- case Keyboard::Key_O : return "O";
- case Keyboard::Key_P : return "P";
- case Keyboard::Key_Q : return "Q";
- case Keyboard::Key_R : return "R";
- case Keyboard::Key_S : return "S";
- case Keyboard::Key_T : return "T";
- case Keyboard::Key_U : return "U";
- case Keyboard::Key_V : return "V";
- case Keyboard::Key_W : return "W";
- case Keyboard::Key_X : return "X";
- case Keyboard::Key_Y : return "Y";
- case Keyboard::Key_Z : return "Z";
- case Keyboard::Key_0 : return "0";
- case Keyboard::Key_1 : return "1";
- case Keyboard::Key_2 : return "2";
- case Keyboard::Key_3 : return "3";
- case Keyboard::Key_4 : return "4";
- case Keyboard::Key_5 : return "5";
- case Keyboard::Key_6 : return "6";
- case Keyboard::Key_7 : return "7";
- case Keyboard::Key_8 : return "8";
- case Keyboard::Key_9 : return "9";
- case Keyboard::Key_0_PAD : return "0_PAD";
- case Keyboard::Key_1_PAD : return "1_PAD";
- case Keyboard::Key_2_PAD : return "2_PAD";
- case Keyboard::Key_3_PAD : return "3_PAD";
- case Keyboard::Key_4_PAD : return "4_PAD";
- case Keyboard::Key_5_PAD : return "5_PAD";
- case Keyboard::Key_6_PAD : return "6_PAD";
- case Keyboard::Key_7_PAD : return "7_PAD";
- case Keyboard::Key_8_PAD : return "8_PAD";
- case Keyboard::Key_9_PAD : return "9_PAD";
- case Keyboard::Key_F1 : return "F1";
- case Keyboard::Key_F2 : return "F2";
- case Keyboard::Key_F3 : return "F3";
- case Keyboard::Key_F4 : return "F4";
- case Keyboard::Key_F5 : return "F5";
- case Keyboard::Key_F6 : return "F6";
- case Keyboard::Key_F7 : return "F7";
- case Keyboard::Key_F8 : return "F8";
- case Keyboard::Key_F9 : return "F9";
- case Keyboard::Key_F10 : return "F10";
- case Keyboard::Key_F11 : return "F11";
- case Keyboard::Key_F12 : return "F12";
- case Keyboard::Key_ESC : return "ESC";
- case Keyboard::Key_TILDE : return "~";
- case Keyboard::Key_MINUS : return "-";
- case Keyboard::Key_EQUALS : return "=";
- case Keyboard::Key_BACKSPACE : return "BACKSPACE";
- case Keyboard::Key_TAB : return "TAB";
- case Keyboard::Key_OPENBRACE : return "OPENBRACE";
- case Keyboard::Key_CLOSEBRACE : return "CLOSEBRACE";
- case Keyboard::Key_ENTER : return "ENTER";
- case Keyboard::Key_COLON : return "COLON";
- case Keyboard::Key_QUOTE : return "QUOTE";
- case Keyboard::Key_BACKSLASH : return "BACKSLASH";
- case Keyboard::Key_BACKSLASH2 : return "BACKSLASH2";
- case Keyboard::Key_COMMA : return "COMMA";
- case Keyboard::Key_STOP : return ".";
- case Keyboard::Key_SLASH : return "SLASH";
- case Keyboard::Key_SPACE : return "SPACE";
- case Keyboard::Key_INSERT : return "INSERT";
- case Keyboard::Key_DEL : return "DEL";
- case Keyboard::Key_HOME : return "HOME";
- case Keyboard::Key_END : return "END";
- case Keyboard::Key_PGUP : return "PGUP";
- case Keyboard::Key_PGDN : return "PGDN";
- case Keyboard::Key_LEFT : return "LEFT";
- case Keyboard::Key_RIGHT : return "RIGHT";
- case Keyboard::Key_UP : return "UP";
- case Keyboard::Key_DOWN : return "DOWN";
- case Keyboard::Key_SLASH_PAD : return "SLASH_PAD";
- case Keyboard::Key_ASTERISK : return "ASTERISK";
- case Keyboard::Key_MINUS_PAD : return "MINUS_PAD";
- case Keyboard::Key_PLUS_PAD : return "PLUS_PAD";
- case Keyboard::Key_DEL_PAD : return "DEL_PAD";
- case Keyboard::Key_ENTER_PAD : return "ENTER_PAD";
- case Keyboard::Key_PRTSCR : return "PRTSCR";
- case Keyboard::Key_PAUSE : return "PAUSE";
- case Keyboard::Key_ABNT_C1 : return "ABNT_C1";
- case Keyboard::Key_YEN : return "YEN";
- case Keyboard::Key_KANA : return "KANA";
- case Keyboard::Key_CONVERT : return "CONVERT";
- case Keyboard::Key_NOCONVERT : return "NOCONVERT";
- case Keyboard::Key_AT : return "AT";
- case Keyboard::Key_CIRCUMFLEX : return "CIRCUMFLEX";
- case Keyboard::Key_COLON2 : return "COLON2";
- case Keyboard::Key_KANJI : return "KANJI";
- case Keyboard::Key_EQUALS_PAD : return "EQUALS_PAD";
- case Keyboard::Key_BACKQUOTE : return "BACKQUOTE";
- case Keyboard::Key_SEMICOLON : return "SEMICOLON";
- case Keyboard::Key_COMMAND : return "COMMAND";
- /*
- case Keyboard::Key_UNKNOWN1 : return "UNKNOWN1";
- case Keyboard::Key_UNKNOWN2 : return "UNKNOWN2";
- case Keyboard::Key_UNKNOWN3 : return "UNKNOWN3";
- case Keyboard::Key_UNKNOWN4 : return "UNKNOWN4";
- case Keyboard::Key_UNKNOWN5 : return "UNKNOWN5";
- case Keyboard::Key_UNKNOWN6 : return "UNKNOWN6";
- case Keyboard::Key_UNKNOWN7 : return "UNKNOWN7";
- case Keyboard::Key_UNKNOWN8 : return "UNKNOWN8";
- */
- // case Keyboard::Key_MODIFIERS : return "MODIFIERS";
- case Keyboard::Key_LSHIFT : return "LSHIFT";
- case Keyboard::Key_RSHIFT : return "RSHIFT";
- case Keyboard::Key_LCONTROL : return "LCONTROL";
- case Keyboard::Key_RCONTROL : return "RCONTROL";
- case Keyboard::Key_ALT : return "ALT";
- case Keyboard::Key_ALTGR : return "ALTGR";
- case Keyboard::Key_LWIN : return "LWIN";
- case Keyboard::Key_RWIN : return "RWIN";
- case Keyboard::Key_MENU : return "MENU";
- case Keyboard::Key_SCRLOCK : return "SCRLOCK";
- case Keyboard::Key_NUMLOCK : return "NUMLOCK";
- case Keyboard::Key_CAPSLOCK : return "CAPSLOCK";
- default : return "Unknown key";
- }
+ switch ( key ){
+ case Keyboard::Key_A : return "A";
+ case Keyboard::Key_B : return "B";
+ case Keyboard::Key_C : return "C";
+ case Keyboard::Key_D : return "D";
+ case Keyboard::Key_E : return "E";
+ case Keyboard::Key_F : return "F";
+ case Keyboard::Key_G : return "G";
+ case Keyboard::Key_H : return "H";
+ case Keyboard::Key_I : return "I";
+ case Keyboard::Key_J : return "J";
+ case Keyboard::Key_K : return "K";
+ case Keyboard::Key_L : return "L";
+ case Keyboard::Key_M : return "M";
+ case Keyboard::Key_N : return "N";
+ case Keyboard::Key_O : return "O";
+ case Keyboard::Key_P : return "P";
+ case Keyboard::Key_Q : return "Q";
+ case Keyboard::Key_R : return "R";
+ case Keyboard::Key_S : return "S";
+ case Keyboard::Key_T : return "T";
+ case Keyboard::Key_U : return "U";
+ case Keyboard::Key_V : return "V";
+ case Keyboard::Key_W : return "W";
+ case Keyboard::Key_X : return "X";
+ case Keyboard::Key_Y : return "Y";
+ case Keyboard::Key_Z : return "Z";
+ case Keyboard::Key_0 : return "0";
+ case Keyboard::Key_1 : return "1";
+ case Keyboard::Key_2 : return "2";
+ case Keyboard::Key_3 : return "3";
+ case Keyboard::Key_4 : return "4";
+ case Keyboard::Key_5 : return "5";
+ case Keyboard::Key_6 : return "6";
+ case Keyboard::Key_7 : return "7";
+ case Keyboard::Key_8 : return "8";
+ case Keyboard::Key_9 : return "9";
+ case Keyboard::Key_0_PAD : return "0_PAD";
+ case Keyboard::Key_1_PAD : return "1_PAD";
+ case Keyboard::Key_2_PAD : return "2_PAD";
+ case Keyboard::Key_3_PAD : return "3_PAD";
+ case Keyboard::Key_4_PAD : return "4_PAD";
+ case Keyboard::Key_5_PAD : return "5_PAD";
+ case Keyboard::Key_6_PAD : return "6_PAD";
+ case Keyboard::Key_7_PAD : return "7_PAD";
+ case Keyboard::Key_8_PAD : return "8_PAD";
+ case Keyboard::Key_9_PAD : return "9_PAD";
+ case Keyboard::Key_F1 : return "F1";
+ case Keyboard::Key_F2 : return "F2";
+ case Keyboard::Key_F3 : return "F3";
+ case Keyboard::Key_F4 : return "F4";
+ case Keyboard::Key_F5 : return "F5";
+ case Keyboard::Key_F6 : return "F6";
+ case Keyboard::Key_F7 : return "F7";
+ case Keyboard::Key_F8 : return "F8";
+ case Keyboard::Key_F9 : return "F9";
+ case Keyboard::Key_F10 : return "F10";
+ case Keyboard::Key_F11 : return "F11";
+ case Keyboard::Key_F12 : return "F12";
+ case Keyboard::Key_ESC : return "ESC";
+ case Keyboard::Key_TILDE : return "~";
+ case Keyboard::Key_MINUS : return "-";
+ case Keyboard::Key_EQUALS : return "=";
+ case Keyboard::Key_BACKSPACE : return "BACKSPACE";
+ case Keyboard::Key_TAB : return "TAB";
+ case Keyboard::Key_OPENBRACE : return "OPENBRACE";
+ case Keyboard::Key_CLOSEBRACE : return "CLOSEBRACE";
+ case Keyboard::Key_ENTER : return "ENTER";
+ case Keyboard::Key_COLON : return "COLON";
+ case Keyboard::Key_QUOTE : return "QUOTE";
+ case Keyboard::Key_BACKSLASH : return "BACKSLASH";
+ case Keyboard::Key_BACKSLASH2 : return "BACKSLASH2";
+ case Keyboard::Key_COMMA : return "COMMA";
+ case Keyboard::Key_STOP : return ".";
+ case Keyboard::Key_SLASH : return "SLASH";
+ case Keyboard::Key_SPACE : return "SPACE";
+ case Keyboard::Key_INSERT : return "INSERT";
+ case Keyboard::Key_DEL : return "DEL";
+ case Keyboard::Key_HOME : return "HOME";
+ case Keyboard::Key_END : return "END";
+ case Keyboard::Key_PGUP : return "PGUP";
+ case Keyboard::Key_PGDN : return "PGDN";
+ case Keyboard::Key_LEFT : return "LEFT";
+ case Keyboard::Key_RIGHT : return "RIGHT";
+ case Keyboard::Key_UP : return "UP";
+ case Keyboard::Key_DOWN : return "DOWN";
+ case Keyboard::Key_SLASH_PAD : return "SLASH_PAD";
+ case Keyboard::Key_ASTERISK : return "ASTERISK";
+ case Keyboard::Key_MINUS_PAD : return "MINUS_PAD";
+ case Keyboard::Key_PLUS_PAD : return "PLUS_PAD";
+ case Keyboard::Key_DEL_PAD : return "DEL_PAD";
+ case Keyboard::Key_ENTER_PAD : return "ENTER_PAD";
+ case Keyboard::Key_PRTSCR : return "PRTSCR";
+ case Keyboard::Key_PAUSE : return "PAUSE";
+ case Keyboard::Key_ABNT_C1 : return "ABNT_C1";
+ case Keyboard::Key_YEN : return "YEN";
+ case Keyboard::Key_KANA : return "KANA";
+ case Keyboard::Key_CONVERT : return "CONVERT";
+ case Keyboard::Key_NOCONVERT : return "NOCONVERT";
+ case Keyboard::Key_AT : return "AT";
+ case Keyboard::Key_CIRCUMFLEX : return "CIRCUMFLEX";
+ case Keyboard::Key_COLON2 : return "COLON2";
+ case Keyboard::Key_KANJI : return "KANJI";
+ case Keyboard::Key_EQUALS_PAD : return "EQUALS_PAD";
+ case Keyboard::Key_BACKQUOTE : return "BACKQUOTE";
+ case Keyboard::Key_SEMICOLON : return "SEMICOLON";
+ case Keyboard::Key_COMMAND : return "COMMAND";
+ /*
+ case Keyboard::Key_UNKNOWN1 : return "UNKNOWN1";
+ case Keyboard::Key_UNKNOWN2 : return "UNKNOWN2";
+ case Keyboard::Key_UNKNOWN3 : return "UNKNOWN3";
+ case Keyboard::Key_UNKNOWN4 : return "UNKNOWN4";
+ case Keyboard::Key_UNKNOWN5 : return "UNKNOWN5";
+ case Keyboard::Key_UNKNOWN6 : return "UNKNOWN6";
+ case Keyboard::Key_UNKNOWN7 : return "UNKNOWN7";
+ case Keyboard::Key_UNKNOWN8 : return "UNKNOWN8";
+ */
+ // case Keyboard::Key_MODIFIERS : return "MODIFIERS";
+ case Keyboard::Key_LSHIFT : return "LSHIFT";
+ case Keyboard::Key_RSHIFT : return "RSHIFT";
+ case Keyboard::Key_LCONTROL : return "LCONTROL";
+ case Keyboard::Key_RCONTROL : return "RCONTROL";
+ case Keyboard::Key_ALT : return "ALT";
+ case Keyboard::Key_ALTGR : return "ALTGR";
+ case Keyboard::Key_LWIN : return "LWIN";
+ case Keyboard::Key_RWIN : return "RWIN";
+ case Keyboard::Key_MENU : return "MENU";
+ case Keyboard::Key_SCRLOCK : return "SCRLOCK";
+ case Keyboard::Key_NUMLOCK : return "NUMLOCK";
+ case Keyboard::Key_CAPSLOCK : return "CAPSLOCK";
+ default : return "Unknown key";
+ }
}
void Keyboard::setDelay( const int key, const int delay ){
- key_delay[ key ] = delay;
+ key_delay[ key ] = delay;
}
-
+
void Keyboard::setAllDelay( const int delay ){
setDelay( Key_A, delay );
setDelay( Key_B, delay );
setDelay( Key_C, delay );
setDelay( Key_D, delay );
setDelay( Key_E, delay );
setDelay( Key_F, delay );
setDelay( Key_G, delay );
setDelay( Key_H, delay );
setDelay( Key_I, delay );
setDelay( Key_J, delay );
setDelay( Key_K, delay );
setDelay( Key_L, delay );
setDelay( Key_M, delay );
setDelay( Key_N, delay );
setDelay( Key_O, delay );
setDelay( Key_P, delay );
setDelay( Key_Q, delay );
setDelay( Key_R, delay );
setDelay( Key_S, delay );
setDelay( Key_T, delay );
setDelay( Key_U, delay );
setDelay( Key_V, delay );
setDelay( Key_W, delay );
setDelay( Key_X, delay );
setDelay( Key_Y, delay );
setDelay( Key_Z, delay );
setDelay( Key_0, delay );
setDelay( Key_1, delay );
setDelay( Key_2, delay );
setDelay( Key_3, delay );
setDelay( Key_4, delay );
setDelay( Key_5, delay );
setDelay( Key_6, delay );
setDelay( Key_7, delay );
setDelay( Key_8, delay );
setDelay( Key_9, delay );
setDelay( Key_0_PAD, delay );
setDelay( Key_1_PAD, delay );
setDelay( Key_2_PAD, delay );
setDelay( Key_3_PAD, delay );
setDelay( Key_4_PAD, delay );
setDelay( Key_5_PAD, delay );
setDelay( Key_6_PAD, delay );
setDelay( Key_7_PAD, delay );
setDelay( Key_8_PAD, delay );
setDelay( Key_9_PAD, delay );
setDelay( Key_F1, delay );
setDelay( Key_F2, delay );
setDelay( Key_F3, delay );
setDelay( Key_F4, delay );
setDelay( Key_F5, delay );
setDelay( Key_F6, delay );
setDelay( Key_F7, delay );
setDelay( Key_F8, delay );
setDelay( Key_F9, delay );
setDelay( Key_F10, delay );
setDelay( Key_F11, delay );
setDelay( Key_F12, delay );
setDelay( Key_ESC, delay );
setDelay( Key_TILDE, delay );
setDelay( Key_MINUS, delay );
setDelay( Key_EQUALS, delay );
setDelay( Key_BACKSPACE, delay );
setDelay( Key_TAB, delay );
setDelay( Key_OPENBRACE, delay );
setDelay( Key_CLOSEBRACE, delay );
setDelay( Key_ENTER, delay );
setDelay( Key_COLON, delay );
setDelay( Key_QUOTE, delay );
setDelay( Key_BACKSLASH, delay );
setDelay( Key_BACKSLASH2, delay );
setDelay( Key_COMMA, delay );
setDelay( Key_STOP, delay );
setDelay( Key_SLASH, delay );
setDelay( Key_SPACE, delay );
setDelay( Key_INSERT, delay );
setDelay( Key_DEL, delay );
setDelay( Key_HOME, delay );
setDelay( Key_END, delay );
setDelay( Key_PGUP, delay );
setDelay( Key_PGDN, delay );
setDelay( Key_LEFT, delay );
setDelay( Key_RIGHT, delay );
setDelay( Key_UP, delay );
setDelay( Key_DOWN, delay );
setDelay( Key_SLASH_PAD, delay );
setDelay( Key_ASTERISK, delay );
setDelay( Key_MINUS_PAD, delay );
setDelay( Key_PLUS_PAD, delay );
setDelay( Key_DEL_PAD, delay );
setDelay( Key_ENTER_PAD, delay );
setDelay( Key_PRTSCR, delay );
setDelay( Key_PAUSE, delay );
setDelay( Key_ABNT_C1, delay );
setDelay( Key_YEN, delay );
setDelay( Key_KANA, delay );
setDelay( Key_CONVERT, delay );
setDelay( Key_NOCONVERT, delay );
setDelay( Key_AT, delay );
setDelay( Key_CIRCUMFLEX, delay );
setDelay( Key_COLON2, delay );
setDelay( Key_KANJI, delay );
setDelay( Key_EQUALS_PAD, delay );
setDelay( Key_BACKQUOTE, delay );
setDelay( Key_SEMICOLON, delay );
setDelay( Key_COMMAND, delay );
/*
setDelay( Key_UNKNOWN1, delay );
setDelay( Key_UNKNOWN2, delay );
setDelay( Key_UNKNOWN3, delay );
setDelay( Key_UNKNOWN4, delay );
setDelay( Key_UNKNOWN5, delay );
setDelay( Key_UNKNOWN6, delay );
setDelay( Key_UNKNOWN7, delay );
setDelay( Key_UNKNOWN8, delay );
*/
setDelay( Key_MODIFIERS, delay );
setDelay( Key_LSHIFT, delay );
setDelay( Key_RSHIFT, delay );
setDelay( Key_LCONTROL, delay );
setDelay( Key_RCONTROL, delay );
setDelay( Key_ALT, delay );
setDelay( Key_ALTGR, delay );
setDelay( Key_LWIN, delay );
setDelay( Key_RWIN, delay );
setDelay( Key_MENU, delay );
setDelay( Key_SCRLOCK, delay );
setDelay( Key_NUMLOCK, delay );
setDelay( Key_CAPSLOCK, delay );
}
void Keyboard::press(KeyType key, unicode_t unicode){
std::set<KeyboardListener*> listeners = getListeners();
for (std::set<KeyboardListener*>::iterator it = listeners.begin(); it != listeners.end(); it++){
(*it)->press(this, key, unicode);
}
keyState[key].key = key;
keyState[key].unicode = unicode;
keyState[key].enabled = true;
// if (enableBuffer){
buffer.push_back(keyState[key]);
// }
/*
KeyData data(key, unicode, true);
for (std::vector<Observer>::iterator it = observers.begin(); it != observers.end(); it++){
Observer observer = (*it);
observer.callback(data, observer.extra);
}
*/
}
void Keyboard::release(KeyType key){
std::set<KeyboardListener*> listeners = getListeners();
for (std::set<KeyboardListener*>::iterator it = listeners.begin(); it != listeners.end(); it++){
(*it)->release(this, key);
}
keyState[key].enabled = false;
buffer.push_back(keyState[key]);
/*
KeyData data(key, 0, false);
for (std::vector<Observer>::iterator it = observers.begin(); it != observers.end(); it++){
Observer observer = (*it);
observer.callback(data, observer.extra);
}
*/
}
void Keyboard::readBufferedKeys(std::vector<int> & keys){
for (std::vector<KeyData>::iterator it = buffer.begin(); it != buffer.end(); it++){
const KeyData & data = *it;
keys.push_back(data.key);
}
}
std::vector<Keyboard::KeyData> Keyboard::readData(){
std::vector<Keyboard::KeyData> out;
for (std::map<KeyType, KeyData>::iterator it = keyState.begin(); it != keyState.end(); it++){
KeyType key = it->first;
const KeyData & data = it->second;
if (data.enabled){
out.push_back(data);
}
}
return out;
}
std::vector<Keyboard::unicode_t> Keyboard::readText(){
std::vector<Keyboard::unicode_t> out;
for (std::map<KeyType, KeyData>::iterator it = keyState.begin(); it != keyState.end(); it++){
KeyType key = it->first;
const KeyData & data = it->second;
if (data.enabled){
out.push_back(data.unicode);
}
}
return out;
}
bool Keyboard::getRepeatState(){
if (repeatState.size() > 0){
return repeatState.back();
}
return true;
}
void Keyboard::pushRepeatState(bool enabled){
if (enabled){
enableKeyRepeat();
} else {
disableKeyRepeat();
}
repeatState.push_back(enabled);
}
void Keyboard::popRepeatState(){
if (repeatState.size() > 0){
bool last = repeatState.back();
repeatState.pop_back();
bool enabled = true;
if (repeatState.size() > 0){
enabled = repeatState.back();
}
if (enabled != last){
if (enabled){
enableKeyRepeat();
} else {
disableKeyRepeat();
}
}
}
}
bool Keyboard::haveKeyboard(){
#if defined(WII) || defined(PS3) || defined(XENON)
return false;
#endif
return true;
}
KeyboardListener::KeyboardListener(){
}
KeyboardListener::~KeyboardListener(){
}
void Keyboard::addListener(KeyboardListener * listener){
listeners.insert(listener);
}
void Keyboard::removeListener(KeyboardListener * listener){
listeners.erase(listener);
}
const std::set<KeyboardListener*> & Keyboard::getListeners(){
return listeners;
}
/*
void Keyboard::addObserver(ObserverCallback observer, void * data){
observers.push_back(Observer(observer, data));
}
void Keyboard::removeObserver(ObserverCallback observer, void * data){
for (std::vector<Observer>::iterator it = observers.begin(); it != observers.end(); it++){
const Observer & what = *it;
if (what.callback == observer && what.extra == data){
observers.erase(it);
break;
}
}
}
*/
diff --git a/src/input/linux_joystick.cpp b/src/input/linux_joystick.cpp
index adc5bb09..94c979b9 100644
--- a/src/input/linux_joystick.cpp
+++ b/src/input/linux_joystick.cpp
@@ -1,390 +1,390 @@
#ifdef LINUX
/* based on
* jstest.c Version 1.2
*
* Copyright (c) 1996-1999 Vojtech Pavlik
*
* Sponsored by SuSE
*/
#include <sys/ioctl.h>
#include <sys/time.h>
#include <sys/types.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <iostream>
#include <sstream>
#include <linux/input.h>
#include <linux/joystick.h>
#include "linux_joystick.h"
-#include "util/debug.h"
+#include "r-tech1/debug.h"
using namespace std;
static const char *axis_names[ABS_MAX + 1] = {
"X", "Y", "Z", "Rx", "Ry", "Rz", "Throttle", "Rudder",
"Wheel", "Gas", "Brake", "?", "?", "?", "?", "?",
"Hat0X", "Hat0Y", "Hat1X", "Hat1Y", "Hat2X", "Hat2Y", "Hat3X", "Hat3Y",
"?", "?", "?", "?", "?", "?", "?",
};
static const char *button_names[KEY_MAX - BTN_MISC + 1] = {
"Btn0", "Btn1", "Btn2", "Btn3", "Btn4", "Btn5", "Btn6", "Btn7", "Btn8", "Btn9", "?", "?", "?", "?", "?", "?",
"LeftBtn", "RightBtn", "MiddleBtn", "SideBtn", "ExtraBtn", "ForwardBtn", "BackBtn", "TaskBtn", "?", "?", "?", "?", "?", "?", "?", "?",
"Trigger", "ThumbBtn", "ThumbBtn2", "TopBtn", "TopBtn2", "PinkieBtn", "BaseBtn", "BaseBtn2", "BaseBtn3", "BaseBtn4", "BaseBtn5", "BaseBtn6", "BtnDead",
"BtnA", "BtnB", "BtnC", "BtnX", "BtnY", "BtnZ", "BtnTL", "BtnTR", "BtnTL2", "BtnTR2", "BtnSelect", "BtnStart", "BtnMode", "BtnThumbL", "BtnThumbR", "?",
"?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?", "?",
"WheelBtn", "Gear up",
};
/* tries to open one /dev/input/jsX and return an open file descriptor */
static int read_joystick(){
for (int num = 0; num < 100; num++){
ostringstream name;
name << "/dev/input/js" << num;
string raw = name.str();
int fd = open(raw.c_str(), O_RDONLY);
if (fd >= 0){
return fd;
}
}
return -1;
}
LinuxJoystick::LinuxJoystick():
button(0),
axis(0){
file = read_joystick();
if (file == -1){
Global::debug(0) << "Could not open joystick" << endl;
} else {
Global::debug(1) << "Opened joystick " << endl;
/* grab useful info */
ioctl(file, JSIOCGVERSION, &version);
ioctl(file, JSIOCGAXES, &axes);
ioctl(file, JSIOCGBUTTONS, &buttons);
ioctl(file, JSIOCGNAME(NAME_LENGTH), name);
ioctl(file, JSIOCGAXMAP, axmap);
ioctl(file, JSIOCGBTNMAP, btnmap);
/* put joystick in nonblocking mode */
fcntl(file, F_SETFL, O_NONBLOCK);
-
+
axis = new int[axes];
memset(axis, 0, sizeof(int) * axes);
button = new char[buttons];
memset(button, 0, sizeof(char) * buttons);
Global::debug(1) << "Joystick axis: " << (int)axes << " buttons: " << (int)buttons << endl;
}
}
LinuxJoystick::~LinuxJoystick(){
delete[] axis;
delete[] button;
if (file != -1){
close(file);
}
}
void LinuxJoystick::poll(){
struct js_event js;
if (file == -1){
return;
}
/* from an email by Vojtech Pavlik:
* "if you #include <linux/joystick.h>, the struct is defined in such a way
* that gcc doesn't add padding."
*/
int bytes = read(file, &js, sizeof(struct js_event));
if (bytes == sizeof(struct js_event)){
Global::debug(4) << "Event: type " << (int)js.type << " time " << (int)js.time << " number " << (int)js.number << " value " << (int)js.value << endl;
if (errno != EAGAIN) {
perror("joystick: error reading");
return;
}
switch (js.type & ~JS_EVENT_INIT) {
case JS_EVENT_BUTTON:
button[js.number] = js.value;
break;
case JS_EVENT_AXIS:
axis[js.number] = js.value;
break;
}
}
}
/*
JoystickInput LinuxJoystick::readAll(){
JoystickInput input;
if (file == -1){
return input;
}
if (axes > 0){
if (axis[0] < 0){
input.left = true;
}
if (axis[0] > 0){
input.right = true;
}
if (axes > 1){
if (axis[1] < 0){
input.up = true;
}
if (axis[1] > 0){
input.down = true;
}
}
}
if (buttons > 0 && button[0]){
input.button1 = true;
}
if (buttons > 1 && button[1]){
input.button2 = true;
}
if (buttons > 2 && button[2]){
input.button3 = true;
}
if (buttons > 3 && button[3]){
input.button4 = true;
}
Global::debug(1) << "joystick input up " << input.up
<< " down " << input.down
<< " left " << input.left
<< " right " << input.right
<< " button1 " << input.button1
<< " button2 " << input.button2
<< " button3 " << input.button3
<< " button4 " << input.button4
<< endl;
return input;
}
*/
#if 0
int main (int argc, char **argv)
{
- int fd, i;
- unsigned char axes = 2;
- unsigned char buttons = 2;
- int version = 0x000800;
- char name[NAME_LENGTH] = "Unknown";
- uint16_t btnmap[KEY_MAX - BTN_MISC + 1];
- uint8_t axmap[ABS_MAX + 1];
-
- if (argc < 2 || argc > 3 || !strcmp("--help", argv[1])) {
- puts("");
- puts("Usage: jstest [<mode>] <device>");
- puts("");
- puts("Modes:");
- puts(" --normal One-line mode showing immediate status");
- puts(" --old Same as --normal, using 0.x interface");
- puts(" --event Prints events as they come in");
- puts(" --nonblock Same as --event, in nonblocking mode");
- puts(" --select Same as --event, using select() call");
- puts("");
- return 1;
- }
- if ((fd = open(argv[argc - 1], O_RDONLY)) < 0) {
- perror("jstest");
- return 1;
- }
-
- ioctl(fd, JSIOCGVERSION, &version);
- ioctl(fd, JSIOCGAXES, &axes);
- ioctl(fd, JSIOCGBUTTONS, &buttons);
- ioctl(fd, JSIOCGNAME(NAME_LENGTH), name);
- ioctl(fd, JSIOCGAXMAP, axmap);
- ioctl(fd, JSIOCGBTNMAP, btnmap);
-
-
- printf("Driver version is %d.%d.%d.\n",
- version >> 16, (version >> 8) & 0xff, version & 0xff);
-
- printf("Joystick (%s) has %d axes (", name, axes);
- for (i = 0; i < axes; i++)
- printf("%s%s", i > 0 ? ", " : "", axis_names[axmap[i]]);
- puts(")");
-
- printf("and %d buttons (", buttons);
- for (i = 0; i < buttons; i++)
- printf("%s%s", i > 0 ? ", " : "", button_names[btnmap[i] - BTN_MISC]);
- puts(").");
-
- printf("Testing ... (interrupt to exit)\n");
+ int fd, i;
+ unsigned char axes = 2;
+ unsigned char buttons = 2;
+ int version = 0x000800;
+ char name[NAME_LENGTH] = "Unknown";
+ uint16_t btnmap[KEY_MAX - BTN_MISC + 1];
+ uint8_t axmap[ABS_MAX + 1];
+
+ if (argc < 2 || argc > 3 || !strcmp("--help", argv[1])) {
+ puts("");
+ puts("Usage: jstest [<mode>] <device>");
+ puts("");
+ puts("Modes:");
+ puts(" --normal One-line mode showing immediate status");
+ puts(" --old Same as --normal, using 0.x interface");
+ puts(" --event Prints events as they come in");
+ puts(" --nonblock Same as --event, in nonblocking mode");
+ puts(" --select Same as --event, using select() call");
+ puts("");
+ return 1;
+ }
+ if ((fd = open(argv[argc - 1], O_RDONLY)) < 0) {
+ perror("jstest");
+ return 1;
+ }
+
+ ioctl(fd, JSIOCGVERSION, &version);
+ ioctl(fd, JSIOCGAXES, &axes);
+ ioctl(fd, JSIOCGBUTTONS, &buttons);
+ ioctl(fd, JSIOCGNAME(NAME_LENGTH), name);
+ ioctl(fd, JSIOCGAXMAP, axmap);
+ ioctl(fd, JSIOCGBTNMAP, btnmap);
+
+
+ printf("Driver version is %d.%d.%d.\n",
+ version >> 16, (version >> 8) & 0xff, version & 0xff);
+
+ printf("Joystick (%s) has %d axes (", name, axes);
+ for (i = 0; i < axes; i++)
+ printf("%s%s", i > 0 ? ", " : "", axis_names[axmap[i]]);
+ puts(")");
+
+ printf("and %d buttons (", buttons);
+ for (i = 0; i < buttons; i++)
+ printf("%s%s", i > 0 ? ", " : "", button_names[btnmap[i] - BTN_MISC]);
+ puts(").");
+
+ printf("Testing ... (interrupt to exit)\n");
/*
* Old (0.x) interface.
*/
- if ((argc == 2 && version < 0x010000) || !strcmp("--old", argv[1])) {
+ if ((argc == 2 && version < 0x010000) || !strcmp("--old", argv[1])) {
- struct JS_DATA_TYPE js;
+ struct JS_DATA_TYPE js;
- while (1) {
+ while (1) {
- if (read(fd, &js, JS_RETURN) != JS_RETURN) {
- perror("\njstest: error reading");
- return 1;
- }
+ if (read(fd, &js, JS_RETURN) != JS_RETURN) {
+ perror("\njstest: error reading");
+ return 1;
+ }
- printf("Axes: X:%3d Y:%3d Buttons: A:%s B:%s\r",
- js.x, js.y, (js.buttons & 1) ? "on " : "off", (js.buttons & 2) ? "on " : "off");
+ printf("Axes: X:%3d Y:%3d Buttons: A:%s B:%s\r",
+ js.x, js.y, (js.buttons & 1) ? "on " : "off", (js.buttons & 2) ? "on " : "off");
- fflush(stdout);
+ fflush(stdout);
- usleep(10000);
- }
- }
+ usleep(10000);
+ }
+ }
/*
* Event interface, single line readout.
*/
- if (argc == 2 || !strcmp("--normal", argv[1])) {
+ if (argc == 2 || !strcmp("--normal", argv[1])) {
- int *axis;
- char *button;
- int i;
- struct js_event js;
+ int *axis;
+ char *button;
+ int i;
+ struct js_event js;
- axis = calloc(axes, sizeof(int));
- button = calloc(buttons, sizeof(char));
+ axis = calloc(axes, sizeof(int));
+ button = calloc(buttons, sizeof(char));
- while (1) {
- if (read(fd, &js, sizeof(struct js_event)) != sizeof(struct js_event)) {
- perror("\njstest: error reading");
- return 1;
- }
+ while (1) {
+ if (read(fd, &js, sizeof(struct js_event)) != sizeof(struct js_event)) {
+ perror("\njstest: error reading");
+ return 1;
+ }
- switch(js.type & ~JS_EVENT_INIT) {
- case JS_EVENT_BUTTON:
- button[js.number] = js.value;
- break;
- case JS_EVENT_AXIS:
- axis[js.number] = js.value;
- break;
- }
+ switch(js.type & ~JS_EVENT_INIT) {
+ case JS_EVENT_BUTTON:
+ button[js.number] = js.value;
+ break;
+ case JS_EVENT_AXIS:
+ axis[js.number] = js.value;
+ break;
+ }
- printf("\r");
+ printf("\r");
- if (axes) {
- printf("Axes: ");
- for (i = 0; i < axes; i++)
- printf("%2d:%6d ", i, axis[i]);
- }
+ if (axes) {
+ printf("Axes: ");
+ for (i = 0; i < axes; i++)
+ printf("%2d:%6d ", i, axis[i]);
+ }
- if (buttons) {
- printf("Buttons: ");
- for (i = 0; i < buttons; i++)
- printf("%2d:%s ", i, button[i] ? "on " : "off");
- }
+ if (buttons) {
+ printf("Buttons: ");
+ for (i = 0; i < buttons; i++)
+ printf("%2d:%s ", i, button[i] ? "on " : "off");
+ }
- fflush(stdout);
- }
- }
+ fflush(stdout);
+ }
+ }
/*
* Event interface, events being printed.
*/
- if (!strcmp("--event", argv[1])) {
+ if (!strcmp("--event", argv[1])) {
- struct js_event js;
+ struct js_event js;
- while (1) {
- if (read(fd, &js, sizeof(struct js_event)) != sizeof(struct js_event)) {
- perror("\njstest: error reading");
- return 1;
- }
+ while (1) {
+ if (read(fd, &js, sizeof(struct js_event)) != sizeof(struct js_event)) {
+ perror("\njstest: error reading");
+ return 1;
+ }
- printf("Event: type %d, time %d, number %d, value %d\n",
- js.type, js.time, js.number, js.value);
+ printf("Event: type %d, time %d, number %d, value %d\n",
+ js.type, js.time, js.number, js.value);
- fflush(stdout);
- }
- }
+ fflush(stdout);
+ }
+ }
/*
* Reading in nonblocking mode.
*/
- if (!strcmp("--nonblock", argv[1])) {
+ if (!strcmp("--nonblock", argv[1])) {
- struct js_event js;
+ struct js_event js;
- fcntl(fd, F_SETFL, O_NONBLOCK);
+ fcntl(fd, F_SETFL, O_NONBLOCK);
- while (1) {
+ while (1) {
- while (read(fd, &js, sizeof(struct js_event)) == sizeof(struct js_event)) {
- printf("Event: type %d, time %d, number %d, value %d\n",
- js.type, js.time, js.number, js.value);
- }
+ while (read(fd, &js, sizeof(struct js_event)) == sizeof(struct js_event)) {
+ printf("Event: type %d, time %d, number %d, value %d\n",
+ js.type, js.time, js.number, js.value);
+ }
- if (errno != EAGAIN) {
- perror("\njstest: error reading");
- return 1;
- }
+ if (errno != EAGAIN) {
+ perror("\njstest: error reading");
+ return 1;
+ }
- usleep(10000);
- }
- }
+ usleep(10000);
+ }
+ }
/*
* Using select() on joystick fd.
*/
- if (!strcmp("--select", argv[1])) {
+ if (!strcmp("--select", argv[1])) {
- struct js_event js;
- struct timeval tv;
- fd_set set;
+ struct js_event js;
+ struct timeval tv;
+ fd_set set;
- tv.tv_sec = 1;
- tv.tv_usec = 0;
+ tv.tv_sec = 1;
+ tv.tv_usec = 0;
- while (1) {
+ while (1) {
- FD_ZERO(&set);
- FD_SET(fd, &set);
+ FD_ZERO(&set);
+ FD_SET(fd, &set);
- if (select(fd+1, &set, NULL, NULL, &tv)) {
+ if (select(fd+1, &set, NULL, NULL, &tv)) {
- if (read(fd, &js, sizeof(struct js_event)) != sizeof(struct js_event)) {
- perror("\njstest: error reading");
- return 1;
- }
+ if (read(fd, &js, sizeof(struct js_event)) != sizeof(struct js_event)) {
+ perror("\njstest: error reading");
+ return 1;
+ }
- printf("Event: type %d, time %d, number %d, value %d\n",
- js.type, js.time, js.number, js.value);
+ printf("Event: type %d, time %d, number %d, value %d\n",
+ js.type, js.time, js.number, js.value);
- }
+ }
- }
- }
+ }
+ }
- printf("jstest: unknown mode: %s\n", argv[1]);
- return -1;
+ printf("jstest: unknown mode: %s\n", argv[1]);
+ return -1;
}
#endif
#endif
diff --git a/src/input/text-input.cpp b/src/input/text-input.cpp
index 3b532fcd..e42b78c6 100644
--- a/src/input/text-input.cpp
+++ b/src/input/text-input.cpp
@@ -1,250 +1,250 @@
-#include "input-map.h"
-#include "text-input.h"
-#include "input-manager.h"
-#include "input-source.h"
-#include "keyboard.h"
+#include "r-tech1/input/input-map.h"
+#include "r-tech1/input/text-input.h"
+#include "r-tech1/input/input-manager.h"
+#include "r-tech1/input/input-source.h"
+#include "r-tech1/input/keyboard.h"
#include <string.h>
#include <sstream>
#include <string>
using namespace std;
static const int Shift = 198;
static const int Control = 199;
static const int Backspace = 200;
TextInput::TextInput(const string & start):
InputMap<unsigned char>(),
blockingKeys(false),
enabled(false),
handle(201){
const int delay = 100;
/*
set(Keyboard::Key_TILDE, delay * 2, false, Toggle);
set(Keyboard::Key_ESC, delay, false, Esc);
set(Keyboard::Key_ENTER, 0, false, Enter);
*/
// set(Keyboard::Key_LCONTROL, 0, false, Control);
set(Keyboard::Key_BACKSPACE, delay, false, Backspace);
/*
set(Keyboard::Key_LSHIFT, 0, false, Shift);
set(Keyboard::Key_RSHIFT, 0, false, Shift);
*/
text.str(start);
text.rdbuf()->pubseekoff(0, ios_base::end, ios_base::out);
text.clear();
}
int TextInput::nextHandle(){
int i = handle;
handle += 1;
return i;
}
void TextInput::addBlockingHandle(int key, callback function, void * data){
int handle = nextHandle();
set(key, 1, true, handle);
callbacks[handle] = Callback(function, data);
}
void TextInput::addBlockingJoystickHandle(Joystick::Key key, callback function, void * data){
int handle = nextHandle();
set(key, 1, true, handle);
callbacks[handle] = Callback(function, data);
}
void TextInput::addHandle(int key, int delay, callback function, void * data){
int handle = nextHandle();
set(key, delay, false, handle);
callbacks[handle] = Callback(function, data);
}
/* FIXME: move this to a more general place */
static string encodeUtf8(unsigned long unicode){
ostringstream out;
if (unicode < 128){
out << (unsigned char) unicode;
} else if (unicode < 2047){
unsigned char byte1 = 192 + unicode / 64;
unsigned char byte2 = 128 + unicode % 64;
out << byte1 << byte2;
} else if (unicode <= 65535){
unsigned char byte1 = 224 + unicode / 4096;
unsigned char byte2 = 128 + (unicode / 64) % 64;
unsigned char byte3 = 128 + unicode % 64;
out << byte1 << byte2 << byte3;
} else if (unicode <= 2097151){
unsigned char byte1 = 240 + unicode / 262144;
unsigned char byte2 = 128 + (unicode / 4096) % 64;
unsigned char byte3 = 128 + (unicode / 64) % 64;
unsigned char byte4 = 128 + (unicode % 64);
out << byte1 << byte2 << byte3 << byte4;
} else if (unicode <= 67108863){
unsigned char byte1 = 248 + (unicode / 16777216);
unsigned char byte2 = 128 + ((unicode / 262144) % 64);
unsigned char byte3 = 128 + ((unicode / 4096) % 64);
unsigned char byte4 = 128 + ((unicode / 64) % 64);
unsigned char byte5 = 128 + (unicode % 64);
out << byte1 << byte2 << byte3 << byte4 << byte5;
} else if (unicode <= 2147483647){
unsigned char byte1 = 252 + (unicode / 1073741824);
unsigned char byte2 = 128 + ((unicode / 16777216) % 64);
unsigned char byte3 = 128 + ((unicode / 262144) % 64);
unsigned char byte4 = 128 + ((unicode / 4096) % 64);
unsigned char byte5 = 128 + ((unicode / 64) % 64);
unsigned char byte6 = 128 + (unicode % 64);
}
return out.str();
}
bool TextInput::doInput(){
bool modified = false;
/* TODO: ensure these codes are consistent across platforms. So far
* they seem to work in windows xp and linux (ubuntu)
*/
const Keyboard::unicode_t control_u = 21;
const Keyboard::unicode_t control_w = 23;
if (enabled){
vector<InputEvent> events = InputManager::getEvents(*this, InputSource(true));
/* the order of reading input is arbitrary right now. I'm not
* sure it matters what order things are done in, but probably
* a few corner cases exist. When they come up please document them.
*/
for (vector<InputEvent>::iterator it = events.begin(); it != events.end(); it++){
InputEvent event = *it;
if (event.enabled){
if (event.out == Backspace){
backspace();
modified = true;
}
if (callbacks.find(event.out) != callbacks.end()){
Callback & callback = callbacks[event.out];
callback.function(callback.data);
} else if (event.unicode == control_u){
clearInput();
modified = true;
} else if (event.unicode == control_w){
deleteLastWord();
modified = true;
} else if (event.unicode >= 32 && event.unicode < 0xffffff){
/* FIXME: whats the maximum unicode value? */
// this->text << (unsigned char) event.unicode;
this->text << encodeUtf8(event.unicode);
modified = true;
}
}
}
}
return modified;
}
void TextInput::enable(){
InputManager::captureInput(*this);
enabled = true;
Keyboard::pushRepeatState(true);
}
void TextInput::disable(){
InputManager::releaseInput(*this);
enabled = false;
Keyboard::popRepeatState();
}
string TextInput::getText() const {
return text.str();
}
/*
void TextInput::clear(){
text.str("");
text.clear();
}
*/
void TextInput::setText(const std::string & text){
this->text.str(text);
this->text.rdbuf()->pubseekoff(0, ios_base::end, ios_base::out);
this->text.clear();
}
void TextInput::clearInput(){
setText(string());
}
void TextInput::backspace(){
/* todo: handle utf8 */
string now = text.str();
now = now.substr(0, now.size()-1);
setText(now);
}
void TextInput::deleteLastWord(){
string now = text.str();
// Global::debug(0) << "Delete last word '" << now << "'" << endl;
if (now.size() > 0){
if (now.at(now.size() - 1) != ' '){
int here = now.size() - 1;
while (here > 0 && now.at(here) != ' '){
here -= 1;
}
if (now.at(here) == ' '){
here += 1;
}
now.erase(here);
} else {
int here = now.size() - 1;
while (here > 0 && now.at(here) == ' '){
here -= 1;
}
if (here > 0){
while (here > 0 && now.at(here) != ' '){
here -= 1;
}
if (now.at(here) == ' '){
here += 1;
}
}
now.erase(here);
}
setText(now);
}
/*
size_t get = now.rfind(" ");
if (get != string::npos){
Global::debug(0) << "get " << get << " size " << now.size() << endl;
if (get == now.size() - 1){
get = now.find_last_not_of(' ');
get = now.rfind(' ', get);
if (get != string::npos){
get = 0;
}
now.erase(get + 1);
} else {
now = now.substr(0, get + 1);
}
text.str(now);
text.rdbuf()->pubseekoff(0, ios_base::end, ios_base::out);
text.clear();
} else {
clearInput();
}
*/
}
TextInput::~TextInput(){
disable();
}
diff --git a/src/language-string.cpp b/src/language-string.cpp
index 464c6e17..77e39eb0 100644
--- a/src/language-string.cpp
+++ b/src/language-string.cpp
@@ -1,60 +1,60 @@
#include <string>
-#include "language-string.h"
-#include "configuration.h"
+#include "r-tech1/language-string.h"
+#include "r-tech1/configuration.h"
using namespace std;
LanguageString::LanguageString(){
}
LanguageString::LanguageString(const std::string & stuff){
add(stuff);
}
LanguageString::LanguageString(const char * stuff){
add(stuff);
}
LanguageString::LanguageString(const std::string & stuff, const std::string & language){
add(stuff, language);
}
LanguageString::LanguageString(const LanguageString & language){
languages = language.languages;
}
LanguageString & LanguageString::operator=(const LanguageString & obj){
this->languages = obj.languages;
return *this;
}
void LanguageString::add(const std::string & stuff, const std::string & language){
languages[language] = stuff;
}
void LanguageString::add(const std::string & stuff){
add(stuff, defaultLanguage());
}
const string LanguageString::currentLanguage() const {
return Configuration::getLanguage();
}
std::string LanguageString::get() const {
map<std::string, std::string>::const_iterator find = languages.find(currentLanguage());
if (find != languages.end()){
return find->second;
}
find = languages.find(defaultLanguage());
if (find != languages.end()){
return find->second;
}
return "";
/*
if (languages[currentLanguage()] != ""){
return languages[currentLanguage()];
}
return languages[defaultLanguage()];
*/
}
diff --git a/src/libs/7z/SConscript b/src/libs/7z/SConscript
index 3017c942..cfabf15f 100644
--- a/src/libs/7z/SConscript
+++ b/src/libs/7z/SConscript
@@ -1,19 +1,19 @@
Import('use')
#source = Split("""
#7zAlloc.c 7zBuf.c 7zBuf2.c 7zCrc.c 7zCrcOpt.c 7zDec.c 7zIn.c CpuArch.c LzmaDec.c Lzma2Dec.c Bra.c Bra86.c Bcj2.c 7zFile.c 7zStream.c
#""")
# Ppmd7.c
# Ppmd7Dec.c
-import helpers
+from scons import helpers
import os.path
-modules = helpers.read_cmake_list(helpers.findFile('src/util/7z/CMakeLists.txt'))
+modules = helpers.read_cmake_list(helpers.findFile('src/libs/7z/CMakeLists.txt'))
source = []
for module in modules:
source.append(modules[module])
out = use.StaticLibrary('7z-local', source)
Return('out')
diff --git a/src/loading.cpp b/src/loading.cpp
index 366226f5..3ff3ae8e 100644
--- a/src/loading.cpp
+++ b/src/loading.cpp
@@ -1,553 +1,553 @@
-#include "graphics/bitmap.h"
+#include "r-tech1/graphics/bitmap.h"
#include <math.h>
#include <iostream>
-#include "messages.h"
-#include "loading.h"
-#include "file-system.h"
-#include "font.h"
-#include "funcs.h"
-#include "version.h"
-#include "graphics/gradient.h"
-#include "parameter.h"
-#include "thread.h"
+#include "r-tech1/messages.h"
+#include "r-tech1/loading.h"
+#include "r-tech1/file-system.h"
+#include "r-tech1/font.h"
+#include "r-tech1/funcs.h"
+#include "r-tech1/version.h"
+#include "r-tech1/graphics/gradient.h"
+#include "r-tech1/parameter.h"
+#include "r-tech1/thread.h"
#include <vector>
-#include "thread.h"
-#include "message-queue.h"
-#include "init.h"
-#include "events.h"
-#include "input/input-map.h"
-#include "input/input-manager.h"
+#include "r-tech1/thread.h"
+#include "r-tech1/message-queue.h"
+#include "r-tech1/init.h"
+#include "r-tech1/events.h"
+#include "r-tech1/input/input-map.h"
+#include "r-tech1/input/input-manager.h"
using namespace std;
namespace Loader{
volatile bool done_loading = true;
typedef struct pair{
- int x, y;
+ int x, y;
} ppair;
class MessageInfo{
public:
MessageInfo(){
MessageQueue::registerInfo(&messages);
}
bool transferMessages(Messages & box){
bool did = false;
while (messages.hasAny()){
const string & str = messages.get();
box.addMessage(str);
did = true;
}
return did;
}
~MessageInfo(){
MessageQueue::unregisterInfo(&messages);
}
private:
MessageQueue messages;
};
Info::Info(const string & message, const Filesystem::AbsolutePath & background):
x(-1),
y(-1),
_loadingMessage(message),
background(NULL),
_loadingBackground(background){
}
Info::Info(const Info & info){
this->x = info.x;
this->y = info.y;
this->_loadingMessage = info._loadingMessage;
this->background = info.background;
this->_loadingBackground = info._loadingBackground;
}
Info::~Info(){
}
void Info::setBackground(const Graphics::Bitmap * background){
this->background = background;
}
void Info::setLoadingMessage(const std::string & str){
this->_loadingMessage = str;
}
void Info::setPosition(int x, int y){
this->x = x;
this->y = y;
}
const Graphics::Bitmap * Info::getBackground() const {
return background;
}
const string & Info::loadingMessage() const {
return _loadingMessage;
}
const Filesystem::AbsolutePath & Info::loadingBackground() const {
return _loadingBackground;
}
int Info::getPositionX() const {
return x;
}
int Info::getPositionY() const {
return y;
}
void * loadingScreenSimple1(void * arg);
static void setupBackground(const Graphics::Bitmap & background, int load_x, int load_y, int load_width, int load_height, int infobox_x, int infobox_y, int infoWidth, int infoHeight, const Graphics::Bitmap & infoBackground, const Graphics::Bitmap & screen){
int startX = background.getWidth() - Font::getDefaultFont().textLength("Paintown version 9.9.9.9");
int startY = background.getHeight() - Font::getDefaultFont().getHeight() * 4;
int height = Font::getDefaultFont().getHeight();
Font::getDefaultFont().printf(startX, startY + height * 0, Graphics::makeColor(192, 192, 192), background, "Paintown version %s", 0, Version::getVersionString().c_str());
Font::getDefaultFont().printf(startX, startY + height * 1, Graphics::makeColor(192, 192, 192), background, "Made by Jon Rafkind", 0);
Font::getDefaultFont().printf(startX, startY + height * 2, Graphics::makeColor(192, 192, 192), background, "http://paintown.org", 0);
/* we have to blit to the screen object passed in because that is the bitmap
* that will be operated on in the draw() method of loadingScreen1.
* we also have to blit to the real screen because the screen object
* is not drawn in its entirety to the real screen, only the part
* that shows the 'Loading ...' message and the info box.
* drawing twice in Allegro5 is redundant because the screen object is the real
* screen but for Allegro4 and SDL we need to do this because the screen object
* is a buffer.
*/
background.Blit(screen);
background.BlitToScreen();
background.Blit(infobox_x, infobox_y, infoWidth, infoHeight, 0, 0, infoBackground);
}
/* converts a bitmap with some text on it into a sequence of points */
static vector<ppair> generateFontPixels(const Font & myFont, const string & message, int width, int height){
Graphics::Bitmap letters(Graphics::Bitmap::createMemoryBitmap(width, height));
letters.fill(Graphics::MaskColor());
myFont.printf(0, 0, Graphics::makeColor(255, 255, 255), letters, message.c_str(), 0);
vector<ppair> pairs;
for (int x = 0; x < letters.getWidth(); x++){
for (int y = 0; y < letters.getHeight(); y++){
Graphics::Color pixel = letters.getPixel(x, y);
if (pixel != Graphics::MaskColor()){
ppair p;
p.x = x;
p.y = y;
pairs.push_back(p);
}
}
}
// Graphics::resetDisplay();
return pairs;
}
/* shows time elapsed */
class TimeCounter{
public:
TimeCounter():
work(200, 40){
start = Global::second_counter;
last = 0;
}
void draw(int x, int y){
const Font & font = Font::getDefaultFont(24, 24);
if (Global::second_counter != last){
work.clear();
last = Global::second_counter;
font.printf(0, 0, Graphics::makeColor(192, 192, 192), work, "Waiting.. %d", 0, last - start);
work.BlitAreaToScreen(x, y);
}
}
Graphics::Bitmap work;
unsigned int start;
unsigned int last;
};
enum LoadingKeys{
Activate
};
static void loadingScreen1(LoadingContext & context, const Info & levelInfo){
int load_x = 80;
int load_y = 220;
const int infobox_width = 300;
const int infobox_height = 150;
const Font & myFont = Font::getDefaultFont(24, 24);
if (levelInfo.getPositionX() != -1){
load_x = levelInfo.getPositionX();
}
if (levelInfo.getPositionY() != -1){
load_y = levelInfo.getPositionY();
}
// const char * the_string = (arg != NULL) ? (const char *) arg : "Loading...";
int load_width = myFont.textLength(levelInfo.loadingMessage().c_str());
int load_height = myFont.getHeight(levelInfo.loadingMessage().c_str());
Global::debug(2) << "loading screen" << endl;
Messages infobox(infobox_width, infobox_height);
const int MAX_COLOR = 200;
/* blend from dark grey to light red */
Effects::Gradient gradient(MAX_COLOR, Graphics::makeColor(16, 16, 16), Graphics::makeColor(192, 8, 8));
// TimeCounter counter;
struct State{
bool drawInfo;
};
class Logic: public Util::Logic {
public:
Logic(LoadingContext & context, State & state, Effects::Gradient & gradient, Messages & infoBox):
context(context),
state(state),
gradient(gradient),
infobox(infoBox),
active(false){
input.set(Keyboard::Key_SPACE, 0, true, Activate);
input.set(Keyboard::Key_ENTER, 0, true, Activate);
input.set(Joystick::Button1, 0, true, Activate);
}
LoadingContext & context;
State & state;
Effects::Gradient & gradient;
MessageInfo info;
Messages & infobox;
bool active;
InputMap<LoadingKeys> input;
void doInput(){
class Handler: public InputHandler<LoadingKeys> {
public:
Handler(bool & active):
active(active){
}
bool & active;
void press(const LoadingKeys & out, Keyboard::unicode_t unicode){
if (out == Activate){
/* the info box can't really be turned off because once
* its drawn it will remain there. the background would
* have to be drawn on top of it to remove the old
* info box. maybe do this in the future, if so use
* active = ! active
* to toggle it.
*/
active = ! active;
}
}
void release(const LoadingKeys & out, Keyboard::unicode_t unicode){
}
};
Handler handler(active);
InputManager::handleEvents(input, InputSource(true), handler);
}
void run(){
for (int i = 0; i < 3; i++){
gradient.backward();
}
doInput();
info.transferMessages(infobox);
// state.drawInfo = active && (info.transferMessages(infobox) || state.drawInfo);
state.drawInfo = active;
}
double ticks(double system){
return system * Global::ticksPerSecond(8);
}
bool done(){
return context.done();
}
};
class Draw: public Util::Draw {
public:
Draw(const Info & levelInfo, State & state, Messages & infobox, Effects::Gradient & gradient, int load_width, int load_height, int infobox_width, int infobox_height, int load_x, int load_y):
levelInfo(levelInfo),
gradient(gradient),
state(state),
infobox(infobox),
infobox_x(load_x),
infobox_y(load_y + load_height * 2),
infobox_width(infobox_width),
infobox_height(infobox_height),
load_x(load_x),
load_y(load_y),
load_width(load_width),
load_height(load_height){
if (levelInfo.loadingBackground() != Filesystem::AbsolutePath("")){
background = Graphics::Bitmap(levelInfo.loadingBackground().path());
}
const Font & myFont = Font::getDefaultFont(24, 24);
pairs = generateFontPixels(myFont, levelInfo.loadingMessage(), load_width, load_height);
}
const Info & levelInfo;
Effects::Gradient & gradient;
State & state;
Messages & infobox;
Graphics::Bitmap background;
// Graphics::Bitmap infoWork;
// Graphics::Bitmap infoBackground;
vector<ppair> pairs;
const int infobox_x;
const int infobox_y;
const int infobox_width;
const int infobox_height;
const int load_x;
const int load_y;
const int load_width;
const int load_height;
/*
void drawFirst(const Graphics::Bitmap & screen){
if (levelInfo.getBackground() != NULL){
setupBackground(*levelInfo.getBackground(), load_x, load_y, load_width, load_height, infobox_x, infobox_y, infoBackground.getWidth(), infoBackground.getHeight(), infoBackground, screen);
} else {
Graphics::Bitmap background;
if (levelInfo.loadingBackground() != Filesystem::AbsolutePath("")){
background = Graphics::Bitmap(levelInfo.loadingBackground().path());
} else {
background = Graphics::Bitmap(*Graphics::screenParameter.current(), true);
}
setupBackground(background, load_x, load_y, load_width, load_height, infobox_x, infobox_y, infoBackground.getWidth(), infoBackground.getHeight(), infoBackground, screen);
}
}
*/
void drawAuthorInfo(const Graphics::Bitmap & screen){
int startX = screen.getWidth() - Font::getDefaultFont().textLength("Paintown version 9.9.9.9");
int startY = screen.getHeight() - Font::getDefaultFont().getHeight() * 4;
int height = Font::getDefaultFont().getHeight();
Font::getDefaultFont().printf(startX, startY + height * 0, Graphics::makeColor(192, 192, 192), screen, "Paintown version %s", 0, Version::getVersionString().c_str());
Font::getDefaultFont().printf(startX, startY + height * 1, Graphics::makeColor(192, 192, 192), screen, "Made by Jon Rafkind", 0);
Font::getDefaultFont().printf(startX, startY + height * 2, Graphics::makeColor(192, 192, 192), screen, "http://paintown.org", 0);
}
void draw(const Graphics::Bitmap & screen){
if (!background.isEmpty()){
background.drawStretched(screen);
}
Graphics::Bitmap work(screen, load_x, load_y, load_width, load_height);
// work.lock();
for (vector< ppair >::iterator it = pairs.begin(); it != pairs.end(); it++){
Graphics::Color color = gradient.current(it->x);
work.putPixel(it->x, it->y, color);
}
// work.unlock();
if (state.drawInfo){
// infoBackground.Blit(infoWork);
const Font & infoFont = Font::getDefaultFont(24, 24);
/* cheesy hack to change the font size. the font
* should store the size and change it on its own
*/
Graphics::Bitmap infoWork(screen, infobox_x, infobox_y, infobox_width, infobox_height);
Font::getDefaultFont(13, 13);
infobox.draw(0, 0, infoWork, infoFont);
Font::getDefaultFont(24, 24);
infoWork.BlitAreaToScreen(infobox_x, infobox_y);
// infoWork.BlitToScreen();
// state.drawInfo = false;
}
drawAuthorInfo(screen);
/* work already contains the correct background */
// work.Blit( load_x, load_y, *Bitmap::Screen );
// work.BlitToScreen();
// work.BlitAreaToScreen(load_x, load_y);
}
};
State state;
state.drawInfo = false;
Logic logic(context, state, gradient, infobox);
Draw draw(levelInfo, state, infobox, gradient, load_width, load_height, infobox_width, infobox_height, load_x, load_y);
Util::standardLoop(logic, draw);
}
static void loadingScreenSimpleX1(LoadingContext & context, const Info & levelInfo){
class Logic: public Util::Logic {
public:
Logic(LoadingContext & context, int & angle, int speed):
context(context),
speed(speed),
angle(angle){
}
LoadingContext & context;
/* speed of rotation */
const int speed;
int & angle;
double ticks(double system){
return system * Global::ticksPerSecond(10);
}
bool done(){
return context.done();
}
void run(){
angle += speed * 2;
angle = angle % 360;
}
};
class Draw: public Util::Draw {
public:
Draw(int & angle, const int speed):
angle(angle),
speed(speed){
/*
if (levelInfo.loadingBackground() != Filesystem::AbsolutePath("")){
background = Graphics::Bitmap(levelInfo.loadingBackground().path());
}
*/
colors[0] = Graphics::makeColor(0x18, 0x52, 0xa0);
colors[1] = Graphics::makeColor(0x00, 0x99, 0xff);
colors[2] = Graphics::makeColor(0xff, 0x22, 0x33);
colors[3] = Graphics::makeColor(0x44, 0x77, 0x33);
Graphics::Bitmap::transBlender(0, 0, 0, 64);
}
Graphics::Bitmap background;
int & angle;
const int speed;
/* the length of this array is the number of circles to show */
Graphics::Color colors[4];
virtual ~Draw(){
}
void draw(const Graphics::Bitmap & screen){
if (!background.isEmpty()){
background.drawStretched(screen);
}
Graphics::Bitmap work(screen, 0, 0, 40, 40);
int max = Util::array_size(colors);
double middleX = work.getWidth() / 2;
double middleY = work.getHeight() / 2;
int size = 15;
int radius = 3;
for (int i = 0; i < max; i++){
double new_angle = angle + 360.0 / (double) max * i;
int lag = 17;
double x = cos(Util::radians(new_angle - lag)) * size;
double y = sin(Util::radians(new_angle - lag)) * size;
/* ghost circle */
work.translucent(0, 0, 0, 128).circleFill(middleX + x, middleY + y, radius, colors[i]);
x = cos(Util::radians(new_angle)) * size;
y = sin(Util::radians(new_angle)) * size;
/* real circle */
work.circleFill(middleX + x, middleY + y, radius, colors[i]);
}
// work.BlitAreaToScreen(0, 0);
}
};
int angle = 0;
int speed = 10;
Logic logic(context, angle, speed);
Draw draw(angle, speed);
Util::standardLoop(logic, draw);
}
LoadingContext::LoadingContext():
finished(false){
Util::Thread::initializeLock(&lock);
}
LoadingContext::~LoadingContext(){
}
void LoadingContext::doLoad(){
this->load();
Util::Thread::acquireLock(&lock);
finished = true;
Util::Thread::releaseLock(&lock);
}
bool LoadingContext::done(){
bool ok = false;
Util::Thread::acquireLock(&lock);
ok = this->finished;
Util::Thread::releaseLock(&lock);
return ok;
}
void * LoadingContext::load_it(void * arg){
LoadingContext * context = (LoadingContext*) arg;
context->doLoad();
return NULL;
}
static void showLoadMessage(){
int screenX = 80;
int screenY = 50;
Graphics::Bitmap work(110, 50);
work.BlitFromScreen(screenX, screenY);
Graphics::Bitmap top(110, 50);
top.fill(Graphics::makeColor(0, 0, 0));
Font::getDefaultFont(25, 25).printf(10, 5, Graphics::makeColor(192, 192, 192), top, "Loading", 0);
Graphics::Bitmap::transBlender(0, 0, 0, 200);
top.translucent().draw(0, 0, work);
work.BlitAreaToScreen(screenX, screenY);
}
void loadScreen(LoadingContext & context, const Info & info, Kind kind){
Util::Thread::Id loadingThread;
bool created = Util::Thread::createThread(&loadingThread, NULL, (Util::Thread::ThreadFunction) LoadingContext::load_it, &context);
if (!created){
Global::debug(0) << "Could not create loading thread. Loading will occur in the main thread" << endl;
showLoadMessage();
LoadingContext::load_it(&context);
// throw LoadException(__FILE__, __LINE__, "Could not create loader thread");
} else {
InputManager::deferResizeEvents(true);
switch (kind){
case Default: loadingScreen1(context, info); break;
case SimpleCircle: loadingScreenSimpleX1(context, info); break;
default: loadingScreen1(context, info); break;
}
Util::Thread::joinThread(loadingThread);
InputManager::deferResizeEvents(false);
}
}
}

File Metadata

Mime Type
text/x-diff
Expires
Wed, Jun 17, 9:36 PM (1 w, 4 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
70050
Default Alt Text
(689 KB)

Event Timeline