optimalizing engine for OAM, remove needles pointer dereferences in every update
This commit is contained in:
parent
a4fb01b87a
commit
573f1623e2
|
@ -36,6 +36,7 @@ std::vector<Sprite *> FoodScene::sprites() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void FoodScene::removeBulletsOffScreen() {
|
void FoodScene::removeBulletsOffScreen() {
|
||||||
|
// TODO this is VERY ineffective, but it's a nice example of how C++11 remove_if works.
|
||||||
bullets.erase(
|
bullets.erase(
|
||||||
std::remove_if(bullets.begin(), bullets.end(), [](std::unique_ptr<Bullet> &s) { return s->isOffScreen(); }),
|
std::remove_if(bullets.begin(), bullets.end(), [](std::unique_ptr<Bullet> &s) { return s->isOffScreen(); }),
|
||||||
bullets.end());
|
bullets.end());
|
||||||
|
@ -55,6 +56,7 @@ void FoodScene::tick(u16 keys) {
|
||||||
TextStream::instance().setText(std::to_string(counter) + std::string(" frames/5sec"), 5, 1);
|
TextStream::instance().setText(std::to_string(counter) + std::string(" frames/5sec"), 5, 1);
|
||||||
TextStream::instance().setText(std::string(engine->getTimer()->to_string()), 6, 1);
|
TextStream::instance().setText(std::string(engine->getTimer()->to_string()), 6, 1);
|
||||||
|
|
||||||
|
|
||||||
avatar->animateToFrame(0);
|
avatar->animateToFrame(0);
|
||||||
bool allowedToShoot = false;
|
bool allowedToShoot = false;
|
||||||
int oldBulletSize = bullets.size();
|
int oldBulletSize = bullets.size();
|
||||||
|
@ -66,11 +68,6 @@ void FoodScene::tick(u16 keys) {
|
||||||
}
|
}
|
||||||
|
|
||||||
removeBulletsOffScreen();
|
removeBulletsOffScreen();
|
||||||
TextStream::instance().setText(std::string("bullets: ") + std::to_string(bullets.size()), 1, 1);
|
|
||||||
TextStream::instance().setText(std::string("cooldown: ") + std::to_string(bulletCooldown), 2, 1);
|
|
||||||
|
|
||||||
TextStream::instance().setText(std::string("angle pa/pb: ") + std::to_string(avatar->getMatrix()->pa) + std::string("/") + std::to_string(avatar->getMatrix()->pb), 3, 1);
|
|
||||||
TextStream::instance().setText(std::string("angle pc/pd: ") + std::to_string(avatar->getMatrix()->pc) + std::string("/") + std::to_string(avatar->getMatrix()->pd), 4, 1);
|
|
||||||
|
|
||||||
if(keys & KEY_LEFT) {
|
if(keys & KEY_LEFT) {
|
||||||
avatarRotation -= AVATAR_ROTATION_DIFF;
|
avatarRotation -= AVATAR_ROTATION_DIFF;
|
||||||
|
@ -92,6 +89,7 @@ void FoodScene::tick(u16 keys) {
|
||||||
}
|
}
|
||||||
|
|
||||||
avatar->rotate(avatarRotation);
|
avatar->rotate(avatarRotation);
|
||||||
|
|
||||||
if(oldBulletSize != bullets.size()) {
|
if(oldBulletSize != bullets.size()) {
|
||||||
engine.get()->updateSpritesInScene();
|
engine.get()->updateSpritesInScene();
|
||||||
}
|
}
|
||||||
|
@ -132,18 +130,5 @@ void FoodScene::load() {
|
||||||
// rotation of a point on a circle within the resolution means our radius should be big enough
|
// rotation of a point on a circle within the resolution means our radius should be big enough
|
||||||
defaultBulletTarget = { GBA_SCREEN_WIDTH / 2, GBA_SCREEN_HEIGHT + (GBA_SCREEN_WIDTH / 2) - avatar->getCenter().y + 40};
|
defaultBulletTarget = { GBA_SCREEN_WIDTH / 2, GBA_SCREEN_HEIGHT + (GBA_SCREEN_WIDTH / 2) - avatar->getCenter().y + 40};
|
||||||
|
|
||||||
/*
|
|
||||||
for(int i = 0; i < 10; i++) {
|
|
||||||
for(int j = 0; j < 4; j++) {
|
|
||||||
bullets.push_back(createBullet());
|
|
||||||
|
|
||||||
auto &b = bullets.at(bullets.size() - 1);
|
|
||||||
b->getSprite()->moveTo(10 + (i * 20), 10 + (j * 20));
|
|
||||||
if(j >= 1) {
|
|
||||||
b->getSprite()->moveTo(10 + (i * 20), 100 + (j * 20));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
engine->getTimer()->start();
|
engine->getTimer()->start();
|
||||||
}
|
}
|
|
@ -58,10 +58,9 @@ protected:
|
||||||
bool stayWithinBounds;
|
bool stayWithinBounds;
|
||||||
u32 imageSize, tileIndex;
|
u32 imageSize, tileIndex;
|
||||||
SpriteSize spriteSize;
|
SpriteSize spriteSize;
|
||||||
u32 animationDelay, numberOfFrames, beginFrame, currentFrame, animationCounter;
|
u8 animationDelay, numberOfFrames, beginFrame, currentFrame, previousFrame, animationCounter;
|
||||||
bool animating;
|
bool animating;
|
||||||
|
OBJ_ATTR oam;
|
||||||
std::unique_ptr<OBJ_ATTR> oam;
|
|
||||||
|
|
||||||
void syncAnimation();
|
void syncAnimation();
|
||||||
virtual void syncOam();
|
virtual void syncOam();
|
||||||
|
|
|
@ -38,7 +38,7 @@ void AffineSprite::setTransformationMatrix(OBJ_AFFINE *matrix) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void AffineSprite::rebuildOamAttr1ForAffineIndex() {
|
void AffineSprite::rebuildOamAttr1ForAffineIndex() {
|
||||||
this->oam->attr1 = this->x |
|
oam.attr1 = this->x |
|
||||||
ATTR1_AFF_ID(affIndex) |
|
ATTR1_AFF_ID(affIndex) |
|
||||||
(HORIZONTAL_FLIP_FLAG << 12) |
|
(HORIZONTAL_FLIP_FLAG << 12) |
|
||||||
(VERTICAL_FLIP_FLAG << 13) |
|
(VERTICAL_FLIP_FLAG << 13) |
|
||||||
|
@ -47,7 +47,7 @@ void AffineSprite::rebuildOamAttr1ForAffineIndex() {
|
||||||
|
|
||||||
void AffineSprite::buildOam(int tileIndex) {
|
void AffineSprite::buildOam(int tileIndex) {
|
||||||
Sprite::buildOam(tileIndex);
|
Sprite::buildOam(tileIndex);
|
||||||
this->oam->attr0 = ATTR0_Y(this->y) |
|
oam.attr0 = ATTR0_Y(this->y) |
|
||||||
ATTR0_MODE(1) |
|
ATTR0_MODE(1) |
|
||||||
(GFX_MODE << 10) |
|
(GFX_MODE << 10) |
|
||||||
(MOSAIC_MODE << 12) |
|
(MOSAIC_MODE << 12) |
|
||||||
|
|
|
@ -29,9 +29,7 @@ void Sprite::moveTo(VECTOR location) {
|
||||||
void Sprite::moveTo(int x, int y) {
|
void Sprite::moveTo(int x, int y) {
|
||||||
this->x = x;
|
this->x = x;
|
||||||
this->y = y;
|
this->y = y;
|
||||||
if(oam) {
|
syncOam();
|
||||||
syncOam();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Sprite::isOffScreen() {
|
bool Sprite::isOffScreen() {
|
||||||
|
@ -40,25 +38,20 @@ bool Sprite::isOffScreen() {
|
||||||
|
|
||||||
void Sprite::flipHorizontally(bool flip) {
|
void Sprite::flipHorizontally(bool flip) {
|
||||||
if(flip) {
|
if(flip) {
|
||||||
oam->attr1 |= ATTR1_HFLIP;
|
oam.attr1 |= ATTR1_HFLIP;
|
||||||
} else {
|
} else {
|
||||||
oam->attr1 &= FLIP_HORIZONTAL_CLEAR;
|
oam.attr1 &= FLIP_HORIZONTAL_CLEAR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sprite::flipVertically(bool flip) {
|
void Sprite::flipVertically(bool flip) {
|
||||||
if(flip) {
|
if(flip) {
|
||||||
oam->attr1 |= ATTR1_VFLIP;
|
oam.attr1 |= ATTR1_VFLIP;
|
||||||
} else {
|
} else {
|
||||||
oam->attr1 &= FLIP_VERTICAL_CLEAR;
|
oam.attr1 &= FLIP_VERTICAL_CLEAR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sprite::syncVelocity() {
|
|
||||||
oam->attr0 = (oam->attr0 & ~ATTR0_Y_MASK) | (y & ATTR0_Y_MASK);
|
|
||||||
oam->attr1 = (oam->attr1 & ~ATTR1_X_MASK) | (x & ATTR1_X_MASK);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Sprite::makeAnimated(int beginFrame, int numberOfFrames, int animationDelay) {
|
void Sprite::makeAnimated(int beginFrame, int numberOfFrames, int animationDelay) {
|
||||||
setBeginFrame(beginFrame);
|
setBeginFrame(beginFrame);
|
||||||
animateToFrame(beginFrame);
|
animateToFrame(beginFrame);
|
||||||
|
@ -67,10 +60,17 @@ void Sprite::makeAnimated(int beginFrame, int numberOfFrames, int animationDelay
|
||||||
animate();
|
animate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Sprite::syncVelocity() {
|
||||||
|
oam.attr0 = (oam.attr0 & ~ATTR0_Y_MASK) | (y & ATTR0_Y_MASK);
|
||||||
|
oam.attr1 = (oam.attr1 & ~ATTR1_X_MASK) | (x & ATTR1_X_MASK);
|
||||||
|
}
|
||||||
|
|
||||||
void Sprite::syncAnimation() {
|
void Sprite::syncAnimation() {
|
||||||
|
if(previousFrame == currentFrame) return;
|
||||||
|
|
||||||
int newTileIndex = this->tileIndex + (currentFrame * (this->animation_offset * 2));
|
int newTileIndex = this->tileIndex + (currentFrame * (this->animation_offset * 2));
|
||||||
oam->attr2 &= OAM_TILE_OFFSET_CLEAR;
|
oam.attr2 &= OAM_TILE_OFFSET_CLEAR;
|
||||||
oam->attr2 |= (newTileIndex & OAM_TILE_OFFSET_NEW);
|
oam.attr2 |= (newTileIndex & OAM_TILE_OFFSET_NEW);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sprite::syncOam() {
|
void Sprite::syncOam() {
|
||||||
|
@ -96,6 +96,7 @@ void Sprite::updateAnimation() {
|
||||||
if(!animating) return;
|
if(!animating) return;
|
||||||
|
|
||||||
animationCounter++;
|
animationCounter++;
|
||||||
|
previousFrame = currentFrame;
|
||||||
if(animationCounter > animationDelay) {
|
if(animationCounter > animationDelay) {
|
||||||
currentFrame++;
|
currentFrame++;
|
||||||
if(currentFrame > (numberOfFrames - 1) + beginFrame) {
|
if(currentFrame > (numberOfFrames - 1) + beginFrame) {
|
||||||
|
@ -148,23 +149,19 @@ bool Sprite::collidesWith(Sprite &s2) {
|
||||||
void Sprite::buildOam(int tileIndex) {
|
void Sprite::buildOam(int tileIndex) {
|
||||||
this->tileIndex = tileIndex;
|
this->tileIndex = tileIndex;
|
||||||
|
|
||||||
if(!oam) {
|
oam.attr0 = ATTR0_Y(this->y & 0x00FF) |
|
||||||
this->oam = std::unique_ptr<OBJ_ATTR>(new OBJ_ATTR());
|
ATTR0_MODE(0) |
|
||||||
|
(GFX_MODE << 10) |
|
||||||
|
(MOSAIC_MODE << 12) |
|
||||||
|
(COLOR_MODE_256 << 13) |
|
||||||
|
(this->shape_bits << 14);
|
||||||
|
oam.attr1 = (this->x & 0x01FF) |
|
||||||
|
(AFFINE_FLAG_NONE_SET_YET << 9) |
|
||||||
|
(HORIZONTAL_FLIP_FLAG << 12) |
|
||||||
|
(VERTICAL_FLIP_FLAG << 13) |
|
||||||
|
(this->size_bits << 14);
|
||||||
|
|
||||||
this->oam->attr0 = ATTR0_Y(this->y & 0x00FF) |
|
oam.attr2 = ATTR2_ID(tileIndex) |
|
||||||
ATTR0_MODE(0) |
|
|
||||||
(GFX_MODE << 10) |
|
|
||||||
(MOSAIC_MODE << 12) |
|
|
||||||
(COLOR_MODE_256 << 13) |
|
|
||||||
(this->shape_bits << 14);
|
|
||||||
this->oam->attr1 = (this->x & 0x01FF) |
|
|
||||||
(AFFINE_FLAG_NONE_SET_YET << 9) |
|
|
||||||
(HORIZONTAL_FLIP_FLAG << 12) |
|
|
||||||
(VERTICAL_FLIP_FLAG << 13) |
|
|
||||||
(this->size_bits << 14);
|
|
||||||
}
|
|
||||||
|
|
||||||
this->oam->attr2 = ATTR2_ID(tileIndex) |
|
|
||||||
ATTR2_PRIO(priority) |
|
ATTR2_PRIO(priority) |
|
||||||
ATTR2_PALBANK(0);
|
ATTR2_PALBANK(0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,8 +45,7 @@ void SpriteManager::copyOverSpriteOAMToVRAM() {
|
||||||
for(auto sprite : this->sprites) {
|
for(auto sprite : this->sprites) {
|
||||||
sprite->update();
|
sprite->update();
|
||||||
|
|
||||||
auto oam = sprite->oam.get();
|
oam_mem[i] = sprite->oam;
|
||||||
oam_mem[i] = *oam;
|
|
||||||
|
|
||||||
auto affine = dynamic_cast<AffineSprite*>(sprite);
|
auto affine = dynamic_cast<AffineSprite*>(sprite);
|
||||||
if(affine) {
|
if(affine) {
|
||||||
|
|
Loading…
Reference in New Issue