1
0
Fork 0
mirror of https://github.com/AquariaOSE/Aquaria.git synced 2024-11-29 03:33:48 +00:00
Aquaria/BBGE/Core.h
fgenesis b8a9815de7 Change the text input box to use SDL textinput events
Add a cheap replacement for SDL1 that doesn't have textinput events.
2024-10-15 04:07:22 +02:00

549 lines
12 KiB
C++

/*
Copyright (C) 2007, 2010 - Bit-Blot
This file is part of Aquaria.
Aquaria is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef BBGE_CORE_H
#define BBGE_CORE_H
#include "Base.h"
#include "RenderObject.h"
#include "SoundManager.h"
#include "Event.h"
#include "StateManager.h"
#include "Localization.h"
#include "Window.h"
#include "TextureMgr.h"
#include "VertexBuffer.h"
#include "DarkLayer.h"
#include "RenderGrid.h"
#include "GameKeys.h"
class ParticleEffect;
class Joystick;
class ParticleManager;
struct ScreenMode
{
ScreenMode() { x = y = hz = 0; }
ScreenMode(int x, int y, int hz) : x(x), y(y), hz(hz) {}
int x, y, hz;
};
struct CoreSettings
{
CoreSettings() { renderOn = true; runInBackground = false; prebufferSounds = false; }
bool renderOn;
bool runInBackground;
bool prebufferSounds;
};
enum CoreLayers
{
LR_NONE = -1
};
enum TextInputEvent
{
TEXTINP_TEXT,
TEXTINP_BACKSPACE,
};
class AfterEffectManager;
class Texture;
const int baseVirtualWidth = 800;
const int baseVirtualHeight = 600;
enum ButtonState { UP = 0, DOWN };
struct MouseButtons
{
MouseButtons ()
{
left = UP;
right = UP;
middle = UP;
}
ButtonState left, right, middle;
ButtonState extra[mouseExtraButtons];
};
struct Mouse
{
Mouse()
{
scrollWheelChange = 0;
buttonsEnabled = true;
_wasMoved = false;
_enableMotionEvents = true;
}
Vector position, lastPosition;
MouseButtons buttons;
MouseButtons pure_buttons;
unsigned rawButtonMask;
Vector change;
bool buttonsEnabled;
int scrollWheelChange;
// transient; not for use outside of event handling
bool _wasMoved;
bool _enableMotionEvents;
};
enum FollowCameraLock
{
FCL_NONE = 0,
FCL_HORZ = 1,
FCL_VERT = 2
};
typedef std::vector <RenderObject*> RenderObjects;
typedef bool (*PreRenderFunc)(const RenderState& rs);
typedef void (*PostRenderFunc)(const RenderState& rs);
class RenderObjectLayer
{
public:
RenderObjectLayer();
~RenderObjectLayer();
void add(RenderObject* r);
void remove(RenderObject* r);
void moveToFront(RenderObject *r);
void moveToBack(RenderObject *r);
void reloadDevice();
void prepareRender();
void render(const RenderState& rs) const;
inline bool empty()
{
return objectCount == 0;
}
inline RenderObject *getFirst()
{
iter = 0;
return getNext();
}
RenderObject *getNext()
{
const size_t size = renderObjects.size();
size_t i;
for (i = iter; i < size; i++)
{
if (renderObjects[i] != 0)
break;
}
if (i < size)
{
iter = i+1;
return renderObjects[i];
}
else
{
iter = i;
return 0;
}
return 0;
}
//inclusive
int startPass, endPass;
bool visible;
float followCamera;
Vector followCameraMult; // calculated based on followCameraLock
int followCameraLock;
PreRenderFunc preRender;
PostRenderFunc postRender;
protected:
RenderObjects renderObjects;
std::vector<const RenderObject*> toRender;
size_t objectCount;
size_t firstFreeIdx;
size_t iter;
};
class CoreWindow : public Window
{
public:
virtual ~CoreWindow();
protected:
virtual void onEvent(const SDL_Event& ev);
virtual void onResize(unsigned w, unsigned h);
virtual void onQuit();
};
class Core : public ActionMapper, public StateManager
{
friend class CoreWindow;
public:
// init
Core(const std::string &filesystem, const std::string& extraDataDir, int numRenderLayers, const std::string &appName="BBGE", int particleSize=1024, std::string userDataSubFolder="");
void initPlatform(const std::string &filesystem);
~Core();
virtual void init();
void initRenderObjectLayers(int num);
void applyState(const std::string &state);
void renderExternal();
void prepareRender();
void renderInternal(int startLayer, int endLayer, bool allowSkip);
void showBuffer();
void quit();
bool isShuttingDown();
bool isWindowFocus();
void cacheRender();
void reloadResources();
void unloadResources();
std::string getPreferencesFolder();
std::string getUserDataFolder();
std::string getDebugLogPath();
void resetCamera();
virtual void shutdown();
void run(float runTime = -1); // can use main
// state functions
void setMousePosition(const Vector &p);
Vector pixelPosToVirtualCoords(int x, int y) const;
void virtualCoordsToPixelPos(int& x, int& y, const Vector& p) const;
void setFullscreen(bool full);
void enable2D(int pixelScaleX, int pixelScaleY);
void addRenderObject(RenderObject *o, unsigned layer);
void switchRenderObjectLayer(RenderObject *o, unsigned toLayer);
CountedPtr<Texture> getTexture(const std::string &name);
enum RemoveRenderObjectFlag { DESTROY_RENDER_OBJECT=0, DO_NOT_DESTROY_RENDER_OBJECT };
void removeRenderObject(RenderObject *r, RemoveRenderObjectFlag flag = DESTROY_RENDER_OBJECT);
void setMouseConstraint(bool on);
void setMouseConstraintCircle(const Vector& pos, float mouseCircle);
virtual void action(int id, int state, int source, InputDevice device){}
void enqueueRenderObjectDeletion(RenderObject *object);
void clearGarbage();
bool isNested() const { return nestedMains > 1; }
int getNestedMains() const { return nestedMains; }
void quitNestedMain();
int getWindowWidth() const { return width; }
int getWindowHeight() const { return height; }
unsigned getTicks();
void updateWindowDrawSize(int w, int h);
Vector getGameCursorPosition() const;
Vector getTopLeftCornerInWorldCoords() const;
Vector getBottomRightCornerInWorldCoords() const;
Vector getGamePosition(const Vector &winpos) const;
Vector getWindowPosition(const Vector& worldpos) const;
bool isRectInWindowCoordsPartiallyOnScreen(const Vector& center, const Vector& wh) const;
bool isRectInWindowCoordsFullyOnScreen(const Vector& center, const Vector& wh) const;
// positive margin makes the screen area narrower, negative margin makes it wider (accept slightly outside)
bool isPointInWindowCoordsOnScreenWithMargin(const Vector& center, const Vector& margin) const;
Vector screenCenter;
void print(int x, int y, const char *str, float sz=1);
RenderObjectLayer *getRenderObjectLayer(int i);
std::vector <int> renderObjectLayerOrder;
typedef std::vector<RenderObjectLayer> RenderObjectLayers;
RenderObjectLayers renderObjectLayers;
RenderObjects garbage;
SoundManager *sound;
int width, height;
InterpolatedVector globalScale;
Vector globalResolutionScale;
virtual void onResetScene(){}
virtual void onPlayedVoice(const std::string &name){}
Vector cameraPos;
int fps;
bool loopDone;
Mouse mouse;
AfterEffectManager *afterEffectManager;
ParticleManager *particleManager;
void setExtraTexturePath(const char *dir, bool watch); // pass NULL to disable secondary
const char *getExtraTexturePath() const; // NULL when no secondary
const std::string& getBaseTexturePath() const;
virtual bool canChangeState();
void resetTimer();
inline int getVirtualWidth()
{
return virtualWidth;
}
inline int getVirtualHeight()
{
return virtualHeight;
}
unsigned char *grabScreenshot(size_t x, size_t y, size_t w, size_t h);
unsigned char *grabCenteredScreenshot(size_t w, size_t h);
bool saveScreenshot(const std::string &filename, bool png);
bool minimized;
std::string getEnqueuedJumpState();
float cullRadius;
float cullRadiusSqr;
Vector cullCenter;
size_t renderObjectCount, processedRenderObjectCount, totalRenderObjectCount;
float invGlobalScale, invGlobalScaleSqr;
void globalScaleChanged();
void screenshot();
void clearRenderObjects();
bool getKeyState(int k);
bool getMouseButtonState(int m);
int keys[KEY_MAXARRAY];
virtual void _debugLog(const std::string &s);
virtual void _errorLog(const std::string &s);
void messageBox(const std::string &title, const std::string &msg);
bool getShiftState();
bool getAltState();
bool getCtrlState();
virtual void generateCollisionMask(RenderObject *r){}
DarkLayer darkLayer;
void setupRenderPositionAndScale();
int particlesPaused;
bool joystickEnabled;
void setup_opengl();
void setClearColor(const Vector &c);
int flipMouseButtons;
FrameBuffer frameBuffer;
void updateRenderObjects(float dt);
bool joystickAsMouse;
virtual void prepScreen(bool t){}
ParticleEffect* createParticleEffect(const std::string &name, const Vector &position, int layer, float rotz=0);
float get_old_dt() { return old_dt; }
float get_current_dt() { return current_dt; }
bool debugLogActive;
bool debugOutputActive;
void setInputGrab(bool on);
void updateInputGrab();
bool isFullscreen();
bool isDesktopResolution();
int getDisplayIndex();
int getRefreshRate();
int getVirtualOffX() const;
int getVirtualOffY() const;
void centerMouse();
Vector center;
void enable2DWide(int rx, int ry);
void enumerateScreenModes(int display);
void enumerateScreenModesIfNecessary(int display = -1);
void resizeWindow(int w, int h, int full, int bpp, int vsync, int display, int hz);
std::vector<ScreenMode> screenModes;
void pollEvents(float dt);
void onEvent(const SDL_Event& event);
CoreSettings settings;
volatile int dbg_numThreadDecoders;
virtual void onBackgroundUpdate();
void initLocalization();
TextureMgr texmgr;
inline const RenderGrid *getDefaultQuadGrid() const { return &defaultQuadGrid; }
inline const DynamicGPUBuffer *getDefaultQuadBorderBuf() const { return &defautQuadBorder; }
protected:
CoreWindow *window;
void updateCullData();
std::string userDataFolder;
bool grabInput;
int virtualOffX, virtualOffY;
float old_dt;
float current_dt;
std::string debugLogPath;
virtual void onReloadResources();
bool lib_graphics, lib_sound, lib_input;
Vector clearColor;
virtual void unloadDevice();
virtual void reloadDevice();
std::string appName;
bool mouseConstraint;
float mouseCircle;
Vector mouseConstraintCenter;
bool doMouseConstraint();
virtual void onTextInput(TextInputEvent ti, const char *text) {}
void beginTextInput();
void endTextInput();
int textInputOpenCount;
virtual void onMouseInput(){}
bool doScreenshot;
float baseCullRadius;
bool initSoundLibrary(const std::string &defaultDevice);
bool initInputLibrary();
void initJoystickLibrary();
void initGraphicsLibrary(int w, int h, bool fullscreen, bool vsync, int bpp, int display, int hz);
void shutdownInputLibrary();
void shutdownJoystickLibrary();
void shutdownGraphicsLibrary();
void shutdownSoundLibrary();
void detectJoysticks();
void clearJoysticks();
virtual void onJoystickAdded(int deviceID);
virtual void onJoystickRemoved(int instanceID);
Vector cameraOffset;
std::vector<float> avgFPS;
virtual void modifyDt(float &dt){}
void setPixelScale(int pixelScaleX, int pixelScaleY);
virtual void onWindowResize(int w, int h);
int virtualHeight, virtualWidth;
bool shuttingDown;
bool quitNestedMainFlag;
int nestedMains;
int nowTicks, thenTicks;
int _lastEnumeratedDisplayIndex;
virtual void onUpdate(float dt);
virtual void onRender(){}
virtual void onPrepareRender(){}
void setupFileAccess();
std::string _extraDataDir;
std::vector<ActionButtonStatus*> actionStatus; // contains at least 1 element (the sentinel)
virtual void updateActionButtons();
void clearActionButtons();
RenderGrid defaultQuadGrid;
DynamicGPUBuffer defautQuadBorder;
public:
RenderGrid blitQuad;
// inclusive!
inline int getMaxActionStatusIndex() const { return int(actionStatus.size()) - 2; }
// pass -1 for is a sentinel that captures all input
inline ActionButtonStatus *getActionStatus(size_t idx) { return actionStatus[idx + 1]; }
Joystick *getJoystick(size_t idx); // warning: may return NULL/contain holes
// not the actual number of joysticks!
size_t getNumJoysticks() const { return joysticks.size(); }
Joystick *getJoystickForSourceID(int sourceID);
private:
std::vector<Joystick*> joysticks;
unsigned sdlUserMouseEventID;
size_t _textureWatcherHandle;
};
extern Core *core;
#include "RenderObject_inline.h"
#endif