1#include "Library/Camera/CameraResourceHolder.h"
2
3#include <prim/seadSafeString.h>
4
5#include "Library/Base/StringUtil.h"
6#include "Library/Camera/CameraTicketId.h"
7#include "Library/Placement/PlacementId.h"
8#include "Library/Resource/Resource.h"
9#include "Library/Yaml/ByamlIter.h"
10
11namespace al {
12
13CameraResourceHolder::CameraResourceHolder(const char* stageName, s32 maxResources)
14 : mStageName(stageName), mMaxEntries(maxResources) {
15 mEntries = new Entry*[maxResources];
16 for (s32 i = 0; i < mMaxEntries; i++)
17 mEntries[i] = nullptr;
18}
19
20// too large to inline with heuristic, but needs to be explicit function (or inline lambda) for
21// stack ordering to match original assembly
22__attribute__((always_inline)) void getStageName(StringTmp<128>* stageName,
23 const char* archiveName) {
24 sead::FixedSafeString<256> safeArchiveName;
25 safeArchiveName.format(formatStr: "%s", archiveName);
26 if (safeArchiveName.endsWith(suffix: "Map"))
27 stageName->copy(src: safeArchiveName, copyLength: safeArchiveName.calcLength() - 3);
28}
29
30bool CameraResourceHolder::tryInitCameraResource(const Resource* resource, s32 unused) {
31 StringTmp<128> stageName = "";
32 getStageName(stageName: &stageName, archiveName: resource->getArchiveName());
33
34 for (s32 i = 0; i < mNumEntries; i++)
35 if (isEqualString(safestr1: stageName.cstr(), safestr2: mEntries[i]->stageName))
36 return false;
37
38 Entry* entry = new Entry;
39
40 if (resource->isExistFile(filePath: StringTmp<64>{"%s.byml", "CameraParam"}))
41 entry->cameraParam = new ByamlIter(resource->getByml(filePath: "CameraParam"));
42
43 if (resource->isExistFile(filePath: StringTmp<64>{"%s.byml", "InterpoleParam"}))
44 entry->interpoleParam = new ByamlIter(resource->getByml(filePath: "InterpoleParam"));
45
46 entry->stageName = stageName;
47
48 mEntries[mNumEntries] = entry;
49 mNumEntries++;
50 return true;
51}
52
53bool CameraResourceHolder::tryFindParamResource(ByamlIter* ticket, const CameraTicketId* ticketId,
54 s32 paramType) const {
55 ByamlIter paramList;
56 const PlacementId* placementId = ticketId->getPlacementId();
57 const char* paramName;
58 if (paramType == 2)
59 paramName = "StartTickets";
60 else if (paramType == 0)
61 paramName = "DefaultTickets";
62 else
63 paramName = "Tickets";
64
65 if (!tryFindCameraParamList(paramList: &paramList, placementId, paramName))
66 return false;
67
68 for (s32 i = 0; i < paramList.getSize(); i++) {
69 if (paramList.tryGetIterByIndex(iter: ticket, index: i)) {
70 ByamlIter id;
71 ticket->tryGetIterByKey(iter: &id, key: "Id");
72 if (ticketId->isEqual(iter: id))
73 return true;
74 }
75 }
76 return false;
77}
78
79bool CameraResourceHolder::tryFindCameraParamList(ByamlIter* paramList,
80 const PlacementId* placementId,
81 const char* paramName) const {
82 if (placementId && placementId->getUnitConfigName())
83 return tryFindCameraParamList(paramList, stageName: placementId->getUnitConfigName(), paramName);
84 else
85 return tryFindCameraParamList(paramList, stageName: mStageName, paramName);
86}
87
88s32 CameraResourceHolder::calcEntranceCameraParamNum() const {
89 ByamlIter startTickets;
90 if (!tryFindCameraParamList(paramList: &startTickets, stageName: mStageName, paramName: "StartTickets"))
91 return 0;
92 return startTickets.getSize();
93}
94
95bool CameraResourceHolder::tryFindCameraParamList(ByamlIter* paramList, const char* stageName,
96 const char* paramName) const {
97 CameraResourceHolder::Entry* entry = findCameraResource(stageName);
98 if (!entry || !entry->cameraParam)
99 return false;
100 return entry->cameraParam->tryGetIterByKey(iter: paramList, key: paramName);
101}
102
103void CameraResourceHolder::getEntranceCameraParamResource(ByamlIter* ticket, s32 index) const {
104 ByamlIter startTickets;
105 tryFindCameraParamList(paramList: &startTickets, stageName: mStageName, paramName: "StartTickets");
106 startTickets.tryGetIterByIndex(iter: ticket, index);
107}
108
109CameraResourceHolder::Entry* CameraResourceHolder::findCameraResource(const char* stageName) const {
110 for (s32 i = 0; i < mNumEntries; i++)
111 if (isEqualString(safestr1: stageName, safestr2: mEntries[i]->stageName))
112 return mEntries[i];
113
114 return nullptr;
115}
116
117CameraResourceHolder::Entry*
118CameraResourceHolder::tryFindCameraResource(const char* stageName) const {
119 return findCameraResource(stageName);
120}
121
122CameraResourceHolder::Entry*
123CameraResourceHolder::tryFindCameraResource(const PlacementId* placementId) const {
124 if (placementId) {
125 const char* name = placementId->getUnitConfigName();
126 if (!name)
127 name = mStageName;
128 return findCameraResource(stageName: name);
129 } else {
130 return findCameraResource(stageName: mStageName);
131 }
132}
133
134} // namespace al
135