From d7bae41fab5570bdac547a46463974adb4723f96 Mon Sep 17 00:00:00 2001 From: Clyne Sullivan Date: Mon, 25 Feb 2019 18:47:55 -0500 Subject: [PATCH] mem leak patches; world ground from image --- assets/testground.png | Bin 0 -> 6902 bytes include/systems/light.hpp | 5 + include/systems/movement.hpp | 22 ++++ include/texture.hpp | 15 +++ include/world.hpp | 7 +- src/systems/light.cpp | 28 +++-- src/systems/movement.cpp | 24 ++-- src/texture.cpp | 54 ++++++++ src/world.cpp | 235 ++++++----------------------------- xml/!town.xml | 18 +-- xml/bobshouse.xml | 18 +-- 11 files changed, 166 insertions(+), 260 deletions(-) create mode 100644 assets/testground.png diff --git a/assets/testground.png b/assets/testground.png new file mode 100644 index 0000000000000000000000000000000000000000..1d79cad9f7321c42aeafd3c80e2e4f6fc7096aa1 GIT binary patch literal 6902 zcmc(EXH-*N&~8FUs-V)FQlyJiK|rd6rqY`fkzR$+TLOqLHXuk3MF}Du4V?f16jTT; zARVG2CA82xe8;lx{d0fbyY5;kXYF&&%-%D5KQr@8;$7q04Cgq{fj}Szh@Q3y2t*kQ zTtB3t0)B6bSos5gR1XYpYlCP(#vmHl^Nn3#gw|irIuHbsy7K!A4lPm-1_r625F;Jx zpJW_tQp^8U`ENsv?pneb*+3vpdx*A% zS?I*-bX2vSOB8lv{r);+T}lumm_T!B@Q~Ax16h*$a@VDFgm~*^wqxvn?HNnYf=WkV z2_TmE%MZMQ3O-q)3RuWf7&w-pUpGI{*kg_Vx`0YnfUfuBm=PFmnzYm5ll zTbrq$MjxH@PC?ejrvum3+}5`?Rrlg`CK?=sw7>76Vy|Px z|Gh`)@_!UOT>V$|CzHgUE9tRsWo>v=+(q?F&bXArx8D{0nHJ^U#GYp`d91MGd!aX% zcFA*YmpQ9Qp4*9g{aS!d!*h4f>96Q;2O+68`Uc+6+@jZv+<+vmT6QxiRcO(?;ou)Z zs+BAmvy72orM{tLK}gu&*_Yfl{}DhNO6?ywtrbCQKq|rr5W=u;wvRadKR!r7ox1)L zek<+;J^|hXPa5VqGec^#fkkXQOD*rqv~nqpAd*q-|0dB?&XO_89NXAE&nR7X#7j6< zO7yM!I2`HRO!cGwb(k3ygI)9Lg0SwN5K-6uVuG&VVz6$LXNa8fu=>T z>Moi_=fCHnW{TK3%=v46B0}G;5|r=tv!snpWH3oW29nM9YvhXc^KuHap_r{l=uvV$ zP&C=ia~SacDsKeWEM+u^8^?3x61MZ138w0UIb{}r-6zZAoP0EJ5xlh*R>r(pl;Ijy zdIkIXJ5^ZTrD6A=m4Xa&z>!0+a5^W`@?L3J@s^gbBf9-QB%2G+C8Wu?MH4El8hM?> zNuVH%V83FQQi=-mWbjcGKz49?a!Sd#jB zlbG_Pd4J}g6I*%_g0)qXitf}?-v^1AJT{QPdl{CnBRGCYE8>TsjqewCg;Mb@uf~2e zhS0~XWy4IshP6@4qsueTM84%$r>m#1BRkF#nn+iT=X#M9huy>1EkD6(Ijb`pf5JlpK~P~*j}bMdoa8vyMX66%->Oh<_8eDGwM&h1 z-Siv8D>`BqR+w<1gJle3{)lDT&BH?h*#LDh-XMR(JKA*n9j1 z9ofb-Oy!gA*TgY92`h7t?sQW37q5;;S6{n8*lSLE^O^#geRP_iH5NATiUEO&=ABaX zV(SO18HB8#dPUoTyaQ_ya@9dGkH2Y5_lo=wY#L_4dvg#*$c8;KP(e0>_gO^-Z?}{h zEhB;qDK=!UV4pJH+3^q0TfdgF_FCF)|E-7SH_#|Z+I_PopOvgxu?w=DAGm{l@~tg= zV^AvUuJ4^$=oJz2JI^h;84pB+AlZd|izouojuAScS9TXXlNlV(g=`sSeoKL@A@pgmd{W+&Z)8Y28V%tOYbKZ%m?q!y(;<@9puq_+Az@dKY!sgu& z*4U4;LUR-4gO`)4$OB3SR);2_*G50vcbNRV1DH$Rz#wqSc;p(ktZ%uTrTXPOD@%3} zZN#f<-yK^`WMG+K z6k{rNKM5)JQL{^39tJe5VQOGZwe@*0TQ>xH7I~_6pN=%IM&lqn$2FC4I{59#^-u%C zP0~Yf0!xg)c`rjItdksAs6}&1e=yaGq1#N|=8RHe>q^?{v%WQDf^1FR$beX849p*W z#2A3)T%m?M_Q>IVu-Q8ug*|h;Yq>RhI{bST#Bvsr5MesERl)d8*x5;*=wm(KrT<1t z9fJnN2=}oG9$gP{Q#5wkdJF#V*f#gmEt6i+l%yL|oj(1>HF@$pIod;G;<%DJbXn@u z61FE7x(M#zDR9QG?>Sf6Lq5oIX7pc{XcK!Hg-vC6$;9gV=+p(Ntr+TZR2kR|uhx!u zdyuv++?&nuo=@=N+o*8rWWIs>01Q)0a7f;5HthseO;lCs!s=NqF4cM|e%IZ8tCSdQ z_0+S_{!or25})?p?WLQ)tY2I^*os&h6U}+JWnfdDkmD?*c`kwOZP<(k0Zo@X+gMD7 zS<+EwZOE)1?}c7Uvgpp+yrYAl`XC#AlcYsRCmc$9qUEm&(HKkjD&A`-uq5;m>sIqv3ggYo)fu2gp>Kj zG!%R>-WAP;Mm7PbL-u{+xRa(@=V7p94=#w(sd1$d`wWJMJ7oQ;O2c7JfJiwSmNxA4 zq|TgoR=|V?`nm{3>Fw;vPB33q zE_2aOK=UP?mOx*PTAL6}_ztRG-_38!`5`zlu||)*blO$YRiN?UFRzIc&W76H68y(<0{L#Ix}Tyu za7pXGVZ`?7P;8Bq+gQ-X=@n4u* z6goq=oRXf$B&9C4+8-2!t6^=|7n#pmexf$mV;T?V3d(M}!&2*uSJ}@G&Dn_W> zH7@ZLJ+tu0eQ*2wJ57AjDv`q2tTUBkXM-#3QWMfQp|9A$wzO#L&1@m}Ry0cn?w$yw z<;KL8hTBBv;2~o!7$=Su|^8ulk~IhF`5e*Qact z+K*i`dz{lwM>0%YRmn)or@*|$Wk?9mxgtL{XCi6};^rbtAAbsp`^8GrKDBgHH}l2* z1^>rfH{F?wP6~cuy=dDf%hgTuyGm0gVUpN5s_>$89}CJ*Rso~02;)g{Q>v02qAST2 zx&5%kf~-$u#bq0L>|80A{In_=Jk!)w7M+R^5MC%I-{*B&GE*z?2Q?s)6$|C2`(@ZA zAn3Kb_K=*COWE(YM2#k;zwSz9_9=99{nk?A^UXS5Rn5D~Y`Bh~=4d|cM2^}0RK-8H z)E~h)#w;@Ela4U+e#}Ht@EG`Zen_e2r>~>vi;(KR73w-*v)FyR45?5_!VO7ds2l2D zn65Yzb>+3PhS`^DB5ssEBo>Id&NEZ)_B>N$P~pvz{z{ZFk!qH?}V)ZX_@NW+euUHvvZT!y-GM6m-@pa#%}`1>6B*Xy;_V`5`Rkpy8k!)F zebD;xEjNjQtqYSCzk<4hi}NEU#V?l3%u-_bPwEoDGa8k9V(~`9#)eF)M zP6tQ9Gc`^}=bYxpSmRZQ%xjg>g&T(HOGu{3)I@8kKF^dn{u^^)wo~&4Rf(yKh3N&u zY0-mXn#O~HuAxsQ7OKi}%uu^x&5va0r*7%3e^bCqzAM;?dXab&BTr9a4B%;if61v* zyC5?7Op>FdZ9589uM-y%u8g(ro@3B|`|3Pvh?=am4K)qg##f&UcV+c7lFJf8$;qsE zJyj!sEb^-HWlK%H>2+$H!azTaNg!bQPnhQ-x~q3?o-}2wA=1R!ukjy~3Tw{N$O<;6~YSa}?4XD``bQgU=BTM%NG@s|n z`G7VDUuJE}%2^p*<&5jUZGY1 zkUrRE2;n*iF9Z2q?)_?e9gjDZ<@c4>$a!j0>RHzI|hcMFk#NrbKnlB`{!$*$E zl}7-PLRO~7g+|GPG3KL*CX9kw3-NZTW~6^8O4dI@F`A9~%h0Xe#Bbnyu(9t(%`x#U zId?T8Dy6j#RwZYZi`EU&FWjcp!fp|X zNsR-Z2c>ZjA!e4({XlBBkHnF?WJw^l<^YJSJCg(W*gd=0%_G+EJW8V~AFwaa$HM>y zf7{e2xEApp8FI|Dhj$wVMw(|1Io4(H!DyQC`^%9berRuYkBTZe~(&7E3j8UKOEmanxjJBkX+fy;T=xg6Rg(9fkaBUVA9%A7x1l(%^aX+caQ zFgk`c{SzF>Z;xwc5-!ivx-tb+F3kf5C*v|IbPa)Z3o<^jD5+f^&I(_fj^Uh%dh$tl z{@si!#eUdFY)y<8%@W%tS7=>tMZ~u}_oKjpw5*RU$?JBu_V{8Ug3OK22Q zd(TQ4D1+;0nwHB|2M79o{R{zDxoobDXvNAT=l9w z{5rF>PrTqS-O@Rx(ohh6>_+2y{`CfN21Ym1ZZ+}g2ANLdX}1G_eu-lW|BQpa7szOu84sr=+4BoiJW48VVHk|&6d4qk(11jZ6*ry_-IKTz*y|qT zJv<~~XlvExDbzfE03obQZ8(7LEVL@tSIVKo|KMGj^BGISwUB-CM=bZnNw)4mxU5jYNN?c+*_~fZ?3l&I z;A+i=*I}IgQmK{|a!un|03LTBQs+_86;7~_0pjEn_^)w!AU}{Z(B>*z1KAAqO^wWv zET;W6*Uc{PBe*2Co-4N}x<9t=u@Hfq;7NGQgW2W|3Cox-KP?Be-X%`yVDrgG=Na>X z^mJ5$$HSkUAQ@bE;?nV9U4*9bvkeX!miz@R_!boaVg!JP(e{JMWNyj#?RBvu<*Y;w z{eHJiV*loMzpm1xAd-tt%~vN2-FEk$HVqm z75aPZL)aV6@2gB|c(gC~02p`F_|l$Q?%a>)%f@dEBn3Q3?1WY4e-&N;q1LcB6Skx% z`6WjV|H&9mh3XuZxI5r$KfSW_9QzL8Juucb^V2{Mx>#&R)StHcvsgS6_&|=no;(Any8tw25C$-QlCYpC zc?0x{R@RaD%dJW7>m(ifzPXdK79K|u1AD<=V1H00NjrPmPv^6)<;8T41FTGJY;ie97Cn#llvov;)F~+@*8TRIk0Bb7EG5+@=3g1 z#OIg6sJhPA*3i&w9|}{l8Hy=|IQ$wJ=Sb50NE!-ka$n~3V#m2+-L=c8bq-O2Z5c=e zbZ>e?HQs2!7f62W)xjoC%ayTp$qNQ{bFr;Hf}T{GYOEOr*ovhf+WPYz zY+-0TU@zeyN;X(;nE#0{Z77F;n`2>?Wp}Yd7!Y+NqkFGb3mLzuNN*4nT_w+@wWCMk z7yNeSl@j~*o*G2m^8-ryNonVTpm9VD)@m z8r@{gwBl0NC*fs31)I8A5U*sgWsPfkQ}n$Hy-7v!9OA07%p0taTTb;cS3c}x|3#SKk!qNjmGTDPinIAq5R*iSlqObq0TtQO*~r{czM z9MDj~5m{{6!J^^AMk3Mlh8!LeJxdMO0oX()kR`b};lKO@4$<=p2a|f470u79;XTmZ zYx4W*Nc$&V09iBh2B4XTV9&n*#iHb^CMdKM%a+AGMQM6n&$9zm6<$O>B+=$qoYTDX zv?acVg*auBz2FOgsrBf_4b9Blh+G{JfScwZNd9J3nH3URpI5gr80OA>kT-r4l%9@q zO^_tpiB(FR$v6%1I80kdPBE5?j@c@wlyLQX?B=JkW+G$6oc({(dwn407I^Po#Of3-pKD!g;JDSv`TTw z&hl3AmMuYsg3Lx@s(X@a5l-~9H1(_|7XnEe#19b5uK|Bpn?n>HYJrD6fuq!T- zjUmQ1^z%~9fV>}ErtI8UvIN+KM;#Oy-iF)nl@gJ2mpyF$G4;eNLEsrok>PZv71|O! zqet^Ys#2vDg9|MG4WQ3Vh72>`X#D2!QKta~UpDw;WVFlz3pK|?1hc;{t8)Qt2N;;4 zYwy3#z=@0Oi@mB)xDMWYocBs6_BtcS`v28+c=!LW kMe+Zv_wj#MF!2ohYz|+TyQX^)Xh(q{I>y?SnvSvm1O9F;*Z=?k literal 0 HcmV?d00001 diff --git a/include/systems/light.hpp b/include/systems/light.hpp index ba91113..02c7eed 100644 --- a/include/systems/light.hpp +++ b/include/systems/light.hpp @@ -21,6 +21,11 @@ class LightSystem : public entityx::System { private: static std::vector lights; + static GLfloat *colorData; + static GLfloat *coordData; + + static void resizeLights(void); + public: void update(entityx::EntityManager& en, entityx::EventManager& ev, entityx::TimeDelta dt) override; diff --git a/include/systems/movement.hpp b/include/systems/movement.hpp index fd37665..745fa9b 100644 --- a/include/systems/movement.hpp +++ b/include/systems/movement.hpp @@ -2,10 +2,32 @@ #define SYSTEM_MOVEMENT_HPP_ #include +#include class MovementSystem : public entityx::System { +private: + constexpr static const char *hitPlayerScript = "\ + effect = function()\n \ + flash(255, 0, 0)\n \ + damage(1)\n \ + end\n \ + hit = function()\n \ + xrange = 5\n \ + end"; + static LuaScript hitPlayer; + static Attack playerAttack; + public: + MovementSystem(void) { + hitPlayer = LuaScript(hitPlayerScript); + AttackSystem::initLua(hitPlayer); + playerAttack = { vec2(), vec2(5, 5), vec2(), vec2(), + hitPlayer, TextureIterator() }; + } + void update(entityx::EntityManager &en, entityx::EventManager &ev, entityx::TimeDelta dt) override; + + static int doAttack(lua_State *); }; #endif // SYSTEM_MOVEMENT_HPP_ diff --git a/include/texture.hpp b/include/texture.hpp index d4bcfa9..db16357 100644 --- a/include/texture.hpp +++ b/include/texture.hpp @@ -174,4 +174,19 @@ public: */ void unloadTextures(void); +class ObjectTexture : public Texture { +private: + std::vector solidMap; + bool valid; + +public: + ObjectTexture(const std::string filename = ""); + + int getHeight(int index); + bool isInsideObject(vec2 coord) const; + inline bool isValid(void) { + return valid; + } +}; + #endif //TEXTURE_HPP_ diff --git a/include/world.hpp b/include/world.hpp index 0bfe078..d53a40b 100644 --- a/include/world.hpp +++ b/include/world.hpp @@ -69,7 +69,7 @@ constexpr const unsigned int INDOOR_FLOOR_HEIGHT = (INDOOR_FLOOR_HEIGHTT + INDOO struct WorldData2 { // Data variables - std::vector data; /**< The world's ground data. */ + ObjectTexture ground; float startX; /**< The furthest left coordinate of the world. */ // Indoor variables @@ -125,8 +125,6 @@ private: static std::vector stars; - static int getLineIndex(float x); - public: static std::thread thAmbient; @@ -159,7 +157,8 @@ public: static void goWorldRight(Position& p, Solid &d); static void goWorldPortal(Position& p); - static void generate(LuaScript& script); + static void generate(const char *file); + static float getGroundHeight(float x); static bool save(void); static void load(const std::string& file); diff --git a/src/systems/light.cpp b/src/systems/light.cpp index 51a6702..b7c62aa 100644 --- a/src/systems/light.cpp +++ b/src/systems/light.cpp @@ -6,6 +6,17 @@ std::vector LightSystem::lights; +GLfloat *LightSystem::colorData = nullptr; +GLfloat *LightSystem::coordData = nullptr; + +void LightSystem::resizeLights(void) +{ + delete colorData; + delete coordData; + colorData = new GLfloat[lights.size() * 4]; + coordData = new GLfloat[lights.size() * 4]; +} + void LightSystem::update(entityx::EntityManager& en, entityx::EventManager& ev, entityx::TimeDelta dt) { (void)ev; (void)dt; @@ -20,23 +31,20 @@ void LightSystem::update(entityx::EntityManager& en, entityx::EventManager& ev, } void LightSystem::render(void) { - auto coords = new GLfloat[lights.size() * 4]; - auto colors = new GLfloat[lights.size() * 4]; - unsigned int offset = 0; for (const auto& l : lights) { - coords[offset] = l.pos.x, coords[offset + 1] = l.pos.y, - coords[offset + 2] = -5, coords[offset + 3] = l.radius; - colors[offset] = l.color.red, colors[offset + 1] = l.color.green, - colors[offset + 2] = l.color.blue, colors[offset + 3] = 1.0f; + coordData[offset] = l.pos.x, coordData[offset + 1] = l.pos.y, + coordData[offset + 2] = -5, coordData[offset + 3] = l.radius; + colorData[offset] = l.color.red, colorData[offset + 1] = l.color.green, + colorData[offset + 2] = l.color.blue, colorData[offset + 3] = 1.0f; offset += 4; } Render::worldShader.use(); Render::worldShader.enable(); - glUniform4fv(Render::worldShader.uniform[WU_light], lights.size(), coords); - glUniform4fv(Render::worldShader.uniform[WU_light_color], lights.size(), colors); + glUniform4fv(Render::worldShader.uniform[WU_light], lights.size(), coordData); + glUniform4fv(Render::worldShader.uniform[WU_light_color], lights.size(), colorData); glUniform1i(Render::worldShader.uniform[WU_light_size], lights.size()); Render::worldShader.disable(); @@ -45,6 +53,7 @@ void LightSystem::render(void) { int LightSystem::addLight(vec2 pos, float radius, Color color) { lights.emplace_back(pos, radius, color); + resizeLights(); return lights.size() - 1; } @@ -56,5 +65,6 @@ void LightSystem::updateLight(int index, vec2 pos, float radius) { void LightSystem::removeLight(int index) { lights.erase(lights.begin() + index); + resizeLights(); } diff --git a/src/systems/movement.cpp b/src/systems/movement.cpp index 642fa6a..b2c95c5 100644 --- a/src/systems/movement.cpp +++ b/src/systems/movement.cpp @@ -10,11 +10,21 @@ #include -#include #include #include #include +LuaScript MovementSystem::hitPlayer; +Attack MovementSystem::playerAttack; + +int MovementSystem::doAttack(lua_State* s) +{ + vec2 pos (lua_tonumber(s, 1), lua_tonumber(s, 2)); + game::events.emit(AttackEvent(pos, + playerAttack, false)); + return 0; +} + void MovementSystem::update(entityx::EntityManager &en, entityx::EventManager &ev, entityx::TimeDelta dt) { //bool fight = false; @@ -72,18 +82,6 @@ void MovementSystem::update(entityx::EntityManager &en, entityx::EventManager &e } } - static auto doAttack = [](lua_State* s) -> int { - vec2 pos (lua_tonumber(s, 1), lua_tonumber(s, 2)); - LuaScript script ("effect = function()\nflash(255,0,0)\ndamage(1)\nend\n\ - hit = function()\nxrange = 5\nend"); - AttackSystem::initLua(script); - Attack attack = {vec2(), vec2(5, 5), vec2(), vec2(), - script, TextureIterator()}; - game::events.emit(AttackEvent(pos, - attack, false)); - return 0; - }; - // make the entity wander // TODO initialX and range? if (entity.has_component()) { diff --git a/src/texture.cpp b/src/texture.cpp index 19aae3f..422f013 100644 --- a/src/texture.cpp +++ b/src/texture.cpp @@ -11,6 +11,60 @@ #include #include +ObjectTexture::ObjectTexture(const std::string filename) +{ + valid = !filename.empty(); + if (!valid) + return; + + auto image = IMG_Load(filename.c_str()); + + // format: RGBA8 + solidMap.resize(image->w * image->h); + auto rgba = ((uint8_t *)image->pixels) + 3; + auto iter = solidMap.begin(); + for (int i = 0; i < image->w * image->h; i++) { + *iter++ = *rgba > 0; + rgba += 4; + } + + GLuint object; + glGenTextures(1, &object); // Turns "object" into a texture + glBindTexture(GL_TEXTURE_2D, object); // Binds "object" to the top of the stack + glPixelStoref(GL_UNPACK_ALIGNMENT, 1); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // Sets the "min" filter + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // The the "max" filter of the stack + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); // Wrap the texture to the matrix + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image->w, image->h, 0, + GL_RGBA, GL_UNSIGNED_BYTE, image->pixels); + + name = filename; + tex = object; + dim = vec2 {(float)image->w, (float)image->h}; + + // free the SDL_Surface + SDL_FreeSurface(image); +} + +int ObjectTexture::getHeight(int index) +{ + if (index < 0 || index > dim.x) + return 100; + + unsigned int h; + for (h = 0; h < dim.y; h++) { + if (solidMap[h * dim.x + index]) + return dim.y - h; + } + return 0; +} + +bool ObjectTexture::isInsideObject(vec2 coord) const { + coord /= 2; + return solidMap[(int)coord.y * (int)dim.x + (int)coord.x]; +} + namespace Colors { ColorTex white; diff --git a/src/world.cpp b/src/world.cpp index 0cfa725..a608384 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -54,45 +54,30 @@ WorldSystem::~WorldSystem(void) { } -int WorldSystem::getLineIndex(float x) +void WorldSystem::generate(const char *file) { - return std::clamp(static_cast((x - world.startX) / game::HLINE), - 0, static_cast(world.data.size())); -} - -void WorldSystem::generate(LuaScript& script) -{ - int i = 0; - world.data.clear(); - do { - float h, g[2]; - script("ground", {LuaVariable("height", h)}); - if (h == -1.0f) - break; - if (h > 5000) - h = 5000; - script("grass", {LuaVariable("height", g[0])}); - script("grass", {LuaVariable("height", g[1])}); - world.data.push_back(WorldData {true, {g[0], g[1]}, h, - static_cast(randGet() % 32 / 8)}); - } while (++i); - - // define x-coordinate of world's leftmost 'line' - world.startX = HLINES(i * -0.5); + world.ground = ObjectTexture(file); + auto width = world.ground.getDim().x; + world.startX = width / -2; // gen. star coordinates if (stars.empty()) { stars.resize(game::SCREEN_WIDTH / 30); for (auto& s : stars) { - s.x = world.startX + (randGet() % (int)HLINES(i)); + s.x = world.startX + (randGet() % (int)width); s.y = game::SCREEN_HEIGHT - (randGet() % (int)HLINES(game::SCREEN_HEIGHT / 1.3f)); } } } +float WorldSystem::getGroundHeight(float x) +{ + return world.ground.getHeight((int)(x - world.startX)); +} + float WorldSystem::isAboveGround(const vec2& p) { - const auto& gh = world.data[getLineIndex(p.x)].groundHeight; + auto gh = getGroundHeight(p.x); return p.y >= gh ? 0 : gh; } @@ -255,8 +240,7 @@ void WorldSystem::loader(void) // world generation else if (tagName == "generation") { - LuaScript script (wxml->GetText()); - generate(script); + generate(wxml->GetText()); } // indoor stuff @@ -421,10 +405,8 @@ void WorldSystem::render(void) const vector2 backgroundOffset (static_cast(SCREEN_WIDTH) / 2, static_cast(SCREEN_HEIGHT) / 2); - int iStart, iEnd, pOffset; - // world width in pixels - int width = HLINES(world.data.size()); + int width = world.ground.getDim().x; static std::once_flag init; std::call_once(init, [&](void) { @@ -557,176 +539,30 @@ void WorldSystem::render(void) delete[] bgItems; } + vec2 dim; if (world.indoor) { world.indoorTex.use(); - auto dim = world.indoorTex.getDim() * game::HLINE; - GLfloat verts[] = { - world.startX, 0, z, 0, 0, - world.startX + dim.x, 0, z, 1, 0, - world.startX + dim.x, dim.y, z, 1, 1, - world.startX + dim.x, dim.y, z, 1, 1, - world.startX, dim.y, z, 0, 1, - world.startX, 0, z, 0, 0, - }; - - glVertexAttribPointer(Render::worldShader.coord, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), verts); - glVertexAttribPointer(Render::worldShader.tex , 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), verts + 3); - glDrawArrays(GL_TRIANGLES, 0, 6); - } - - //glUniform1f(Render::worldShader.uniform[WU_light_impact], 0.075f + (0.2f * i)); - //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 - world.startX) / game::HLINE; - - // only draw world within player vision - iStart = std::clamp(static_cast(pOffset - (SCREEN_WIDTH / 2 / game::HLINE)), - 0, static_cast(world.data.size())); - iEnd = std::clamp(static_cast(pOffset + (SCREEN_WIDTH / 2 / game::HLINE) + 2), - 0, static_cast(world.data.size())); - - // draw the dirt - waitToSwap = true; - - bgTex++; - z = Render::ZRange::Ground; - - static std::vector dirt; - if (dirt.size() != world.data.size() * 30) { - dirt.clear(); - dirt.resize(world.data.size() * 30); - } - - GLfloat *dirtp = &dirt[0]; - for (int i = iStart; i < iEnd; i++) { - int ty = world.data[i].groundHeight / 64 + world.data[i].groundColor; - GLfloat five[5] = { - 0, 0, world.startX + HLINES(i), world.data[i].groundHeight, z - 0.1f - }; - - push5(dirtp, five); - five[0]++, five[2] += game::HLINE; - push5(dirtp, five); - five[1] += ty, five[3] = 0; - push5(dirtp, five); - push5(dirtp, five); - five[0]--, five[2] -= game::HLINE; - push5(dirtp, five); - five[1] = 0, five[3] = world.data[i].groundHeight; - push5(dirtp, five); - } - - glUniform1f(Render::worldShader.uniform[WU_light_impact], 0.45f); - - glVertexAttribPointer(Render::worldShader.coord, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), &dirt[2]); - glVertexAttribPointer(Render::worldShader.tex, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), &dirt[0]); - glDrawArrays(GL_TRIANGLES, 0 , dirt.size() / 5); - - Render::worldShader.disable(); - Render::worldShader.unuse(); - - bgTex++; - - static std::vector grass; - if (grass.size() != world.data.size() * 60) { - grass.clear(); - grass.resize(world.data.size() * 60); - } - - GLfloat *grassp = &grass[0]; - for (int i = iStart; i < iEnd; i++) { - auto wd = world.data[i]; - auto gh = wd.grassHeight; - - // flatten the grass if the player is standing on it. - if (!world.indoor && !wd.grassUnpressed) { - gh[0] /= 4; - gh[1] /= 4; - } - - // actually draw the grass. - if (wd.groundHeight) { - float five[5] = { - 0, 1, world.startX + HLINES(i), wd.groundHeight + gh[0], z - 0.2f - }; - - push5(grassp, five); - five[0]++, five[1]--, five[2] += HLINES(0.5f); - push5(grassp, five); - five[1]++, five[3] = wd.groundHeight; - push5(grassp, five); - push5(grassp, five); - five[0]--, five[2] -= HLINES(0.5f); - push5(grassp, five); - five[1]--, five[3] = wd.groundHeight + gh[0]; - push5(grassp, five); - five[1]++; - - five[2] = world.startX + HLINES(i + 0.5), five[3] = wd.groundHeight + gh[1]; - - push5(grassp, five); - five[0]++, five[1]--, five[2] += HLINES(0.5f) + 1; - push5(grassp, five); - five[1]++, five[3] = wd.groundHeight; - push5(grassp, five); - push5(grassp, five); - five[0]--, five[2] -= HLINES(0.5f) + 1; - push5(grassp, five); - five[1]--, five[3] = wd.groundHeight + gh[1]; - push5(grassp, five); - } + dim = world.indoorTex.getDim(); + } else { + world.ground.use(); + dim = world.ground.getDim(); } - Render::worldShader.use(); - glUniform1f(Render::worldShader.uniform[WU_light_impact], 1.0f); - - Render::worldShader.enable(); - - glVertexAttribPointer(Render::worldShader.coord, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), &grass[2]); - glVertexAttribPointer(Render::worldShader.tex, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), &grass[0]); - glDrawArrays(GL_TRIANGLES, 0 , grass.size() / 5); - - // the starting pixel of the world - static const float s = -(static_cast(SCREEN_WIDTH) / 2.0f); - // the ending pixel of the world - static const float e = static_cast(SCREEN_WIDTH) / 2.0f; - static const float sheight = static_cast(SCREEN_HEIGHT); - - auto yOffset = offset.y - static_cast(SCREEN_HEIGHT) / 2.0f; - GLfloat blackBar[] = { - s, yOffset, z - 0.3f, 0.0f, 0.0f, - world.startX, yOffset, z - 0.3f, 1.0f, 0.0f, - world.startX, yOffset + sheight, z - 0.3f, 1.0f, 1.0f, - world.startX, yOffset + sheight, z - 0.3f, 1.0f, 1.0f, - s, yOffset + sheight, z - 0.3f, 0.0f, 1.0f, - s, yOffset, z - 0.3f, 0.0f, 0.0f + GLfloat verts[] = { + world.startX, 0, z, 0, 0, + world.startX + dim.x, 0, z, 1, 0, + world.startX + dim.x, dim.y, z, 1, 1, + world.startX + dim.x, dim.y, z, 1, 1, + world.startX, dim.y, z, 0, 1, + world.startX, 0, z, 0, 0, }; - if (offset.x + world.startX > s) { - Colors::black.use(); - glUniform1f(Render::worldShader.uniform[WU_light_impact], 0.0f); - glVertexAttribPointer(Render::worldShader.coord, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 5, blackBar); - glVertexAttribPointer(Render::worldShader.tex, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 5, blackBar + 3); - glDrawArrays(GL_TRIANGLES, 0, 6); - } - - if (offset.x - world.startX < e) { - blackBar[0] = blackBar[20] = blackBar[25] = -world.startX; - blackBar[5] = blackBar[10] = blackBar[15] = e; - - Colors::black.use(); - glUniform1f(Render::worldShader.uniform[WU_light_impact], 0.0f); - glVertexAttribPointer(Render::worldShader.coord, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 5, blackBar); - glVertexAttribPointer(Render::worldShader.tex, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 5, blackBar + 3); - glDrawArrays(GL_TRIANGLES, 0, 6); - } + glVertexAttribPointer(Render::worldShader.coord, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), verts); + glVertexAttribPointer(Render::worldShader.tex , 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), verts + 3); + glDrawArrays(GL_TRIANGLES, 0, 6); Render::worldShader.disable(); Render::worldShader.unuse(); - - waitToSwap = false; } bool WorldSystem::receive(const BGMToggleEvent &bte) @@ -781,7 +617,7 @@ void WorldSystem::detect(entityx::TimeDelta dt) (void)e; if (!g.grounded) { // make sure entity is above ground - auto height = world.data[getLineIndex(loc.x + dim.width / 2)].groundHeight; + auto height = getGroundHeight(loc.x + dim.width / 2); if (loc.y != height) { loc.y = height; e.remove(); @@ -800,25 +636,24 @@ void WorldSystem::detect(entityx::TimeDelta dt) game::entities.each( [&](entityx::Entity e, Position &loc, Direction &vel, Solid &dim) { (void)e; - // get the line the entity is on - auto line = getLineIndex(loc.x + dim.width / 2); // make sure entity is above ground - if (loc.y < world.data[line].groundHeight) { - int dir = vel.x < 0 ? -1 : 1; + auto height = getGroundHeight(loc.x + dim.width / 2); + if (loc.y < height) { + /*int dir = vel.x < 0 ? -1 : 1; auto near = std::clamp(line + dir * 2, 0, static_cast(world.data.size())); if (world.data[near].groundHeight - 30 > world.data[line + dir].groundHeight) { loc.x -= (PLAYER_SPEED_CONSTANT + 2.7f) * dir * 2; vel.x = 0; - } else { - loc.y = world.data[line].groundHeight - 0.001f * dt; + } else {*/ + loc.y = height - 0.001f * dt; vel.y = 0; if (!vel.grounded) { vel.grounded = true; ParticleSystem::addMultiple(20, ParticleType::SmallPoof, [&](){ return vec2(loc.x + randGet() % static_cast(dim.width), loc.y); }, 500, 30); } - } + //} } diff --git a/xml/!town.xml b/xml/!town.xml index b2d96a5..1b1d527 100644 --- a/xml/!town.xml +++ b/xml/!town.xml @@ -12,22 +12,7 @@ - - x = 0 - - ground = function() - if (x == 320) then - height = -1 - else - height = 1 / math.pow(2, (x - 50) / 2) + 60 - end - x = x + 1 - end - - grass = function() - height = math.random(2, 7) - end - + assets/testground.png Sunny -300 @@ -37,7 +22,6 @@ - diff --git a/xml/bobshouse.xml b/xml/bobshouse.xml index 9160ef0..384af4f 100644 --- a/xml/bobshouse.xml +++ b/xml/bobshouse.xml @@ -13,23 +13,7 @@ - - x = 0 - - ground = function() - if (x == 320) then - height = -1 - else - height = 60 - end - - x = x + 1 - end - - grass = function() - height = 2 - end - + testground.png -- 2.39.5