/* 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 "Effects.h" #include "Localization.h" #include "Window.h" #include "DarkLayer.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 }; const int NO_FOLLOW_CAMERA = -999; 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; } Vector position, lastPosition; MouseButtons buttons; MouseButtons pure_buttons; unsigned rawButtonMask; Vector change; bool buttonsEnabled; int scrollWheelChange; }; enum FollowCameraLock { FCL_NONE = 0, FCL_HORZ = 1, FCL_VERT = 2 }; typedef std::vector RenderObjects; class RenderObjectLayer { public: RenderObjectLayer(); ~RenderObjectLayer(); void add(RenderObject* r); void remove(RenderObject* r); void moveToFront(RenderObject *r); void moveToBack(RenderObject *r); void setCull(bool cull); void setOptimizeStatic(bool opt); void sort(); void renderPass(int pass); void reloadDevice(); 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; int followCameraLock; bool cull; bool update; Vector color; protected: void clearDisplayList(); void generateDisplayList(); inline void renderOneObject(RenderObject *robj); bool optimizeStatic; bool displayListValid; int displayListGeneration; struct DisplayListElement { DisplayListElement() {isList = false; u.robj = 0;} bool isList; // True if this is a GL display list union { RenderObject *robj; unsigned listID; } u; }; std::vector displayList; RenderObjects renderObjects; 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 clearBuffers(); void render(int startLayer=-1, int endLayer=-1, bool useFrameBufferIfAvail=true); void showBuffer(); void quit(); bool isShuttingDown(); bool isWindowFocus(); void instantQuit(); void cacheRender(); void reloadResources(); void unloadResources(); std::string getPreferencesFolder(); std::string getUserDataFolder(); void resetCamera(); virtual void shutdown(); void run(float runTime = -1); // can use main // state functions std::string getTextureLoadName(const std::string &texture); void setMousePosition(const Vector &p); void setFullscreen(bool full); void enable2D(int pixelScaleX, int pixelScaleY); void addRenderObject(RenderObject *o, size_t layer=0); void switchRenderObjectLayer(RenderObject *o, int toLayer); void addTexture(Texture *r); CountedPtr findTexture(const std::string &name); void removeTexture(Texture *res); void clearResources(); CountedPtr addTexture(const std::string &texture); PostProcessingFX postProcessingFx; 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){} bool exists(const std::string &file); void enqueueRenderObjectDeletion(RenderObject *object); void clearGarbage(); bool isNested() { return nestedMains > 1; } int getNestedMains() { return nestedMains; } void quitNestedMain(); int getWindowWidth() { return width; } int getWindowHeight() { return height; } unsigned getTicks(); void updateWindowDrawSize(int w, int h); Vector getGameCursorPosition(); Vector getGamePosition(const Vector &v); Vector screenCenter; void print(int x, int y, const char *str, float sz=1); std::vector resources; RenderObjectLayer *getRenderObjectLayer(int i); std::vector renderObjectLayerOrder; typedef std::vector 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 setBaseTextureDirectory(const std::string &newBaseTextureDirectory) { this->baseTextureDirectory = newBaseTextureDirectory; } std::string getBaseTextureDirectory() { return baseTextureDirectory; } virtual bool canChangeState(); void resetTimer(); inline int getVirtualWidth() { return virtualWidth; } inline int getVirtualHeight() { return virtualHeight; } unsigned char *grabScreenshot(int x, int y, int w, int h); unsigned char *grabCenteredScreenshot(int w, int h); bool saveScreenshot(const std::string &filename, bool png); bool minimized; std::string getEnqueuedJumpState(); float cullRadius; float cullRadiusSqr; Vector cullCenter; unsigned int renderObjectCount, processedRenderObjectCount, totalRenderObjectCount; float invGlobalScale, invGlobalScaleSqr; void globalScaleChanged(); void screenshot(); void clearRenderObjects(); bool getKeyState(int k); bool getMouseButtonState(int m); int currentLayerPass; 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(); void setupGlobalResolutionScale(); int particlesPaused; bool joystickEnabled; bool debugLogTextures; void setup_opengl(); void setClearColor(const Vector &c); int flipMouseButtons; FrameBuffer frameBuffer; void updateRenderObjects(float dt); bool joystickAsMouse; virtual void prepScreen(bool t){} bool updateMouse; bool frameOutputMode; int overrideStartLayer, overrideEndLayer; ParticleEffect* createParticleEffect(const std::string &name, const Vector &position, int layer, float rotz=0); std::string secondaryTexturePath; float get_old_dt() { return old_dt; } float get_current_dt() { return current_dt; } bool debugLogActive; void setInputGrab(bool on); void updateInputGrab(); bool isFullscreen(); bool isDesktopResolution(); int getDisplayIndex(); int getRefreshRate(); int getVirtualOffX(); int getVirtualOffY(); 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 screenModes; void pollEvents(float dt); void onEvent(const SDL_Event& event); CoreSettings settings; volatile int dbg_numThreadDecoders; virtual void onBackgroundUpdate(); void initLocalization(); 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(); CountedPtr doTextureAdd(const std::string &texture, const std::string &name, std::string internalTextureName); 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 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); int afterEffectManagerLayer; Vector cameraOffset; std::vector 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; std::string baseTextureDirectory; int nowTicks, thenTicks; int _lastEnumeratedDisplayIndex; virtual void onUpdate(float dt); virtual void onRender(){} void setupFileAccess(); std::string _extraDataDir; std::vector actionStatus; // contains at least 1 element (the sentinel) virtual void updateActionButtons(); void clearActionButtons(); public: // 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 joysticks; }; extern Core *core; #include "RenderObject_inline.h" #endif