]> code.bitgloo.com Git - clyne/gamedev.git/commitdiff
worldsystem snags drawing, theme stuff
authorClyne Sullivan <tullivan99@gmail.com>
Fri, 14 Oct 2016 01:28:35 +0000 (21:28 -0400)
committerClyne Sullivan <tullivan99@gmail.com>
Fri, 14 Oct 2016 01:28:35 +0000 (21:28 -0400)
brice.dat
include/common.hpp
include/coolarray.hpp
include/window.hpp
include/world.hpp
main.cpp
src/ui.cpp
src/window.cpp
src/world.cpp
xml/!town.xml

index a49519bc19be0df833e2e9e14dad4233653b8805..2653f9ce5cd4f99cef1fe2519168885e87cffb42 100644 (file)
--- a/brice.dat
+++ b/brice.dat
@@ -1,7 +1,7 @@
 3
-canSprint
+Slow
 1
 canJump
-1
-Slow
+0
+canSprint
 0
index 15442a7a23e59b15bfb00aedabc16e6e21d73295..69e6a11f81678d7f020d4161164cee02e71ea5a9 100644 (file)
@@ -71,25 +71,15 @@ typedef ivec2 dim2;
 /**
  * Creates a coordinate out of floating point integers.
  */
-class vec2 {
-public:
+struct vec2 {
        float x; /**< The x coordinate */
        float y; /**< The y coordinate */
 
-       /**
-        * Constructs an empty vec2.
-        */
-       vec2(){
-               x = y = 0.0f;
-       }
-
        /**
         * Constructs a vec2 with the specified coordinates.
         */
-       vec2(float _x, float _y) {
-               x = _x;
-               y = _y;
-       }
+       vec2(float _x = 0.0f, float _y = 0.0f)
+               : x(_x), y(_y) {}
 
        bool operator==(const vec2 &v) const {
                return (x == v.x) && (y == v.y);
@@ -105,33 +95,33 @@ public:
        const vec2 operator+(const T &n) {
                return vec2 (x + n, y + n);
        }
-};
+
+       // std::swap can't work due to being packed
+
+       inline void swapX(vec2 &v) {
+               float t = x;
+               x = v.x, v.x = t;
+       }
+
+       inline void swapY(vec2 &v) {
+               float t = y;
+               y = v.y, v.y = t;
+       }
+
+} __attribute__ ((packed));
 
 /**
  * A structure for three-dimensional points.
  */
-class vec3{
-public:
+struct vec3 {
        float x; /**< The x coordinate */
        float y; /**< The y coordinate */
        float z; /**< The z coordinate */
 
-       vec3() {
-               x = y = z = 0.0f;
-       }
+       vec3(float _x = 0.0f, float _y = 0.0f, float _z = 1.0f)
+               : x(_x), y(_y), z(_z) {}
 
-       vec3(float _x, float _y, float _z) {
-               x = _x;
-               y = _y;
-               z = _z;
-       }
-
-       vec3(float _x, float _y) {
-               x = _x;
-               y = _y;
-               z = 1.0f;
-       }
-};
+} __attribute__ ((packed));
 
 /**
  * This structure contains two sets of coordinates for ray drawing.
index be221b8133922dbd0d4d4bc696d1066c8deeb822..0df4f18e9d0e3add4d101fddb2c844bbf3f0fe34 100644 (file)
@@ -118,7 +118,7 @@ public:
 
        void push_back(const T& x) {
                if (_size >= _capacity)
-                       reserve(_capacity + 5);
+                       reserve(_capacity + 10);
 
                buffer[_size++] = x;
        }
index b642835abc8f96e29d51314019cf753d90e4417a..d168a5418e2c4fcda735694e48dc68e47cea89fc 100644 (file)
@@ -12,7 +12,8 @@ private:
 
 public:
        WindowSystem(void);
-       ~WindowSystem(void);
+
+       void die(void);
 
     void update(entityx::EntityManager &en, entityx::EventManager &ev, entityx::TimeDelta dt) override;
 };
index 17462ca79e6d49fc35f3869d3ce1648335bbac78..a99affa87be921e5ab889f5cc854e9c2fa40e691 100644 (file)
@@ -141,11 +141,18 @@ constexpr const char* WorldWeatherString[3] = {
 
 class WorldSystem : public entityx::System<WorldSystem>, public entityx::Receiver<WorldSystem> {
 private:
+       World *world;
+
        WorldWeather weather;
 
        Mix_Music *bgmObj;
        std::string bgmObjFile;
 
+       std::vector<std::string> bgFiles;
+       std::vector<std::string> bgFilesIndoors;
+
+       TextureIterator bgTex;
+
 public:
        explicit WorldSystem(void);
        ~WorldSystem(void);
@@ -157,6 +164,9 @@ public:
        void receive(const BGMToggleEvent &bte);
 
        void update(entityx::EntityManager &en, entityx::EventManager &ev, entityx::TimeDelta dt) override;
+       void render(void);
+
+       void setWorld(World *w);
 
        inline const std::string getWeatherStr(void) const
        { return WorldWeatherString[static_cast<int>(weather)]; }
@@ -176,8 +186,12 @@ public:
  */
 class World {
 //friend class ItemLight;
-protected:
+public:
+
+       WorldBGType bgType;
 
+       std::string styleFolder;
+       
        /**
         * An array of all the world's ground data, populated through
         * World::generate().
@@ -195,18 +209,6 @@ protected:
         */
        float worldStart;
 
-       /**
-        * Handles textures for the background elements.
-        */
-       TextureIterator bgTex;
-
-       /**
-        * Defines the set of background images being used for the world.
-        *
-        * @see setBackground()
-        */
-       WorldBGType bgType;
-
        /**
         * The path to the XML file of the world to the left.
         *
@@ -229,20 +231,6 @@ protected:
         */
        std::vector<std::string> sTexLoc;
 
-       /**
-        * The paths of files to be used for the background textures.
-        *
-        * @see setStyle()
-        */
-       std::vector<std::string> bgFiles;
-
-       /**
-        * The paths of files to be used for the indoor background textures.
-        *
-        * @see setStyle()
-        */
-       std::vector<std::string> bgFilesIndoors;
-
        /**
         * Contains randomly generated coordinates for stars.
         */
@@ -256,13 +244,6 @@ protected:
         */
        std::vector<Light>        light;
 
-       /**
-        * A vector of all particles in the world.
-        *
-        * @see addParticle()
-        */
-       //CoolArray<Particles>    particles;
-
        /**
         * A vector of all villages in the world.
         *
@@ -283,12 +264,6 @@ protected:
         */
        void deleteEntities(void);
 
-       /**
-        * Draws background textures.
-        */
-       void drawBackgrounds();
-
-public:
        /**
         * The filename of the world's BGM file.
         *
index 697452e53e7b38698bf2b33b4f2d72c23cc29724..91a2759e835e1726aa11328bd1ff691b39652a4a 100644 (file)
--- a/main.cpp
+++ b/main.cpp
@@ -194,7 +194,7 @@ int main(int argc, char *argv[])
        }
 
        if (worldDontReallyRun)
-               return 0;
+               goto EXIT_ROUTINE;
 
        if (!worldActuallyUseThisXMLFile.empty()) {
                delete currentWorld;
@@ -219,6 +219,8 @@ int main(int argc, char *argv[])
        ui::menu::init();
        game::events.emit<BGMToggleEvent>(currentWorld->bgm);
 
+       game::engine.getSystem<WorldSystem>()->setWorld(currentWorld);
+
        // spawn the arena
        arena = new Arena();
        arena->setStyle("");
@@ -248,6 +250,8 @@ int main(int argc, char *argv[])
                render();
        }
 
+EXIT_ROUTINE:
+
        // put away the brice for later
        game::briceSave();
 
@@ -264,6 +268,8 @@ int main(int argc, char *argv[])
        delete arena;
        //delete currentWorld;
 
+       game::engine.getSystem<WindowSystem>()->die();
+
     return 0; // Calls everything passed to atexit
 }
 
@@ -336,8 +342,9 @@ void render() {
        Render::worldShader.unuse();
 
        // draw the world and player
+       game::engine.getSystem<WorldSystem>()->render();
        currentWorld->draw(player);
-
+       
        // draw the player's inventory
        player->inv->draw();
 
index f7cc0992f1d068b77eadebc36abfdc8737198df6..09102a1b1471efaad9a029b920dd7feb8c745e77 100644 (file)
@@ -755,8 +755,8 @@ namespace ui {
                auto stride = 5 * sizeof(GLfloat);
 
                // we always want to make sure c1 is lower left and c2 is upper right
-               if (c1.x > c2.x) std::swap(c1.x, c2.y);
-               if (c1.y > c2.y) std::swap(c1.y, c2.y);
+               if (c1.x > c2.x) c1.swapX(c2); // std::swap(c1.x, c2.y);
+               if (c1.y > c2.y) c1.swapY(c2); // std::swap(c1.y, c2.y);
 
                // if the box is too small, we will not be able to draw it
                if (c2.x - c1.x < (box_corner_dim_t.x)) return;
index 4a060de084644ce8d9de6e5c3a6af9c36fe0793e..e21bf696ee0b139235da5eadda5375007a726db9 100644 (file)
@@ -55,7 +55,7 @@ WindowSystem::WindowSystem(void)
     }
 }
 
-WindowSystem::~WindowSystem(void)
+void WindowSystem::die(void)
 {
     SDL_GL_DeleteContext(glContext);
     SDL_DestroyWindow(window);
index 59a23eb1e1ba2e6a5820ee20287808e396576dd9..40edbb1991d1c94a302af9dd8fb2cda384a1822a 100644 (file)
@@ -226,271 +226,10 @@ generate(int width)
 
 static Color ambient;
 
-void World::drawBackgrounds(void)
-{
-    auto SCREEN_WIDTH = game::SCREEN_WIDTH;
-       auto SCREEN_HEIGHT = game::SCREEN_HEIGHT;
-    auto HLINE = game::HLINE;
-
-    const ivec2 backgroundOffset = ivec2 {
-        static_cast<int>(SCREEN_WIDTH) / 2, static_cast<int>(SCREEN_HEIGHT) / 2
-    };
-
-    // world width in pixels
-       int width = worldData.size() * HLINE;
-
-    // used for alpha values of background textures
-    int alpha;
-
-       switch (game::engine.getSystem<WorldSystem>()->getWeatherId()) {
-       case WorldWeather::Snowy:
-               alpha = 150;
-               break;
-       case WorldWeather::Rain:
-               alpha = 0;
-               break;
-       default:
-               alpha = 255 - worldShade * 4;
-               break;
-       }
-
-       // shade value for GLSL
-       float shadeAmbient = std::max(0.0f, static_cast<float>(-worldShade) / 50 + 0.5f); // 0 to 1.5f
-
-       if (shadeAmbient > 0.9f)
-               shadeAmbient = 1;
-
-    glActiveTexture(GL_TEXTURE0);
-    glUniform1i(Render::worldShader.uniform[WU_texture], 0);
-
-    // draw background images.
-    GLfloat tex_coord[] = { 0.0f, 1.0f,
-                            1.0f, 1.0f,
-                            1.0f, 0.0f,
-
-                            1.0f, 0.0f,
-                            0.0f, 0.0f,
-                            0.0f, 1.0f,};
-
-       // TODO scroll backdrop
-       GLfloat bgOff = game::time::getTickCount()/24000.0f;
-
-       GLfloat topS = .125f + bgOff;
-       GLfloat bottomS = 0.0f + bgOff;
-
-       if (topS < 0.0f) topS += 1.0f;
-       if (bottomS < 0.0f) bottomS += 1.0f;
-       if(bgOff < 0)std::cout << bottomS << "," << topS << std::endl;
-
-       GLfloat scrolling_tex_coord[] = {0.0f,  bottomS,
-                                                                        1.0f,  bottomS,
-                                                                        1.0f,  bottomS,
-
-                                                                        1.0f,  bottomS,
-                                                                        0.0f,  bottomS,
-                                                                        0.0f,  bottomS};
-
-       vec2 bg_tex_coord[] = { vec2(0.0f, 0.0f),
-                            vec2(1.0f, 0.0f),
-                            vec2(1.0f, 1.0f),
-
-                            vec2(1.0f, 1.0f),
-                            vec2(0.0f, 1.0f),
-                            vec2(0.0f, 0.0f)};
-
-    GLfloat back_tex_coord[] = {offset.x - backgroundOffset.x - 5, offset.y - backgroundOffset.y, 9.9f,
-                                offset.x + backgroundOffset.x + 5, offset.y - backgroundOffset.y, 9.9f,
-                                offset.x + backgroundOffset.x + 5, offset.y + backgroundOffset.y, 9.9f,
-
-                                offset.x + backgroundOffset.x + 5, offset.y + backgroundOffset.y, 9.9f,
-                                offset.x - backgroundOffset.x - 5, offset.y + backgroundOffset.y, 9.9f,
-                                offset.x - backgroundOffset.x - 5, offset.y - backgroundOffset.y, 9.9f};
-
-    GLfloat fron_tex_coord[] = {offset.x - backgroundOffset.x - 5, offset.y + backgroundOffset.y, 9.8f,
-                                offset.x + backgroundOffset.x + 5, offset.y + backgroundOffset.y, 9.8f,
-                                offset.x + backgroundOffset.x + 5, offset.y - backgroundOffset.y, 9.8f,
-
-                                offset.x + backgroundOffset.x + 5, offset.y - backgroundOffset.y, 9.8f,
-                                offset.x - backgroundOffset.x - 5, offset.y - backgroundOffset.y, 9.8f,
-                                offset.x - backgroundOffset.x - 5, offset.y + backgroundOffset.y, 9.8f};
-
-       Render::worldShader.use();
-       glUniform1f(Render::worldShader.uniform[WU_light_impact], 0.0f);
-       glUniform4f(Render::worldShader.uniform[WU_ambient], 1.0, 1.0, 1.0, 1.0);
-
-    Render::worldShader.enable();
-
-       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
-       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
-
-    bgTex(0);
-       glUniform4f(Render::worldShader.uniform[WU_tex_color], 1.0, 1.0, 1.0, 1.0);
-
-
-       makeWorldDrawingSimplerEvenThoughAndyDoesntThinkWeCanMakeItIntoFunctions(0, back_tex_coord, scrolling_tex_coord, 6);
-
-       bgTex++;
-       glUniform4f(Render::worldShader.uniform[WU_tex_color], 1.0, 1.0, 1.0, 1.3 - static_cast<float>(alpha)/255.0f);
-
-       makeWorldDrawingSimplerEvenThoughAndyDoesntThinkWeCanMakeItIntoFunctions(0, fron_tex_coord, tex_coord, 6);
-
-       // TODO make stars dynamic
-       //static GLuint starTex = Texture::genColor(Color(255, 255, 255));
-       static GLuint starTex = Texture::loadTexture("assets/style/classic/bg/star.png");
-       const static float stardim = 24;
-       GLfloat star_coord[star.size() * 5 * 6 + 1];
-    GLfloat *si = &star_coord[0];
-
-       if (worldShade > 0) {
-
-               auto xcoord = offset.x * 0.9f;
-
-               for (auto &s : star) {
-                       *(si++) = s.x + xcoord;
-                       *(si++) = s.y,
-                       *(si++) = 9.7f;
-
-                       *(si++) = 0.0;
-                       *(si++) = 0.0;
-
-                       *(si++) = s.x + xcoord + stardim;
-                       *(si++) = s.y,
-                       *(si++) = 9.7f;
-
-                       *(si++) = 1.0;
-                       *(si++) = 0.0;
-
-                       *(si++) = s.x + xcoord + stardim;
-                       *(si++) = s.y + stardim,
-                       *(si++) = 9.7f;
-
-                       *(si++) = 1.0;
-                       *(si++) = 1.0;
-
-                       *(si++) = s.x + xcoord + stardim;
-                       *(si++) = s.y + stardim,
-                       *(si++) = 9.7f;
-
-                       *(si++) = 1.0;
-                       *(si++) = 1.0;
-
-                       *(si++) = s.x + xcoord;
-                       *(si++) = s.y + stardim,
-                       *(si++) = 9.7f;
-
-                       *(si++) = 0.0;
-                       *(si++) = 1.0;
-
-                       *(si++) = s.x + xcoord;
-                       *(si++) = s.y,
-                       *(si++) = 9.7f;
-
-                       *(si++) = 0.0;
-                       *(si++) = 0.0;
-               }
-               glBindTexture(GL_TEXTURE_2D, starTex);
-               //glUniform4f(worldShader_uniform_color, 1.0, 1.0, 1.0, (255.0f - (randGet() % 200 - 100)) / 255.0f);
-               glUniform4f(Render::worldShader.uniform[WU_tex_color], 1.0, 1.0, 1.0, 1.3 - static_cast<float>(alpha)/255.0f);
-
-               makeWorldDrawingSimplerEvenThoughAndyDoesntThinkWeCanMakeItIntoFunctions(5 * sizeof(GLfloat), &star_coord[0], &star_coord[3], star.size() * 6);
-       }
-
-       Render::worldShader.disable();
-
-       glUniform4f(Render::worldShader.uniform[WU_tex_color], 1.0, 1.0, 1.0, 1.0);
-       glUniform4f(Render::worldShader.uniform[WU_ambient], ambient.red, ambient.green, ambient.blue, 1.0);
-
-       Render::worldShader.unuse();
-
-
-    std::vector<vec3> bg_items;
-
-       bgTex++;
-       dim2 mountainDim = bgTex.getTextureDim();
-    auto xcoord = width / 2 * -1 + offset.x * 0.85f;
-       for (unsigned int i = 0; i <= worldData.size() * HLINE / mountainDim.x; i++) {
-        bg_items.push_back(vec3(mountainDim.x * i       + xcoord, GROUND_HEIGHT_MINIMUM,                                8.0f));
-        bg_items.push_back(vec3(mountainDim.x * (i + 1) + xcoord, GROUND_HEIGHT_MINIMUM,                                8.0f));
-        bg_items.push_back(vec3(mountainDim.x * (i + 1) + xcoord, GROUND_HEIGHT_MINIMUM + mountainDim.y, 8.0f));
-
-        bg_items.push_back(vec3(mountainDim.x * (i + 1) + xcoord, GROUND_HEIGHT_MINIMUM + mountainDim.y, 8.0f));
-        bg_items.push_back(vec3(mountainDim.x * i       + xcoord, GROUND_HEIGHT_MINIMUM + mountainDim.y, 8.0f));
-        bg_items.push_back(vec3(mountainDim.x * i       + xcoord, GROUND_HEIGHT_MINIMUM,                                8.0f));
-       }
-
-    std::vector<GLfloat> bg_i;
-    std::vector<GLfloat> bg_tx;
-
-    for (auto &v : bg_items) {
-        bg_i.push_back(v.x);
-        bg_i.push_back(v.y);
-        bg_i.push_back(v.z);
-    }
-
-    for (uint i = 0; i < bg_items.size()/6; i++) {
-        for (auto &v : bg_tex_coord) {
-            bg_tx.push_back(v.x);
-            bg_tx.push_back(v.y);
-        }
-    }
-
-    Render::worldShader.use();
-       glUniform1f(Render::worldShader.uniform[WU_light_impact], 0.01);
-
-       makeWorldDrawingSimplerEvenThoughAndyDoesntThinkWeCanMakeItIntoFunctions_JustDrawThis(0, &bg_i[0], &bg_tx[0], bg_items.size());
-
-    Render::worldShader.unuse();
-
-       // draw the remaining layers
-       for (unsigned int i = 0; i < 4; i++) {
-        std::vector<vec3>c;
-               bgTex++;
-        dim2 dim = bgTex.getTextureDim();
-               auto xcoord = offset.x * bgDraw[i][2];
-               for (int j = worldStart; j <= -worldStart; j += dim.x) {
-            c.push_back(vec3(j         + xcoord, GROUND_HEIGHT_MINIMUM,                7-(i*.1)));
-            c.push_back(vec3(j + dim.x + xcoord, GROUND_HEIGHT_MINIMUM,                7-(i*.1)));
-            c.push_back(vec3(j + dim.x + xcoord, GROUND_HEIGHT_MINIMUM + dim.y, 7-(i*.1)));
-
-            c.push_back(vec3(j + dim.x + xcoord, GROUND_HEIGHT_MINIMUM + dim.y, 7-(i*.1)));
-            c.push_back(vec3(j         + xcoord, GROUND_HEIGHT_MINIMUM + dim.y, 7-(i*.1)));
-            c.push_back(vec3(j         + xcoord, GROUND_HEIGHT_MINIMUM,                7-(i*.1)));
-               }
-
-        bg_i.clear();
-        bg_tx.clear();
-
-        for (auto &v : c) {
-            bg_i.push_back(v.x);
-            bg_i.push_back(v.y);
-            bg_i.push_back(v.z);
-        }
-
-        for (uint i = 0; i < c.size()/6; i++) {
-            for (auto &v : bg_tex_coord) {
-                bg_tx.push_back(v.x);
-                bg_tx.push_back(v.y);
-            }
-        }
-
-        Render::worldShader.use();
-               glUniform1f(Render::worldShader.uniform[WU_light_impact], 0.075f + (0.2f*i));
-
-               makeWorldDrawingSimplerEvenThoughAndyDoesntThinkWeCanMakeItIntoFunctions_JustDrawThis(0, &bg_i[0], &bg_tx[0], c.size());
-
-        Render::worldShader.unuse();
-       }
-}
-
 void World::draw(Player *p)
 {
-       int iStart, iEnd, pOffset;
-
-       auto SCREEN_WIDTH = game::SCREEN_WIDTH;
        auto HLINE = game::HLINE;
 
-       drawBackgrounds();
-
        uint ls = light.size();
 
        GLfloat *lightCoords = new GLfloat[ls * 4];
@@ -548,201 +287,54 @@ void World::draw(Player *p)
 
        Render::worldShader.unuse();
 
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+       for (auto &e :entity)
+        e->draw();
 
-    // get the line that the player is currently standing on
-    pOffset = (offset.x + p->width / 2 - worldStart) / HLINE;
+       // flatten grass under the player if the player is on the ground
+       if (p->ground) {
+               int pOffset = (p->loc.x + p->width / 2 - worldStart) / HLINE;
 
-    // only draw world within player vision
-    iStart = std::clamp(static_cast<int>(pOffset - (SCREEN_WIDTH / 2 / HLINE) - GROUND_HILLINESS),
-                           0, static_cast<int>(lineCount));
-       iEnd = std::clamp(static_cast<int>(pOffset + (SCREEN_WIDTH / 2 / HLINE)),
-                      0, static_cast<int>(lineCount));
+               for (unsigned int i = 0; i < worldData.size(); i++)
+                       worldData[i].grassUnpressed = !(i < static_cast<unsigned int>(pOffset + 6) && i > static_cast<unsigned int>(pOffset - 6));
+       } else {
+               for (auto &wd : worldData)
+                       wd.grassUnpressed = true;
+       }
 
-    // draw the dirt
-    bgTex++;
-    std::vector<std::pair<vec2,vec3>> c;
+    // draw the player
+       //p->draw();
 
-    for (int i = iStart; i < iEnd; i++) {
-        if (worldData[i].groundHeight <= 0) { // TODO holes (andy)
-            worldData[i].groundHeight = GROUND_HEIGHT_MINIMUM - 1;
-            glColor4ub(0, 0, 0, 255);
-        } else {
-            safeSetColorA(150, 150, 150, 255);
-        }
+       // draw particles like a MASTAH
+    glBindTexture(GL_TEXTURE_2D, colorIndex);
+    glUniform1i(Render::worldShader.uniform[WU_texture], 0);
+    Render::worldShader.use();
 
-        int ty = worldData[i].groundHeight / 64 + worldData[i].groundColor;
-        // glTexCoord2i(0, 0);  glVertex2i(worldStart + i * HLINE         , worldData[i].groundHeight - GRASS_HEIGHT);
-        // glTexCoord2i(1, 0);  glVertex2i(worldStart + i * HLINE + HLINE , worldData[i].groundHeight - GRASS_HEIGHT);
-        // glTexCoord2i(1, ty); glVertex2i(worldStart + i * HLINE + HLINE, 0);
-        // glTexCoord2i(0, ty); glVertex2i(worldStart + i * HLINE            , 0);
+       glUniform4f(Render::worldShader.uniform[WU_tex_color], 1.0, 1.0, 1.0, .8);
 
-               c.push_back(std::make_pair(vec2(0, 0), vec3(worldStart + HLINES(i),         worldData[i].groundHeight - GRASS_HEIGHT, -4.0f)));
-        c.push_back(std::make_pair(vec2(1, 0), vec3(worldStart + HLINES(i) + HLINE, worldData[i].groundHeight - GRASS_HEIGHT, -4.0f)));
-        c.push_back(std::make_pair(vec2(1, ty),vec3(worldStart + HLINES(i) + HLINE, 0,                                        -4.0f)));
+    Render::worldShader.enable();
 
-        c.push_back(std::make_pair(vec2(1, ty),vec3(worldStart + HLINES(i) + HLINE, 0,                                        -4.0f)));
-        c.push_back(std::make_pair(vec2(0, ty),vec3(worldStart + HLINES(i),         0,                                        -4.0f)));
-        c.push_back(std::make_pair(vec2(0, 0), vec3(worldStart + HLINES(i),         worldData[i].groundHeight - GRASS_HEIGHT, -4.0f)));
+       partMutex.lock();
+       uint ps = particles.size();
+    uint pss = ps * 6 * 5;
+       uint pc = 0;
 
-        if (worldData[i].groundHeight == GROUND_HEIGHT_MINIMUM - 1)
-            worldData[i].groundHeight = 0;
+       std::vector<GLfloat> partVec(pss);
+       auto *pIndex = &partVec[0];
+       for (uint i = 0; i < ps; i++) {
+        pc += 30;
+               if (pc > pss) {
+                       // TODO resize the vector or something better than breaking
+                       break;
+               }
+               particles[i].draw(pIndex);
     }
+       partMutex.unlock();
 
-    std::vector<GLfloat> dirtc;
-    std::vector<GLfloat> dirtt;
+    glVertexAttribPointer(Render::worldShader.coord, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), &partVec[0]);
+    glVertexAttribPointer(Render::worldShader.tex, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), &partVec[3]);
+    glDrawArrays(GL_TRIANGLES, 0, ps * 6);
 
-    for (auto &v : c) {
-        dirtc.push_back(v.second.x);
-        dirtc.push_back(v.second.y);
-        dirtc.push_back(v.second.z);
-
-        dirtt.push_back(v.first.x);
-        dirtt.push_back(v.first.y);
-    }
-
-    Render::worldShader.use();
-       glUniform1f(Render::worldShader.uniform[WU_light_impact], 0.45f);
-
-    Render::worldShader.enable();
-
-    glVertexAttribPointer(Render::worldShader.coord, 3, GL_FLOAT, GL_FALSE, 0, &dirtc[0]);
-    glVertexAttribPointer(Render::worldShader.tex, 2, GL_FLOAT, GL_FALSE, 0, &dirtt[0]);
-    glDrawArrays(GL_TRIANGLES, 0 , c.size());
-
-    Render::worldShader.disable();
-       Render::worldShader.unuse();
-
-       //glEnd();
-
-       //glUseProgram(0);
-
-       // draw the grass
-       //glEnable(GL_TEXTURE_2D);
-       //glActiveTexture(GL_TEXTURE0);
-       bgTex++;
-       //glUseProgram(shaderProgram);
-       //glUniform1i(glGetUniformLocation(shaderProgram, "sampler"), 0);
-    safeSetColorA(255, 255, 255, 255);
-
-    c.clear();
-    std::vector<GLfloat> grassc;
-    std::vector<GLfloat> grasst;
-
-       for (int i = iStart; i < iEnd; i++) {
-        auto wd = worldData[i];
-        auto gh = wd.grassHeight;
-
-               // flatten the grass if the player is standing on it.
-       if (!wd.grassUnpressed) {
-               gh[0] /= 4;
-                       gh[1] /= 4;
-               }
-
-               // actually draw the grass.
-        if (wd.groundHeight) {
-               //glBegin(GL_QUADS);
-                       /*glTexCoord2i(0, 0); glVertex2i(worldStart + i * HLINE            , wd.groundHeight + gh[0]);
-                       glTexCoord2i(1, 0); glVertex2i(worldStart + i * HLINE + HLINE / 2, wd.groundHeight + gh[0]);
-                       glTexCoord2i(1, 1); glVertex2i(worldStart + i * HLINE + HLINE / 2, wd.groundHeight - GRASS_HEIGHT);
-                       glTexCoord2i(0, 1); glVertex2i(worldStart + i * HLINE                , wd.groundHeight - GRASS_HEIGHT);
-                glTexCoord2i(0, 0); glVertex2i(worldStart + i * HLINE + HLINE / 2, wd.groundHeight + gh[1]);
-                       glTexCoord2i(1, 0); glVertex2i(worldStart + i * HLINE + HLINE    , wd.groundHeight + gh[1]);
-                       glTexCoord2i(1, 1); glVertex2i(worldStart + i * HLINE + HLINE    , wd.groundHeight - GRASS_HEIGHT);
-                       glTexCoord2i(0, 1); glVertex2i(worldStart + i * HLINE + HLINE / 2, wd.groundHeight - GRASS_HEIGHT);*/
-
-                c.push_back(std::make_pair(vec2(0, 0),vec3(worldStart + HLINES(i)            , wd.groundHeight + gh[0],                -3)));
-                c.push_back(std::make_pair(vec2(1, 0),vec3(worldStart + HLINES(i) + HLINE / 2, wd.groundHeight + gh[0],                -3)));
-                c.push_back(std::make_pair(vec2(1, 1),vec3(worldStart + HLINES(i) + HLINE / 2, wd.groundHeight - GRASS_HEIGHT,         -3)));
-
-                c.push_back(std::make_pair(vec2(1, 1),vec3(worldStart + HLINES(i) + HLINE / 2, wd.groundHeight - GRASS_HEIGHT, -3)));
-                c.push_back(std::make_pair(vec2(0, 1),vec3(worldStart + HLINES(i)                   , wd.groundHeight - GRASS_HEIGHT,  -3)));
-                c.push_back(std::make_pair(vec2(0, 0),vec3(worldStart + HLINES(i)            , wd.groundHeight + gh[0],                        -3)));
-
-
-                c.push_back(std::make_pair(vec2(0, 0),vec3(worldStart + HLINES(i) + HLINE / 2, wd.groundHeight + gh[1],                        -3)));
-                c.push_back(std::make_pair(vec2(1, 0),vec3(worldStart + HLINES(i) + HLINE    , wd.groundHeight + gh[1],                        -3)));
-                c.push_back(std::make_pair(vec2(1, 1),vec3(worldStart + HLINES(i) + HLINE    , wd.groundHeight - GRASS_HEIGHT, -3)));
-
-                c.push_back(std::make_pair(vec2(1, 1),vec3(worldStart + HLINES(i) + HLINE    , wd.groundHeight - GRASS_HEIGHT, -3)));
-                c.push_back(std::make_pair(vec2(0, 1),vec3(worldStart + HLINES(i) + HLINE / 2, wd.groundHeight - GRASS_HEIGHT, -3)));
-                c.push_back(std::make_pair(vec2(0, 0),vec3(worldStart + HLINES(i) + HLINE / 2, wd.groundHeight + gh[1],                        -3)));
-
-            //glEnd();
-        }
-       }
-
-    for (auto &v : c) {
-        grassc.push_back(v.second.x);
-        grassc.push_back(v.second.y);
-        grassc.push_back(v.second.z);
-
-        grasst.push_back(v.first.x);
-        grasst.push_back(v.first.y);
-    }
-
-    Render::worldShader.use();
-       glUniform1f(Render::worldShader.uniform[WU_light_impact], 1.0f);
-
-    Render::worldShader.enable();
-
-    glVertexAttribPointer(Render::worldShader.coord, 3, GL_FLOAT, GL_FALSE, 0, &grassc[0]);
-    glVertexAttribPointer(Render::worldShader.tex, 2, GL_FLOAT, GL_FALSE, 0, &grasst[0]);
-    glDrawArrays(GL_TRIANGLES, 0 , c.size());
-
-    Render::worldShader.disable();
-       Render::worldShader.unuse();
-
-       for (auto &e :entity)
-        e->draw();
-
-       // flatten grass under the player if the player is on the ground
-       if (p->ground) {
-               pOffset = (p->loc.x + p->width / 2 - worldStart) / HLINE;
-
-               for (unsigned int i = 0; i < worldData.size(); i++)
-                       worldData[i].grassUnpressed = !(i < static_cast<unsigned int>(pOffset + 6) && i > static_cast<unsigned int>(pOffset - 6));
-       } else {
-               for (auto &wd : worldData)
-                       wd.grassUnpressed = true;
-       }
-
-    // draw the player
-       p->draw();
-
-       // draw particles like a MASTAH
-    glBindTexture(GL_TEXTURE_2D, colorIndex);
-    glUniform1i(Render::worldShader.uniform[WU_texture], 0);
-    Render::worldShader.use();
-
-       glUniform4f(Render::worldShader.uniform[WU_tex_color], 1.0, 1.0, 1.0, .8);
-
-    Render::worldShader.enable();
-
-       partMutex.lock();
-       uint ps = particles.size();
-    uint pss = ps * 6 * 5;
-       uint pc = 0;
-
-       std::vector<GLfloat> partVec(pss);
-       auto *pIndex = &partVec[0];
-       for (uint i = 0; i < ps; i++) {
-        pc += 30;
-               if (pc > pss) {
-                       // TODO resize the vector or something better than breaking
-                       //std::cout << "Whoops:" << pc << "," << partVec.size() << std::endl;
-                       break;
-               }
-               particles[i].draw(pIndex);
-    }
-       partMutex.unlock();
-
-    glVertexAttribPointer(Render::worldShader.coord, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), &partVec[0]);
-    glVertexAttribPointer(Render::worldShader.tex, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), &partVec[3]);
-    glDrawArrays(GL_TRIANGLES, 0, ps * 6);
-
-    Render::worldShader.disable();
+    Render::worldShader.disable();
 
        glUniform4f(Render::worldShader.uniform[WU_tex_color], 1.0, 1.0, 1.0, 1.0);
 
