mirror of
https://github.com/thunderbrewhq/thunderbrew
synced 2025-12-12 19:22:30 +00:00
168 lines
4.1 KiB
C++
168 lines
4.1 KiB
C++
#include "ui/CFrameStrata.hpp"
|
|
#include "ui/CSimpleFrame.hpp"
|
|
#include "ui/CSimpleRender.hpp"
|
|
|
|
int32_t CFrameStrataNode::BuildBatches() {
|
|
if (!this->batchDirty) {
|
|
return 0;
|
|
}
|
|
|
|
int32_t batchDirty = this->batchDirty;
|
|
this->batchDirty = 0;
|
|
|
|
for (int32_t layer = 0; layer < NUM_SIMPLEFRAME_DRAWLAYERS; layer++) {
|
|
CRenderBatch* batch = &this->batches[layer];
|
|
|
|
this->renderList.UnlinkNode(batch);
|
|
|
|
if ((1 << layer) & batchDirty) {
|
|
batch->Clear();
|
|
|
|
for (auto frame = this->frames.Head(); frame; frame = this->frames.Link(frame)->Next()) {
|
|
if (!(frame->m_flags & 0x2000)) {
|
|
frame->OnFrameRender(batch, layer);
|
|
}
|
|
}
|
|
|
|
batch->Finish();
|
|
}
|
|
|
|
if (batch->m_count) {
|
|
this->renderList.LinkToTail(batch);
|
|
}
|
|
}
|
|
|
|
if (this->batchDirty & 0x20) {
|
|
this->batchDirty |= 0x1F;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void CFrameStrataNode::OnLayerUpdate(float elapsedSec) {
|
|
auto frame = this->frames.Head();
|
|
|
|
while (frame) {
|
|
auto next = this->frames.Link(frame)->Next();
|
|
this->pendingFrame = next;
|
|
frame->OnLayerUpdate(elapsedSec);
|
|
frame = this->pendingFrame;
|
|
}
|
|
|
|
// TODO
|
|
// this->frames.Combine(this->pendingFrames, 2, nullptr);
|
|
}
|
|
|
|
bool CFrameStrataNode::RemoveFrame(CSimpleFrame* frame) {
|
|
if (!this->frames.Link(frame)->IsLinked()) {
|
|
return 0;
|
|
}
|
|
|
|
if (frame == this->pendingFrame) {
|
|
this->pendingFrame = this->frames.Link(frame)->Next();
|
|
}
|
|
|
|
this->frames.UnlinkNode(frame);
|
|
|
|
if (!(frame->m_flags & 0x2000)) {
|
|
this->batchDirty = -1;
|
|
}
|
|
|
|
return this->batchDirty != 0;
|
|
}
|
|
|
|
void CFrameStrata::AddFrame(CSimpleFrame* frame) {
|
|
// TODO
|
|
// - potentially an inlined TSFixedArray function?
|
|
if (frame->m_level >= this->levels.Count()) {
|
|
uint32_t count = this->levels.Count();
|
|
|
|
this->levels.SetCount(frame->m_level + 1);
|
|
|
|
for (int32_t i = count; i < frame->m_level + 1; i++) {
|
|
auto m = SMemAlloc(sizeof(CFrameStrataNode), __FILE__, __LINE__, 0x0);
|
|
auto node = new (m) CFrameStrataNode();
|
|
this->levels[i] = node;
|
|
}
|
|
}
|
|
|
|
if (frame->m_level >= this->topLevel) {
|
|
this->topLevel = frame->m_level + 1;
|
|
}
|
|
|
|
auto level = this->levels[frame->m_level];
|
|
|
|
if (!frame->m_strataLink.IsLinked()) {
|
|
auto frames = level->pendingFrame ? &level->pendingFrames : &level->frames;
|
|
|
|
frames->LinkToTail(frame);
|
|
|
|
if (!(frame->m_flags & 0x2000)) {
|
|
level->batchDirty = -1;
|
|
}
|
|
}
|
|
|
|
this->levelsDirty = 1;
|
|
this->batchDirty |= (level->batchDirty != 0);
|
|
}
|
|
|
|
void CFrameStrata::CheckOcclusion() {
|
|
// TODO
|
|
}
|
|
|
|
int32_t CFrameStrata::BuildBatches(int32_t a2) {
|
|
if (this->levelsDirty) {
|
|
this->CheckOcclusion();
|
|
this->levelsDirty = 0;
|
|
}
|
|
|
|
if (!this->batchDirty) {
|
|
return this->batchDirty;
|
|
}
|
|
|
|
this->batchDirty = 0;
|
|
|
|
if (this->topLevel == 0) {
|
|
return 0;
|
|
}
|
|
|
|
for (int32_t i = 0; i < this->topLevel; i++) {
|
|
if (this->levels[i]->BuildBatches()) {
|
|
this->batchDirty = 1;
|
|
}
|
|
}
|
|
|
|
return this->batchDirty;
|
|
}
|
|
|
|
int32_t CFrameStrata::FrameOccluded(CSimpleFrame* frame) {
|
|
// TODO
|
|
return 0;
|
|
}
|
|
|
|
void CFrameStrata::OnLayerUpdate(float elapsedSec) {
|
|
if (this->topLevel) {
|
|
for (int32_t l = 0; l < this->topLevel; l++) {
|
|
this->levels[l]->OnLayerUpdate(elapsedSec);
|
|
}
|
|
}
|
|
}
|
|
|
|
void CFrameStrata::RemoveFrame(CSimpleFrame* frame) {
|
|
if (frame->m_level < this->levels.Count()) {
|
|
CFrameStrataNode* level = this->levels[frame->m_level];
|
|
int32_t batchDirty = level->RemoveFrame(frame);
|
|
this->batchDirty |= batchDirty;
|
|
this->levelsDirty = 1;
|
|
}
|
|
}
|
|
|
|
void CFrameStrata::RenderBatches() {
|
|
for (int32_t i = 0; i < this->topLevel; i++) {
|
|
auto renderList = &this->levels[i]->renderList;
|
|
|
|
for (auto batch = renderList->Head(); batch; batch = renderList->Link(batch)->Next()) {
|
|
CSimpleRender::DrawBatch(batch);
|
|
}
|
|
}
|
|
}
|