// // Created by Wouter Groeneveld on 26/07/18. // #include #include #include #include #include #define MAX_SPRITE_SIZE 128 #define MAX_AFFINE_SIZE 31 void SpriteManager::set(std::vector sprites) { initialized = false; this->sprites.clear(); this->sprites.insert(this->sprites.end(), sprites.begin(), sprites.end()); } void SpriteManager::add(Sprite* sprite) { if(sprites.size() == MAX_SPRITE_SIZE) { failure_gba(MaxSpriteSizeReached); } sprites.push_back(sprite); copyOverImageDataToVRAM(sprite); } void SpriteManager::render() { // WARNING - This is called every time in the main update loop; keep amount of instructions as minimal as possible in here! copyOverSpriteOAMToVRAM(); } void SpriteManager::persist() { copyOverImageDataToVRAM(); initialized = true; } void SpriteManager::copyOverSpriteOAMToVRAM() { int i = 0; int affineIndex = 0; for(auto sprite : this->sprites) { sprite->update(); oam_mem[i] = sprite->oam; if(sprite->isAffine) { // WHY warning: can't do this: obj_aff_mem[affineIndex] = *affineShadow; // because that would override OAM also! only want to set non-overlapping affine attribs auto affine = static_cast(sprite); affine->setTransformationMatrix(&obj_aff_mem[affineIndex]); affine->setAffineIndex(affineIndex); affineIndex++; } i++; } } void SpriteManager::hideAll() { for(int i = 0; i < MAX_SPRITE_SIZE; i++) { oam_mem[i].attr0 = ATTR0_HIDE; } } void SpriteManager::copyOverImageDataToVRAM(Sprite *sprite) { if(!sprite->data && sprite->imageSize == 0) { // assume it's copied over from another sprite sprite->buildOam(sprite->tileIndex); } else { const auto allocated = Allocator::allocateObjectTiles(sprite->imageSize); dma3_cpy(allocated.pointer(), sprite->data, allocated.size); sprite->buildOam(allocated.getTileLocation()); } } void SpriteManager::copyOverImageDataToVRAM() { for(auto sprite : sprites) { copyOverImageDataToVRAM(sprite); } }