@@ -1120,18 +712,7 @@ void World::save(const std::string& s)
  */
 void World::setBackground(WorldBGType bgt)
 {
-    // load textures with a limit check
-       switch ((bgType = bgt)) {
-       case WorldBGType::Forest:
-               bgTex = TextureIterator(bgFiles);
-               break;
-       case WorldBGType::WoodHouse:
-               bgTex = TextureIterator(bgFilesIndoors);
-               break;
-    default:
-        UserError("Invalid world background type");
-        break;
-       }
+       bgType = bgt;
 }
 
 /**
@@ -1143,16 +724,10 @@ void World::setStyle(std::string pre)
 {
     // get folder prefix
        std::string prefix = pre.empty() ? "assets/style/classic/" : pre;
+       styleFolder = prefix + "bg/";
 
     for (const auto &s : buildPaths)
         sTexLoc.push_back(prefix + s);
-
-    prefix += "bg/";
-
-    for (const auto &s : bgPaths[0])
-        bgFiles.push_back(prefix + s);
-    for (const auto &s : bgPaths[1])
-        bgFilesIndoors.push_back(prefix + s);
 }
 
 /**
@@ -1590,7 +1165,7 @@ draw(Player *p)
        Render::worldShader.use();
 
        glActiveTexture(GL_TEXTURE0);
-       bgTex(0);
+       //game::engine.getSystem<WorldSystem>bgTex(0);
 
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); //for the s direction
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); //for the t direction
@@ -1627,56 +1202,20 @@ draw(Player *p)
        static GLuint floorTex = Texture::genColor(Color(150, 100, 50));
        glBindTexture(GL_TEXTURE_2D, floorTex);
 
-       std::vector<GLfloat> fc;
-       std::vector<GLfloat> ft;
+       Render::worldShader.use();
+       Render::useShader(&Render::worldShader);
 
        for (fl = 0; fl < floor.size(); fl++) {
         i = 0;
        for (const auto &h : floor[fl]) {
                x = worldStart + HLINES(fstart[fl] + i);
 
-                       fc.emplace_back(x);
-               fc.emplace_back(h);
-                       fc.emplace_back(-3);
-                       ft.emplace_back(0);
-                       ft.emplace_back(0);
-
-                       fc.emplace_back(x + HLINE);
-                       fc.emplace_back(h);
-                       fc.emplace_back(-3);
-                       ft.emplace_back(1);
-                       ft.emplace_back(0);
-
-                       fc.emplace_back(x + HLINE);
-                       fc.emplace_back(h - INDOOR_FLOOR_THICKNESS);
-                       fc.emplace_back(-3);
-                       ft.emplace_back(1);
-                       ft.emplace_back(1);
-
-                       fc.emplace_back(x + HLINE);
-                       fc.emplace_back(h - INDOOR_FLOOR_THICKNESS);
-                       fc.emplace_back(-3);
-                       ft.emplace_back(1);
-                       ft.emplace_back(1);
-
-                       fc.emplace_back(x);
-                       fc.emplace_back(h - INDOOR_FLOOR_THICKNESS);
-                       fc.emplace_back(-3);
-                       ft.emplace_back(0);
-                       ft.emplace_back(1);
-
-                       fc.emplace_back(x);
-               fc.emplace_back(h);
-                       fc.emplace_back(-3);
-                       ft.emplace_back(0);
-                       ft.emplace_back(0);
+                       Render::drawRect(vec2 {(float)x, h}, vec2 {(float)(x + HLINE), h - INDOOR_FLOOR_THICKNESS}, -3.0f);
 
                        i++;
        }
     }
 
-       Render::worldShader.use();
-       makeWorldDrawingSimplerEvenThoughAndyDoesntThinkWeCanMakeItIntoFunctions_JustDrawThis(0, &fc[0], &ft[0], floor.size() * 6);
        Render::worldShader.unuse();
 
        /*
@@ -2132,10 +1671,366 @@ void WorldSystem::update(entityx::EntityManager &en, entityx::EventManager &ev,
                Mix_FadeInMusic(bgmObj, -1, 2000);
 }
 
-void WorldSystem::receive(const BGMToggleEvent &bte)
+void WorldSystem::render(void)
 {
-       std::cout << bgmObjFile << '|' << (int)(bte.world == nullptr) << '|' << bte.file << '\n';
+       const auto SCREEN_WIDTH = game::SCREEN_WIDTH;
+       const auto SCREEN_HEIGHT = game::SCREEN_HEIGHT;
+       const auto HLINE = game::HLINE;
+
+       const ivec2 backgroundOffset = ivec2 {
+        static_cast<int>(SCREEN_WIDTH) / 2, static_cast<int>(SCREEN_HEIGHT) / 2
+    };
+
+       auto& worldData = currentWorld->worldData;
+       auto& star = currentWorld->star;
+       auto worldStart = currentWorld->worldStart;
+
+       int iStart, iEnd, pOffset;
+
+    // world width in pixels
+       int width = worldData.size() * HLINE;
+
+    // used for alpha values of background textures
+    int alpha;
+
+       switch (weather) {
+       case WorldWeather::Snowy:
+               alpha = 150;
+               break;
+       case WorldWeather::Rain:
+               alpha = 0;
+               break;
+       default:
+               alpha = 255 - worldShade * 4;
+               break;
+       }
+
+       // shade value for GLSL
+       float shadeAmbient = std::max(0.0f, static_cast<float>(-worldShade) / 50 + 0.5f); // 0 to 1.5f
+
+       if (shadeAmbient > 0.9f)
+               shadeAmbient = 1;
+
+    // draw background images.
+    GLfloat tex_coord[] = { 0.0f, 1.0f,
+                            1.0f, 1.0f,
+                            1.0f, 0.0f,
+
+                            1.0f, 0.0f,
+                            0.0f, 0.0f,
+                            0.0f, 1.0f,};
+
+       // TODO scroll backdrop
+       GLfloat bgOff = game::time::getTickCount()/24000.0f;
+
+       GLfloat topS = .125f + bgOff;
+       GLfloat bottomS = 0.0f + bgOff;
+
+       if (topS < 0.0f) topS += 1.0f;
+       if (bottomS < 0.0f) bottomS += 1.0f;
+       if(bgOff < 0)std::cout << bottomS << "," << topS << std::endl;
+
+       GLfloat scrolling_tex_coord[] = {0.0f,  bottomS,
+                                                                        1.0f,  bottomS,
+                                                                        1.0f,  bottomS,
+
+                                                                        1.0f,  bottomS,
+                                                                        0.0f,  bottomS,
+                                                                        0.0f,  bottomS};
+
+       vec2 bg_tex_coord[] = { vec2(0.0f, 0.0f),
+                            vec2(1.0f, 0.0f),
+                            vec2(1.0f, 1.0f),
+
+                            vec2(1.0f, 1.0f),
+                            vec2(0.0f, 1.0f),
+                            vec2(0.0f, 0.0f)};
+
+    GLfloat back_tex_coord[] = {offset.x - backgroundOffset.x - 5, offset.y - backgroundOffset.y, 9.9f,
+                                offset.x + backgroundOffset.x + 5, offset.y - backgroundOffset.y, 9.9f,
+                                offset.x + backgroundOffset.x + 5, offset.y + backgroundOffset.y, 9.9f,
+
+                                offset.x + backgroundOffset.x + 5, offset.y + backgroundOffset.y, 9.9f,
+                                offset.x - backgroundOffset.x - 5, offset.y + backgroundOffset.y, 9.9f,
+                                offset.x - backgroundOffset.x - 5, offset.y - backgroundOffset.y, 9.9f};
+
+    GLfloat fron_tex_coord[] = {offset.x - backgroundOffset.x - 5, offset.y + backgroundOffset.y, 9.8f,
+                                offset.x + backgroundOffset.x + 5, offset.y + backgroundOffset.y, 9.8f,
+                                offset.x + backgroundOffset.x + 5, offset.y - backgroundOffset.y, 9.8f,
+
+                                offset.x + backgroundOffset.x + 5, offset.y - backgroundOffset.y, 9.8f,
+                                offset.x - backgroundOffset.x - 5, offset.y - backgroundOffset.y, 9.8f,
+                                offset.x - backgroundOffset.x - 5, offset.y + backgroundOffset.y, 9.8f};
+
+       // rendering!!
+
+    glActiveTexture(GL_TEXTURE0);
+    glUniform1i(Render::worldShader.uniform[WU_texture], 0);
 
+       Render::worldShader.use();
+       glUniform1f(Render::worldShader.uniform[WU_light_impact], 0.0f);
+       glUniform4f(Render::worldShader.uniform[WU_ambient], 1.0, 1.0, 1.0, 1.0);
+
+    Render::worldShader.enable();
+
+       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+
+    bgTex(0);
+       glUniform4f(Render::worldShader.uniform[WU_tex_color], 1.0, 1.0, 1.0, 1.0);
+
+
+       makeWorldDrawingSimplerEvenThoughAndyDoesntThinkWeCanMakeItIntoFunctions(0, back_tex_coord, scrolling_tex_coord, 6);
+
+       bgTex++;
+       glUniform4f(Render::worldShader.uniform[WU_tex_color], 1.0, 1.0, 1.0, 1.3 - static_cast<float>(alpha)/255.0f);
+
+       makeWorldDrawingSimplerEvenThoughAndyDoesntThinkWeCanMakeItIntoFunctions(0, fron_tex_coord, tex_coord, 6);
+
+       // TODO make stars dynamic
+       static GLuint starTex = Texture::loadTexture("assets/style/classic/bg/star.png");
+       const static float stardim = 24;
+       GLfloat star_coord[star.size() * 5 * 6 + 1];
+    GLfloat *si = &star_coord[0];
+
+       if (worldShade > 0) {
+
+               auto xcoord = offset.x * 0.9f;
+
+               for (auto &s : star) {
+                       float data[30] = {
+                               s.x + xcoord, s.y, 9.7, 0, 0,
+                               s.x + xcoord + stardim, s.y, 9.7, 1, 0,
+                               s.x + xcoord + stardim, s.y + stardim, 9.7, 1, 1,
+                               s.x + xcoord + stardim, s.y + stardim, 9.7, 1, 1,
+                               s.x + xcoord, s.y + stardim, 9.7, 0, 1,
+                               s.x + xcoord, s.y, 9.7, 0, 0
+                       };
+
+                       std::memcpy(si, data, sizeof(float) * 30);
+                       si += 30;
+               }
+               glBindTexture(GL_TEXTURE_2D, starTex);
+               glUniform4f(Render::worldShader.uniform[WU_tex_color], 1.0, 1.0, 1.0, 1.3 - static_cast<float>(alpha)/255.0f);
+
+               makeWorldDrawingSimplerEvenThoughAndyDoesntThinkWeCanMakeItIntoFunctions(5 * sizeof(GLfloat), &star_coord[0], &star_coord[3], star.size() * 6);
+       }
+
+       Render::worldShader.disable();
+
+       glUniform4f(Render::worldShader.uniform[WU_tex_color], 1.0, 1.0, 1.0, 1.0);
+       glUniform4f(Render::worldShader.uniform[WU_ambient], ambient.red, ambient.green, ambient.blue, 1.0);
+
+       Render::worldShader.unuse();
+
+    std::vector<vec3> bg_items;
+       std::vector<vec2> bg_tex;
+
+       bgTex++;
+       dim2 mountainDim = bgTex.getTextureDim();
+    auto xcoord = width / 2 * -1 + offset.x * 0.85f;
+       for (unsigned int i = 0; i <= worldData.size() * HLINE / mountainDim.x; i++) {
+        bg_items.emplace_back(mountainDim.x * i       + xcoord, GROUND_HEIGHT_MINIMUM,                                  8.0f);
+        bg_items.emplace_back(mountainDim.x * (i + 1) + xcoord, GROUND_HEIGHT_MINIMUM,                                  8.0f);
+        bg_items.emplace_back(mountainDim.x * (i + 1) + xcoord, GROUND_HEIGHT_MINIMUM + mountainDim.y, 8.0f);
+
+        bg_items.emplace_back(mountainDim.x * (i + 1) + xcoord, GROUND_HEIGHT_MINIMUM + mountainDim.y, 8.0f);
+        bg_items.emplace_back(mountainDim.x * i       + xcoord, GROUND_HEIGHT_MINIMUM + mountainDim.y, 8.0f);
+        bg_items.emplace_back(mountainDim.x * i       + xcoord, GROUND_HEIGHT_MINIMUM,                                  8.0f);
+       }
+
+    for (uint i = 0; i < bg_items.size()/6; i++) {
+        for (auto &v : bg_tex_coord)
+            bg_tex.push_back(v);
+    }
+
+    Render::worldShader.use();
+       glUniform1f(Render::worldShader.uniform[WU_light_impact], 0.01);
+
+       makeWorldDrawingSimplerEvenThoughAndyDoesntThinkWeCanMakeItIntoFunctions_JustDrawThis(0, bg_items.data(), bg_tex.data(), bg_items.size());
+
+    Render::worldShader.unuse();
+
+       // draw the remaining layers
+       for (unsigned int i = 0; i < 4; i++) {
+               bgTex++;
+        dim2 dim = bgTex.getTextureDim();
+               auto xcoord = offset.x * bgDraw[i][2];
+
+               bg_items.clear();
+               bg_tex.clear();
+
+               for (int j = worldStart; j <= -worldStart; j += dim.x) {
+            bg_items.emplace_back(j         + xcoord, GROUND_HEIGHT_MINIMUM,           7-(i*.1));
+            bg_items.emplace_back(j + dim.x + xcoord, GROUND_HEIGHT_MINIMUM,           7-(i*.1));
+            bg_items.emplace_back(j + dim.x + xcoord, GROUND_HEIGHT_MINIMUM + dim.y, 7-(i*.1));
+
+            bg_items.emplace_back(j + dim.x + xcoord, GROUND_HEIGHT_MINIMUM + dim.y, 7-(i*.1));
+            bg_items.emplace_back(j         + xcoord, GROUND_HEIGHT_MINIMUM + dim.y, 7-(i*.1));
+            bg_items.emplace_back(j         + xcoord, GROUND_HEIGHT_MINIMUM,           7-(i*.1));
+               }
+
+        for (uint i = 0; i < bg_items.size()/6; i++) {
+            for (auto &v : bg_tex_coord)
+                bg_tex.push_back(v);
+        }
+
+        Render::worldShader.use();
+               glUniform1f(Render::worldShader.uniform[WU_light_impact], 0.075f + (0.2f*i));
+
+               makeWorldDrawingSimplerEvenThoughAndyDoesntThinkWeCanMakeItIntoFunctions_JustDrawThis(0, bg_items.data(), &bg_tex[0], bg_items.size());
+
+        Render::worldShader.unuse();
+       }
+
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+
+    // get the line that the player is currently standing on
+    pOffset = (offset.x + player->width / 2 - worldStart) / HLINE;
+
+    // only draw world within player vision
+    iStart = std::clamp(static_cast<int>(pOffset - (SCREEN_WIDTH / 2 / HLINE) - GROUND_HILLINESS),
+                           0, static_cast<int>(world->lineCount));
+       iEnd = std::clamp(static_cast<int>(pOffset + (SCREEN_WIDTH / 2 / HLINE)),
+                      0, static_cast<int>(world->lineCount));
+
+    // draw the dirt
+    bgTex++;
+    std::vector<std::pair<vec2,vec3>> c;
+
+    for (int i = iStart; i < iEnd; i++) {
+        if (worldData[i].groundHeight <= 0) { // TODO holes (andy)
+            worldData[i].groundHeight = GROUND_HEIGHT_MINIMUM - 1;
+            glColor4ub(0, 0, 0, 255);
+        } else {
+            safeSetColorA(150, 150, 150, 255);
+        }
+
+        int ty = worldData[i].groundHeight / 64 + worldData[i].groundColor;
+
+               c.push_back(std::make_pair(vec2(0, 0), vec3(worldStart + HLINES(i),         worldData[i].groundHeight - GRASS_HEIGHT, -4.0f)));
+        c.push_back(std::make_pair(vec2(1, 0), vec3(worldStart + HLINES(i) + HLINE, worldData[i].groundHeight - GRASS_HEIGHT, -4.0f)));
+        c.push_back(std::make_pair(vec2(1, ty),vec3(worldStart + HLINES(i) + HLINE, 0,                                        -4.0f)));
+
+        c.push_back(std::make_pair(vec2(1, ty),vec3(worldStart + HLINES(i) + HLINE, 0,                                        -4.0f)));
+        c.push_back(std::make_pair(vec2(0, ty),vec3(worldStart + HLINES(i),         0,                                        -4.0f)));
+        c.push_back(std::make_pair(vec2(0, 0), vec3(worldStart + HLINES(i),         worldData[i].groundHeight - GRASS_HEIGHT, -4.0f)));
+
+        if (worldData[i].groundHeight == GROUND_HEIGHT_MINIMUM - 1)
+            worldData[i].groundHeight = 0;
+    }
+
+    std::vector<GLfloat> dirtc;
+    std::vector<GLfloat> dirtt;
+
+    for (auto &v : c) {
+        dirtc.push_back(v.second.x);
+        dirtc.push_back(v.second.y);
+        dirtc.push_back(v.second.z);
+
+        dirtt.push_back(v.first.x);
+        dirtt.push_back(v.first.y);
+    }
+
+    Render::worldShader.use();
+       glUniform1f(Render::worldShader.uniform[WU_light_impact], 0.45f);
+
+    Render::worldShader.enable();
+
+    glVertexAttribPointer(Render::worldShader.coord, 3, GL_FLOAT, GL_FALSE, 0, &dirtc[0]);
+    glVertexAttribPointer(Render::worldShader.tex, 2, GL_FLOAT, GL_FALSE, 0, &dirtt[0]);
+    glDrawArrays(GL_TRIANGLES, 0 , c.size());
+
+    Render::worldShader.disable();
+       Render::worldShader.unuse();
+
+       bgTex++;
+    safeSetColorA(255, 255, 255, 255);
+
+    c.clear();
+    std::vector<GLfloat> grassc;
+    std::vector<GLfloat> grasst;
+
+       for (int i = iStart; i < iEnd; i++) {
+        auto wd = worldData[i];
+        auto gh = wd.grassHeight;
+
+               // flatten the grass if the player is standing on it.
+       if (!wd.grassUnpressed) {
+               gh[0] /= 4;
+                       gh[1] /= 4;
+               }
+
+               // actually draw the grass.
+        if (wd.groundHeight) {
+            c.push_back(std::make_pair(vec2(0, 0),vec3(worldStart + HLINES(i)            , wd.groundHeight + gh[0],            -3)));
+            c.push_back(std::make_pair(vec2(1, 0),vec3(worldStart + HLINES(i) + HLINE / 2, wd.groundHeight + gh[0],            -3)));
+            c.push_back(std::make_pair(vec2(1, 1),vec3(worldStart + HLINES(i) + HLINE / 2, wd.groundHeight - GRASS_HEIGHT,     -3)));
+
+            c.push_back(std::make_pair(vec2(1, 1),vec3(worldStart + HLINES(i) + HLINE / 2, wd.groundHeight - GRASS_HEIGHT,     -3)));
+            c.push_back(std::make_pair(vec2(0, 1),vec3(worldStart + HLINES(i)               , wd.groundHeight - GRASS_HEIGHT,  -3)));
+            c.push_back(std::make_pair(vec2(0, 0),vec3(worldStart + HLINES(i)            , wd.groundHeight + gh[0],                    -3)));
+
+            c.push_back(std::make_pair(vec2(0, 0),vec3(worldStart + HLINES(i) + HLINE / 2, wd.groundHeight + gh[1],                    -3)));
+            c.push_back(std::make_pair(vec2(1, 0),vec3(worldStart + HLINES(i) + HLINE    , wd.groundHeight + gh[1],                    -3)));
+            c.push_back(std::make_pair(vec2(1, 1),vec3(worldStart + HLINES(i) + HLINE    , wd.groundHeight - GRASS_HEIGHT,     -3)));
+
+            c.push_back(std::make_pair(vec2(1, 1),vec3(worldStart + HLINES(i) + HLINE    , wd.groundHeight - GRASS_HEIGHT,     -3)));
+            c.push_back(std::make_pair(vec2(0, 1),vec3(worldStart + HLINES(i) + HLINE / 2, wd.groundHeight - GRASS_HEIGHT,     -3)));
+            c.push_back(std::make_pair(vec2(0, 0),vec3(worldStart + HLINES(i) + HLINE / 2, wd.groundHeight + gh[1],                    -3)));
+        }
+       }
+
+    for (auto &v : c) {
+        grassc.push_back(v.second.x);
+        grassc.push_back(v.second.y);
+        grassc.push_back(v.second.z);
+
+        grasst.push_back(v.first.x);
+        grasst.push_back(v.first.y);
+    }
+
+    Render::worldShader.use();
+       glUniform1f(Render::worldShader.uniform[WU_light_impact], 1.0f);
+
+    Render::worldShader.enable();
+
+    glVertexAttribPointer(Render::worldShader.coord, 3, GL_FLOAT, GL_FALSE, 0, &grassc[0]);
+    glVertexAttribPointer(Render::worldShader.tex, 2, GL_FLOAT, GL_FALSE, 0, &grasst[0]);
+    glDrawArrays(GL_TRIANGLES, 0 , c.size());
+
+    Render::worldShader.disable();
+       Render::worldShader.unuse();
+
+       player->draw();
+}
+
+void WorldSystem::setWorld(World *w)
+{
+       world = w;
+       
+       for (const auto &s : bgPaths[0])
+               bgFiles.push_back(w->styleFolder + s);
+       for (const auto &s : bgPaths[1])
+               bgFilesIndoors.push_back(w->styleFolder + s);
+
+       switch (w->bgType) {
+       case WorldBGType::Forest:
+               bgTex = TextureIterator(bgFiles);
+               break;
+       case WorldBGType::WoodHouse:
+               bgTex = TextureIterator(bgFilesIndoors);
+               break;
+    default:
+        UserError("Invalid world background type");
+        break;
+       }
+}
+
+
+void WorldSystem::receive(const BGMToggleEvent &bte)
+{
        if (bte.world == nullptr || bgmObjFile != bte.file) {
                Mix_FadeOutMusic(800);
 
index 28b7d55a4a8022777b71af77ae6d7d1feb688bc5..a03e0bf71af9427601d21a7444509e5f09ac3644 100644 (file)
@@ -4,11 +4,11 @@
     <generation type="Random" width="1600"/>
     <time>6000</time>
     <spawnx>-300</spawnx>
-    <npc name="Sanc" hasDialog="true" health="1" x="-136.30008" y="62.998978" dindex="9999"/>
-    <npc name="Bob" hasDialog="true" spawnx="30" health="1" x="748" y="63.398766" dindex="0"/>
-    <structure type="1" spawnx="300" alive="1"/>
-    <structure inside="bobshouse.xml" type="1" spawnx="10" alive="1"/>
-    <chest alive="1"/>
+    <npc name="Sanc" hasDialog="true"/>
+    <npc name="Bob" hasDialog="true" spawnx="30"/>
+    <structure type="1" spawnx="300"/>
+    <structure inside="bobshouse.xml" type="1" spawnx="10"/>
+    <chest/>
 </World>
 
 <Dialog name="Bob">