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() {
|
||||
// TODO this is VERY ineffective, but it's a nice example of how C++11 remove_if works.
|
||||
bullets.erase(
|
||||
std::remove_if(bullets.begin(), bullets.end(), [](std::unique_ptr<Bullet> &s) { return s->isOffScreen(); }),
|
||||
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::string(engine->getTimer()->to_string()), 6, 1);
|
||||
|
||||
|
||||
avatar->animateToFrame(0);
|
||||
bool allowedToShoot = false;
|
||||
int oldBulletSize = bullets.size();
|
||||
|
@ -66,11 +68,6 @@ void FoodScene::tick(u16 keys) {
|
|||
}
|
||||
|
||||
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) {
|
||||
avatarRotation -= AVATAR_ROTATION_DIFF;
|
||||
|
@ -92,6 +89,7 @@ void FoodScene::tick(u16 keys) {
|
|||
}
|
||||
|
||||
avatar->rotate(avatarRotation);
|
||||
|
||||
if(oldBulletSize != bullets.size()) {
|
||||
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
|
||||
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();
|
||||
}
|
|
@ -58,10 +58,9 @@ protected:
|
|||
bool stayWithinBounds;
|
||||
u32 imageSize, tileIndex;
|
||||
SpriteSize spriteSize;
|
||||
u32 animationDelay, numberOfFrames, beginFrame, currentFrame, animationCounter;
|
||||
u8 animationDelay, numberOfFrames, beginFrame, currentFrame, previousFrame, animationCounter;
|
||||
bool animating;
|
||||
|
||||
std::unique_ptr<OBJ_ATTR> oam;
|
||||
OBJ_ATTR oam;
|
||||
|
||||
void syncAnimation();
|
||||
virtual void syncOam();
|
||||
|
|
|
@ -38,7 +38,7 @@ void AffineSprite::setTransformationMatrix(OBJ_AFFINE *matrix) {
|
|||
}
|
||||
|
||||
void AffineSprite::rebuildOamAttr1ForAffineIndex() {
|
||||
this->oam->attr1 = this->x |
|
||||
oam.attr1 = this->x |
|
||||
ATTR1_AFF_ID(affIndex) |
|
||||
(HORIZONTAL_FLIP_FLAG << 12) |
|
||||
(VERTICAL_FLIP_FLAG << 13) |
|
||||
|
@ -47,7 +47,7 @@ void AffineSprite::rebuildOamAttr1ForAffineIndex() {
|
|||
|
||||
void AffineSprite::buildOam(int tileIndex) {
|
||||
Sprite::buildOam(tileIndex);
|
||||
this->oam->attr0 = ATTR0_Y(this->y) |
|
||||
oam.attr0 = ATTR0_Y(this->y) |
|
||||
ATTR0_MODE(1) |
|
||||
(GFX_MODE << 10) |
|
||||
(MOSAIC_MODE << 12) |
|
||||
|
|
|
@ -29,9 +29,7 @@ void Sprite::moveTo(VECTOR location) {
|
|||
void Sprite::moveTo(int x, int y) {
|
||||
this->x = x;
|
||||
this->y = y;
|
||||
if(oam) {
|
||||
syncOam();
|
||||
}
|
||||
syncOam();
|
||||
}
|
||||
|
||||
bool Sprite::isOffScreen() {
|
||||
|
@ -40,25 +38,20 @@ bool Sprite::isOffScreen() {
|
|||
|
||||
void Sprite::flipHorizontally(bool flip) {
|
||||
if(flip) {
|
||||
oam->attr1 |= ATTR1_HFLIP;
|
||||
oam.attr1 |= ATTR1_HFLIP;
|
||||
} else {
|
||||
oam->attr1 &= FLIP_HORIZONTAL_CLEAR;
|
||||
oam.attr1 &= FLIP_HORIZONTAL_CLEAR;
|
||||
}
|
||||
}
|
||||
|
||||
void Sprite::flipVertically(bool flip) {
|
||||
if(flip) {
|
||||
oam->attr1 |= ATTR1_VFLIP;
|
||||
oam.attr1 |= ATTR1_VFLIP;
|
||||
} 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) {
|
||||
setBeginFrame(beginFrame);
|
||||
animateToFrame(beginFrame);
|
||||
|
@ -67,10 +60,17 @@ void Sprite::makeAnimated(int beginFrame, int numberOfFrames, int animationDelay
|
|||
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() {
|
||||
if(previousFrame == currentFrame) return;
|
||||
|
||||
int newTileIndex = this->tileIndex + (currentFrame * (this->animation_offset * 2));
|
||||
oam->attr2 &= OAM_TILE_OFFSET_CLEAR;
|
||||
oam->attr2 |= (newTileIndex & OAM_TILE_OFFSET_NEW);
|
||||
oam.attr2 &= OAM_TILE_OFFSET_CLEAR;
|
||||
oam.attr2 |= (newTileIndex & OAM_TILE_OFFSET_NEW);
|
||||
}
|
||||
|
||||
void Sprite::syncOam() {
|
||||
|
@ -96,6 +96,7 @@ void Sprite::updateAnimation() {
|
|||
if(!animating) return;
|
||||
|
||||
animationCounter++;
|
||||
previousFrame = currentFrame;
|
||||
if(animationCounter > animationDelay) {
|
||||
currentFrame++;
|
||||
if(currentFrame > (numberOfFrames - 1) + beginFrame) {
|
||||
|
@ -148,23 +149,19 @@ bool Sprite::collidesWith(Sprite &s2) {
|
|||
void Sprite::buildOam(int tileIndex) {
|
||||
this->tileIndex = tileIndex;
|
||||
|
||||
if(!oam) {
|
||||
this->oam = std::unique_ptr<OBJ_ATTR>(new OBJ_ATTR());
|
||||
oam.attr0 = ATTR0_Y(this->y & 0x00FF) |
|
||||
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) |
|
||||
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) |
|
||||
oam.attr2 = ATTR2_ID(tileIndex) |
|
||||
ATTR2_PRIO(priority) |
|
||||
ATTR2_PALBANK(0);
|
||||
}
|
||||
|
|
|
@ -45,8 +45,7 @@ void SpriteManager::copyOverSpriteOAMToVRAM() {
|
|||
for(auto sprite : this->sprites) {
|
||||
sprite->update();
|
||||
|
||||
auto oam = sprite->oam.get();
|
||||
oam_mem[i] = *oam;
|
||||
oam_mem[i] = sprite->oam;
|
||||
|
||||
auto affine = dynamic_cast<AffineSprite*>(sprite);
|
||||
if(affine) {
|
||||
|
|
Loading…
Reference in New Issue