1
0
Fork 0
mirror of https://github.com/AquariaOSE/Aquaria.git synced 2024-11-25 17:53:47 +00:00

Merge branch 'experimental' into tile-optimization

This commit is contained in:
fgenesis 2023-12-21 14:20:22 +01:00
commit f641764765
12 changed files with 129 additions and 110 deletions

View file

@ -3109,6 +3109,10 @@ std::string DSQ::getUserInputString(std::string labelText, std::string t, bool a
doAlphabetInputKey(KEY_MINUS, '-', (char*)&map, &text, '_');
doAlphabetInputKey(KEY_TILDE, '~', (char*)&map, &text, '~');
doAlphabetInputKey(KEY_EQUALS, '=', (char*)&map, &text);
doAlphabetInputKey(KEY_LBRACKET, '(', (char*)&map, &text);
doAlphabetInputKey(KEY_RBRACKET, ')', (char*)&map, &text);
doAlphabetInputKey(KEY_SEMICOLON, ';', (char*)&map, &text);
}
if (getKeyState(KEY_BACKSPACE))

View file

@ -2447,7 +2447,7 @@ bool Entity::doCollisionAvoidance(float dt, int search, float mod, Vector *vp, f
Vector accum;
int c = 0;
bool isInWaterBubble = false;
if (waterBubble && isUnderWater())
if (isUnderWater() && waterBubble) // isUnderWater() may set waterBubble
{
//debugLog("collision avoidance in bubble");
isInWaterBubble = true;

View file

@ -230,6 +230,7 @@ Game::Game() : StateObject()
doScreenTrans = false;
noSceneTransitionFadeout = false;
fullTilesetReload = false;
highestLoadedEntityID = 0;
}
Game::~Game()
@ -908,7 +909,7 @@ EntitySaveData *Game::getEntitySaveDataForEntity(Entity *e)
int Game::findUnusedEntityID(bool temporary) const
{
const int inc = temporary ? -1 : 1;
int id = 0;
int id = temporary ? 0 : highestLoadedEntityID + 1; // never touch entity IDs that were in use in the map xml
retry:
id += inc;
FOR_ENTITIES(i)
@ -1228,7 +1229,7 @@ Path *Game::getWaterbubbleAt(const Vector& pos, float rad) const
UnderWaterResult Game::isUnderWater(const Vector& pos, float rad) const
{
UnderWaterResult ret { false, NULL };
UnderWaterResult ret = { false, NULL };
if (!game->useWaterLevel || game->waterLevel.x == 0
|| (useWaterLevel && waterLevel.x > 0 && pos.y-rad > waterLevel.x))
{
@ -1795,9 +1796,11 @@ next_SE:
void Game::spawnEntities(const EntitySaveData *sav, size_t n)
{
std::vector<size_t> conflicting, usable;
int highest = 0;
for(size_t i = 0; i < n; ++i)
{
const EntitySaveData& es = sav[i];
highest = std::max(es.id, highest);
// check for ID conflicts
int id = es.id;
@ -1820,6 +1823,8 @@ void Game::spawnEntities(const EntitySaveData *sav, size_t n)
conflicting.push_back(i);
}
highestLoadedEntityID = highest;
{
std::ostringstream os;
os << "Game::spawnEntities: Spawning " << usable.size() << " entities";
@ -1838,7 +1843,7 @@ void Game::spawnEntities(const EntitySaveData *sav, size_t n)
}
// spawn and renumber the rest
int lastid = 0;
int lastid = highest;
for(size_t i = 0; i < conflicting.size(); ++i)
{
// find an unused ID

View file

@ -90,6 +90,8 @@ class ObsRow
public:
inline ObsRow(unsigned tx, unsigned ty, unsigned len)
: tx(tx), ty(ty), len(len) {}
inline ObsRow(const ObsRow& o)
: tx(o.tx), ty(o.ty), len(o.len) {}
const unsigned tx, ty, len;
};
@ -412,6 +414,7 @@ public:
void onContinuityReset();
protected:
unsigned highestLoadedEntityID;
void toggleHelpScreen(bool on, const std::string &label="");
void onToggleHelpScreen();

View file

@ -970,17 +970,18 @@ void Core::resetTimer()
void Core::setMousePosition(const Vector &p)
{
float px = p.x + virtualOffX;
float py = p.y;
int ix, iy;
virtualCoordsToPixelPos(ix, iy, p);
SDL_Event ev = { sdlUserMouseEventID };
ev.motion.x = ix;
ev.motion.y = iy;
ev.motion.xrel = 0;
ev.motion.yrel = 0;
ev.motion.state = 0;
SDL_PushEvent(&ev);
window->warpMouse(
px * (float(width)/float(virtualWidth)),
py * (float(height)/float(virtualHeight))
);
window->warpMouse(ix, iy);
ev.motion.state = 1;
SDL_PushEvent(&ev);
@ -1247,12 +1248,12 @@ void Core::setMouseConstraintCircle(const Vector& pos, float circle)
int Core::getVirtualOffX()
int Core::getVirtualOffX() const
{
return virtualOffX;
}
int Core::getVirtualOffY()
int Core::getVirtualOffY() const
{
return virtualOffY;
}
@ -1279,12 +1280,39 @@ bool Core::doMouseConstraint()
return false;
}
Vector Core::pixelPosToVirtualCoords(int x, int y) const
{
const float mx = float(virtualWidth)/float(getWindowWidth());
const float my = float(virtualHeight)/float(getWindowHeight());
return Vector(
(x * mx) - getVirtualOffX(),
y * my
);
}
void Core::virtualCoordsToPixelPos(int& x, int& y, const Vector& p) const
{
const float px = p.x + getVirtualOffX();
const float py = p.y;
x = px * (float(getWindowWidth())/float(virtualWidth));
y = py * (float(getWindowHeight())/float(virtualHeight));
}
void Core::onEvent(const SDL_Event& event)
{
const bool focus = window->hasFocus();
if(event.type == sdlUserMouseEventID)
{
mouse._enableMotionEvents = event.motion.state;
mouse._enableMotionEvents = !!event.motion.state;
if(event.motion.state) // If 1, the generated mouse move is done and the rest is true mouse events
{
// We just set the position, so lets make sure that this mouse move isn't picked up
// as a relative change, ie. there was no actual user mouse move.
// There may be regular mouse move events after this one, which will be picked up normally.
mouse.lastPosition = pixelPosToVirtualCoords(event.motion.x, event.motion.y);
goto motion; // All the needed data are there, use this like a regular motion event
}
return;
}
@ -1324,17 +1352,16 @@ void Core::onEvent(const SDL_Event& event)
}
break;
// This event is also sent when SDL sets the mouse position!
// Since there's no way to distinguish the generated event from a true "user moved the mouse" event,
// sdlUserMouseEventID (above) is used to guard a generated motion event.
case SDL_MOUSEMOTION:
{
if (focus)
if (focus && mouse._enableMotionEvents)
{
const float mx = float(virtualWidth)/float(getWindowWidth());
const float my = float(virtualHeight)/float(getWindowHeight());
mouse.position.x = ((event.motion.x) * mx) - getVirtualOffX();
mouse.position.y = event.motion.y * my;
if(mouse._enableMotionEvents)
mouse._wasMoved = true;
motion:
mouse.position = pixelPosToVirtualCoords(event.motion.x, event.motion.y);
mouse._wasMoved = true;
}
}
break;
@ -1438,10 +1465,7 @@ void Core::pollEvents(float dt)
if(mouse._wasMoved)
{
if(doMouseConstraint())
{
setMousePosition(mouse.position);
window->handleInput();
}
mouse.change = mouse.position - mouse.lastPosition;
}

View file

@ -233,6 +233,8 @@ public:
// 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);
@ -383,8 +385,8 @@ public:
int getDisplayIndex();
int getRefreshRate();
int getVirtualOffX();
int getVirtualOffY();
int getVirtualOffX() const;
int getVirtualOffY() const;
void centerMouse();

View file

@ -90,7 +90,7 @@ void Precacher::doCache(ProgressCallback progress)
debugLog(os.str());
std::vector<Texture*> tmp(todo.size());
core->texmgr.loadBatch(&tmp[0], &todo[0], todo.size(), TextureMgr::KEEP,
progress ? texLoadProgressCallback : NULL, progress);
progress ? texLoadProgressCallback : NULL, (void*)progress);
todo.clear();
texkeep.reserve(texkeep.size() + tmp.size());
for(size_t i = 0; i < tmp.size(); ++i)

View file

@ -137,51 +137,16 @@ void Bone::createStrip(bool vert, int num)
}
Quad* Bone::addFrame(const std::string &gfx)
void Bone::addFrame(const std::string &gfx)
{
renderQuad = false;
Quad *q = new Quad();
q->setTexture(gfx);
q->renderBeforeParent = 1;
addChild(q, PM_POINTER);
return q;
framegfx.push_back(gfx);
}
void Bone::showFrame(int idx)
{
int c = 0;
for (Children::iterator i = children.begin(); i != children.end(); i++)
{
RenderObject *r = (*i);
if (idx == c)
{
if (r->alpha == 0)
{
r->alpha = 1;
// add option to turn on alpha fading
//r->alpha.interpolateTo(1, t);
}
else
{
r->alpha = 1;
}
}
else
{
if (r->alpha == 1)
{
r->alpha = 0;
//r->alpha.interpolateTo(0, t*2);
}
else
{
r->alpha = 0;
}
}
c++;
}
size_t i = idx;
if(i < framegfx.size())
setTexture(framegfx[i]);
}
@ -391,6 +356,11 @@ bool BoneCommand::parse(Bone *b, SimpleIStringStream &is)
}
else if(type == "AC_RESET_PASS")
command = AC_RESET_PASS;
else if(type == "AC_SET_FH")
{
command = AC_SET_FH;
is >> slot;
}
else // fail
{
std::ostringstream os;
@ -445,6 +415,19 @@ void BoneCommand::run()
case AC_RESET_PASS:
b->setRenderPass(b->originalRenderPass);
break;
case AC_SET_FH:
{
bool should = false;
switch(slot)
{
case 0: should = b->originalFH; break;
case 1: should = !b->originalFH; break;
case 2: should = true; break;
default: should = false; break;
}
b->fhTo(should);
break;
}
case AC_SEGS_START:
case AC_SEGS_STOP:
break;
@ -605,7 +588,7 @@ void AnimationLayer::createTransitionAnimation(Animation& to, float time)
void AnimationLayer::stopAnimation()
{
if(s->loaded && getCurrentAnimation()->resetPassOnEnd)
if(s->loaded && getCurrentAnimation()->resetOnEnd)
resetPass();
animating = false;
if (!enqueuedAnimation.empty())
@ -627,7 +610,7 @@ float AnimationLayer::getAnimationLength()
}
Animation::Animation()
: resetPassOnEnd(false)
: resetOnEnd(true)
{
}
@ -980,7 +963,7 @@ bool SkeletalSprite::saveSkeletal(const std::string &fn)
bone->SetAttribute("gfx", this->bones[i]->gfx.c_str());
bone->SetAttribute("pidx", this->bones[i]->pidx);
bone->SetAttribute("name", this->bones[i]->name.c_str());
bone->SetAttribute("fh", this->bones[i]->isfh());
bone->SetAttribute("fh", this->bones[i]->originalFH);
bone->SetAttribute("fv", this->bones[i]->isfv());
bone->SetAttribute("gc", this->bones[i]->generateCollisionMask);
bone->SetAttribute("cr", this->bones[i]->collideRadius);
@ -1039,21 +1022,11 @@ bool SkeletalSprite::saveSkeletal(const std::string &fn)
}
for (Children::iterator j = this->bones[i]->children.begin(); j != this->bones[i]->children.end(); j++)
for(size_t j = 0; j < this->bones[i]->framegfx.size(); ++j)
{
Bone *b = dynamic_cast<Bone*>(*j);
Quad *q = dynamic_cast<Quad*>(*j);
Particle *p = dynamic_cast<Particle*>(*j);
if (q && !b && !p)
{
XMLElement *frame = xml->NewElement("Frame");
frame->SetAttribute("gfx", q->texture->name.c_str());
if (q->getRenderPass() != 0)
{
frame->SetAttribute("pass", q->getRenderPass());
}
bone->InsertEndChild(frame);
}
XMLElement *frame = xml->NewElement("Frame");
frame->SetAttribute("gfx", this->bones[i]->framegfx[j].c_str());
bone->InsertEndChild(frame);
}
bones->InsertEndChild(bone);
}
@ -1065,8 +1038,8 @@ bool SkeletalSprite::saveSkeletal(const std::string &fn)
Animation *a = &this->animations[i];
XMLElement *animation = xml->NewElement("Animation");
animation->SetAttribute("name", a->name.c_str());
if(a->resetPassOnEnd)
animation->SetAttribute("resetPassOnEnd", a->resetPassOnEnd);
if(!a->resetOnEnd)
animation->SetAttribute("resetOnEnd", a->resetOnEnd);
for (size_t j = 0; j < a->interpolators.size(); ++j)
{
@ -1206,6 +1179,7 @@ Bone *SkeletalSprite::initBone(int idx, std::string gfx, int pidx, bool rbp, std
b->pidx = pidx;
b->collideRadius = cr;
b->name = name;
b->originalFH = fh;
if (fh)
b->flipHorizontal();
@ -1492,19 +1466,11 @@ void SkeletalSprite::loadSkeletal(const std::string &fn)
int frc=0;
while(fr)
{
Quad *q=0;
std::string gfx;
if (fr->Attribute("gfx"))
{
gfx = fr->Attribute("gfx");
q = newb->addFrame(gfx);
}
if (fr->Attribute("pass"))
{
if (q)
{
q->setRenderPass(atoi(fr->Attribute("pass")));
}
newb->addFrame(gfx);
}
fr = fr->NextSiblingElement("Frame");
frc++;
@ -1698,7 +1664,8 @@ void SkeletalSprite::loadSkeletal(const std::string &fn)
{
Animation newAnimation;
newAnimation.name = animation->Attribute("name");
newAnimation.resetPassOnEnd = animation->BoolAttribute("resetPassOnEnd");
if(animation->Attribute("resetOnEnd"))
newAnimation.resetOnEnd = animation->BoolAttribute("resetOnEnd");
stringToLower(newAnimation.name);
XMLElement *key = animation->FirstChildElement("Key");
@ -1952,7 +1919,10 @@ void AnimationLayer::resetPass()
{
Bone *b = s->bones[i];
if (contains(b))
{
b->setRenderPass(b->originalRenderPass);
b->fhTo(b->originalFH);
}
}
}

View file

@ -37,7 +37,8 @@ enum AnimationCommand
AC_SND_PLAY ,
AC_SEGS_STOP,
AC_SET_PASS,
AC_RESET_PASS
AC_RESET_PASS,
AC_SET_FH
};
class ParticleEffect;
@ -58,7 +59,7 @@ public:
ANIM_ALL = ANIM_POS | ANIM_ROT
};
void createStrip(bool vert, int num);
Quad* addFrame(const std::string &gfx);
void addFrame(const std::string &gfx);
void showFrame(int i);
void destroy() OVERRIDE;
std::string gfx;
@ -93,6 +94,7 @@ public:
bool fileRenderQuad;
bool selectable;
int originalRenderPass; // stores the render pass originally set in the XML file. For AC_RESET_PASS.
bool originalFH;
void spawnParticlesFromCollisionMask(const char *p, unsigned intv, int layer, float rotz = 0);
Vector getCollisionMaskNormal(Vector pos, float dist) const;
@ -107,6 +109,8 @@ public:
std::vector<Vector> collisionMask;
std::vector<Vector> transformedCollisionMask;
float collisionMaskRadius;
std::vector<std::string> framegfx;
};
class BoneCommand
@ -181,7 +185,7 @@ public:
size_t getSkeletalKeyframeIndex(SkeletalKeyframe *skey);
size_t getNumKeyframes();
void reverse();
bool resetPassOnEnd;
bool resetOnEnd;
BoneGridInterpolator *getBoneGridInterpolator(size_t boneIdx);
typedef std::vector <BoneGridInterpolator> Interpolators;

View file

@ -1,5 +1,6 @@
CMAKE_MINIMUM_REQUIRED(VERSION 2.6...3.20)
PROJECT(Aquaria)
SET(CMAKE_CXX_STANDARD 98)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/")
@ -56,6 +57,9 @@ OPTION(AQUARIA_USE_GLM "Use GLM for matrix math" TRUE)
OPTION(AQUARIA_DEBUG_SHOW_PATHS "Show important paths upon game start to aid in finding path problems" FALSE)
mark_as_advanced(AQUARIA_DEBUG_SHOW_PATHS)
#add_compile_options(-fsanitize=address)
#add_link_options(-fsanitize=address)
################ Look for external libraries
### Pick one: SDL 1.2 or SDL2
@ -137,14 +141,17 @@ ELSE(AQUARIA_DEMO_BUILD)
ADD_DEFINITIONS(-DAQUARIA_BUILD_SCENEEDITOR=1)
ENDIF(AQUARIA_DEMO_BUILD)
IF(CMAKE_BUILD_TYPE STREQUAL "Release")
ADD_DEFINITIONS(-DNDEBUG) # MSVC defines this in release mode by default, gcc/mingw do not
message(STATUS "This is a release build.")
ENDIF(CMAKE_BUILD_TYPE STREQUAL "Release")
IF(CMAKE_BUILD_TYPE STREQUAL "Debug")
ADD_DEFINITIONS(-D_DEBUG) # MSVC defines this in debug mode by default, gcc/mingw do not
message(STATUS "This is a debug build.")
ENDIF(CMAKE_BUILD_TYPE STREQUAL "Debug")
IF(NOT MSVC)
# MSVC defines these in release mode by default, gcc/mingw do not
IF(CMAKE_BUILD_TYPE STREQUAL "Release")
ADD_DEFINITIONS(-DNDEBUG)
message(STATUS "This is a release build.")
ENDIF(CMAKE_BUILD_TYPE STREQUAL "Release")
IF(CMAKE_BUILD_TYPE STREQUAL "Debug")
ADD_DEFINITIONS(-D_DEBUG)
message(STATUS "This is a debug build.")
ENDIF(CMAKE_BUILD_TYPE STREQUAL "Debug")
ENDIF(NOT MSVC)
# FIXME: These should go
IF(UNIX)

View file

@ -172,7 +172,7 @@ void DirBase::forEachDir(DirEnumCallback f, void *user /* = NULL */, bool safe /
DirBase *DirBase::getDirByName(const char *dn, bool /* unused: lazyLoad = true */, bool useSubtrees /* = true */)
{
if(!dn[0] || (dn[0] == '.' && !dn[1]))
if(!dn || !dn[0] || (dn[0] == '.' && !dn[1]))
return this;
Dirs::iterator it = _subdirs.find(dn);
@ -312,7 +312,7 @@ DirBase *Dir::getDirByName(const char *dn, bool lazyLoad /* = true */, bool useS
return NULL;
// Fix for absolute paths: No dir should have '/' (or any other absolute dirs) as subdir.
if(fullnameLen() && dn[0] == '/')
if(fullnameLen() && (dn && dn[0] == '/'))
return NULL;
// Lazy-load file if it's not in the tree yet

View file

@ -65,7 +65,7 @@ template <typename T> void SkipSelfPath(T *& s)
inline std::string joinPath(std::string base, const char *sub)
{
if(!*sub)
if(!sub || !*sub)
return base;
if(*sub != '/' && base.length() && base[base.length()-1] != '/')
base += '/';