Alchemy
Loading...
Searching...
No Matches

outputs.c

Go to the documentation of this file.
1/// @file
2/// Sprite outputs, portraits and the window spans.
3/// Part of battle_command.c, the menu object, compiled only through it.
4
6
7/// Creates a sprite output for the VRAM cache slot `slot` and attaches it to
8/// `window`, placed at (offsetX, offsetY) pixels from the window's inner
9/// corner (one tile in from its top-left border). `oamFlags` holds the OAM
10/// shape and size bits. The sprite draws on layer 255 until the caller changes
11/// it. Returns the output, or NULL with the VRAM slot released when all
12/// outputs are in use.
13struct RenderOutput *RenderOutput_Create(s32 slot, s32 oamFlags,
14 struct UiWindow *window, s32 offsetX,
15 s32 offsetY) {
16 s32 x;
17 struct RenderOutput *output;
18 s32 y;
19
20 output = RenderOutput_AcquireFree();
21 if (output == NULL) {
23 return NULL;
24 }
25
26 // Window tiles to screen pixels, wrapped to OAM's 9-bit X and 8-bit Y.
27 x = offsetX + (window->x * 8) + 8;
28 y = offsetY + (window->y * 8) + 8;
29 x &= 0x1ff;
30 y &= 0xff;
31 // UB: attributes 0 and 1, then attribute 2, are written as words through
32 // the bitfields; UBFIX copies the words.
33#ifdef UBFIX
34 {
35 u32 words[2];
36
37 words[0] = (x << 16) | y | oamFlags;
38 // Attribute 2: the first tile of the slot's VRAM block (32 bytes a tile).
39 words[1] =
40 ((struct VramBlockCacheEntry *)Ram_VramBlockCache)[slot].offset >> 5;
41 __builtin_memcpy(&output->oam, words, sizeof(words));
42 }
43#else
44 *(u32 *)&output->oam = (x << 16) | y | oamFlags;
45 // Attribute 2: the first tile of the slot's VRAM block (32 bytes a tile).
46 ((u32 *)&output->oam)[1] =
47 ((struct VramBlockCacheEntry *)Ram_VramBlockCache)[slot].offset >> 5;
48#endif
49 output->sentinel = 0xff;
50 output->next = NULL;
51 output->x = x;
52 output->y = y;
53 output->index = slot;
54 output->kind = 1;
55 output->active = 1;
56 RenderOutput_AppendToList(&window->output, output);
57 return output;
58}
59
60/// Loads resource `resource` in loading mode `mode` into a VRAM slot and shows
61/// it as a 16x16 sprite at (x, y) in `window`. Returns NULL when it cannot be
62/// loaded.
64 struct UiWindow *window,
65 s32 x, s32 y) {
66 s32 slot;
67
68 slot = Resource_LoadByMode(mode, resource);
69 if (slot < 0) {
70 return NULL;
71 }
72 return RenderOutput_Create(slot, OUTPUT_SIZE_16X16, window, x, y);
73}
74
75/// Copies icon `icon` (with `layers` passed on to the copier) into a free VRAM
76/// slot and shows it as a 16x16 sprite at (x, y) in `window`. Returns NULL
77/// when no slot is free.
79 struct UiWindow *window, s32 x,
80 s32 y) {
81 s32 slot;
82 struct RenderOutput *output;
83
85 output = NULL;
86 if (slot != VRAM_CACHE_ENTRY_COUNT) {
87 UiIcon_CopyResourceToSlot(icon, layers, slot);
88 output = RenderOutput_Create(slot, OUTPUT_SIZE_16X16, window, x, y);
89 }
90 return output;
91}
92
93/// Builds a 16x16 icon from frame pattern 1 with overlay pattern `icon` drawn
94/// over it, and shows it at (x, y) in `window` on draw layer 251. Returns NULL
95/// when no VRAM slot is free.
97 struct UiWindow *window,
98 s32 x, s32 y) {
99 s32 slot;
100 s32 unusedTile;
101 struct RenderOutput *output;
102
103 slot = Resource_FindFreeEntry();
104 if (slot == VRAM_CACHE_ENTRY_COUNT) {
105 return NULL;
106 }
107 Ui_BuildPairedPatternsToSlot(icon, 1, &slot, &unusedTile, 1);
108 output = RenderOutput_Create(slot, OUTPUT_SIZE_16X16, window, x, y);
109 output->sentinel = 251;
110 return output;
111}
112
113/// Loads the pattern at the start of gRenderResource_PairSourceTable into a
114/// free VRAM slot and shows it as a 16x16 sprite at (x, y) in `window`.
115/// `tableEntry` is passed on to the loader, which loads that same pattern for
116/// every value. Returns NULL when no slot is free.
118 struct UiWindow *window,
119 s32 x, s32 y) {
120 s32 slot;
121 struct RenderOutput *output;
122
123 slot = Resource_FindFreeEntry();
124 output = NULL;
125 if (slot != VRAM_CACHE_ENTRY_COUNT) {
126 RenderResource_LoadTableEntry(tableEntry, 0, slot);
127 output = RenderOutput_Create(slot, OUTPUT_SIZE_16X16, window, x, y);
128 }
129 return output;
130}
131
132/// Shows the 32x32 portrait of `character` at (x, y) in `window`, in portrait
133/// slot `side` (0 or 1, or any other value for the first free one; the second
134/// is tried first). Each slot has its own palette, 14 or 15. In the prologue,
135/// characters 0 and 1 show portraits 18 and 19 instead. `unused` is
136/// passed on to the loader, which ignores it. Returns the sprite, or NULL when
137/// the character has no portrait or both slots are taken.
138struct RenderOutput *CreateSideObject(s32 character, s32 unused, s32 side,
139 struct UiWindow *window, s32 x, s32 y) {
140 struct UiRenderWork *work = UI_WORK;
141 struct RenderOutput *portrait = NULL;
142 s32 slot;
143 s32 tile;
144 s32 icon;
145 s32 palette;
146
148 if (character == 0)
149 character = 18;
150 if (character == 1)
151 character = 19;
152 }
153
154 icon = Localization_LookupEntryId(character);
155 if (icon == -1)
156 return portrait;
157
158 if ((u32)side > 1) {
159 side = 1;
160 if (work->resourceIds[1] != PORTRAIT_SLOT_EMPTY) {
161 side = 0;
162 if (work->resourceIds[0] != PORTRAIT_SLOT_EMPTY)
163 return portrait;
164 }
165 }
166
167 palette = PORTRAIT_PALETTE + side;
168 UiGlyph_LoadEntryWithPalette(icon, unused, &slot, &tile, palette, 0);
169 portrait = RenderOutput_Create(slot, OUTPUT_SIZE_32X32, window, x, y);
170 if (portrait != NULL) {
171 portrait->oam.palette = palette;
172 portrait->kind = 2;
173 }
174
175 work->resourceIds[side] = icon;
176 work->outputIds[side] = slot;
177 return portrait;
178}
179
180/// Reloads the portrait image of `character` into portrait slot `side` (0 or
181/// 1), keeping its sprite: used to change the picture of a portrait already on
182/// screen. With any other `side`, the slot already showing that character's
183/// portrait is used, and nothing happens when none does. `unused` is passed on
184/// to the loader, which ignores it.
185void Ui_LoadCharacterEntryForSlot(u32 side, s32 character, s32 unused) {
186 s32 tile;
187 s32 slot;
188 u32 icon;
189 struct UiRenderWork *work;
190
191 work = UI_WORK;
192
194 if (character == 0)
195 character = 18;
196 if (character == 1)
197 character = 19;
198 }
199
200 icon = Localization_LookupEntryId(character);
201 if (icon != -1U) {
202 if (side > 1U) {
203 if (work->resourceIds[1] == icon) {
204 side = 1;
205 } else if (work->resourceIds[0] == icon) {
206 side = 0;
207 } else {
208 return;
209 }
210 }
211 slot = work->outputIds[side];
212 UiGlyph_LoadEntryWithPalette(icon, unused, &slot, &tile,
213 PORTRAIT_PALETTE + side, 1);
214 }
215}
216
217/// Switches the sprite output `out` to animation `mode` from its first step.
218/// Does nothing when `out` is NULL.
220 if (out != NULL) {
221 out->active = mode;
222 out->animStep = 0;
223 }
224}
225
226/// Sets the draw layer of the sprite output `output` to 255 - `priority`, so a
227/// higher priority draws on a lower layer. Does nothing when `output` is NULL.
228void RenderOutput_SetInvertedSentinel(void *output, s32 priority) {
229 if (output != NULL)
230 ((struct RenderOutput *)output)->sentinel = ~priority;
231}
232
233typedef void (*WindowSpanRoutine)(u16 *spans, u16 *tilemap);
234
235/// Fills `spans` with the horizontal extent of the windows on each of the 20
236/// tile rows, read from the UI tilemap by the ARM routine Tile_BuildMetatiles
237/// copied into RAM. With no UI work, every row is filled with 0xe0e0 (no
238/// window).
239void UiWindow_FillFromScene(void *spans) {
240 void *tilemap = gWindowWork[0];
241
242 if (tilemap == NULL) {
243 Dma_Fill16(0xe0e0, spans, 0x140);
244 } else {
245 WindowSpanRoutine routine;
246
248 routine(spans, tilemap);
249 MemFree(routine);
250 }
251}
252
253/// Fills the top-left `width` x `height` tiles of the 32-tile-wide BG screen
254/// block at 0x06002000 with the tilemap entry `value`. The first two
255/// parameters are ignored.
256void UiWindow_FillScreenBlockRect(s32 unused0, s32 unused1, u32 width,
257 u32 height, s32 value) {
258 u32 row = 0;
259 s16 *dst = (s16 *)UI_TILEMAP_VRAM;
260
261 if (row < height) {
262 do {
263 u32 column = 0;
264 if (column < width) {
265 do {
266 column++;
267 *dst = value;
268 dst++;
269 } while (column < width);
270 }
271 row++;
272 dst += 32 - width;
273 } while (row < height);
274 }
275}
What every part of the menu object shares: its includes, edition values, macros and the link round st...
#define OUTPUT_SIZE_32X32
#define PORTRAIT_SLOT_EMPTY
#define OUTPUT_SIZE_16X16
OAM attribute bits a sprite output is created with: the size field of attribute 1 (bits 30-31 of the ...
#define PORTRAIT_PALETTE
#define Dma_Fill16(value, destination, size)
Fills size bytes at destination with the halfword value by DMA3, from a volatile copy of it on the st...
Definition dma.h:22
s32 GameFlag_TestFar(s32 flag)
#define FLAG_CHILDHOOD
the prologue: Isaac and Garet are children
Definition flags.h:10
void Tile_BuildMetatiles(u16 *scanlineBounds, u16 *frameTiles)
Builds the hardware window's horizontal extent for each of the screen's 160 scanlines from frameTiles...
Definition glyph_arm.c:288
u8 Tile_BuildMetatilesCodeSize[]
void MemFree(void *buffer)
void UiWindow_FillFromScene(void *spans)
Fills spans with the horizontal extent of the windows on each of the 20 tile rows,...
Definition outputs.c:239
void RenderOutput_SetAnimation(struct RenderOutput *out, s32 mode)
Switches the sprite output out to animation mode from its first step.
Definition outputs.c:219
struct RenderOutput * RenderOutput_Create(s32 slot, s32 oamFlags, struct UiWindow *window, s32 offsetX, s32 offsetY)
Creates a sprite output for the VRAM cache slot slot and attaches it to window, placed at (offsetX,...
Definition outputs.c:13
struct RenderOutput * RenderOutput_CreateFromTable(s32 tableEntry, struct UiWindow *window, s32 x, s32 y)
Loads the pattern at the start of gRenderResource_PairSourceTable into a free VRAM slot and shows it ...
Definition outputs.c:117
struct RenderOutput * RenderOutput_CreateFromResource(s32 mode, s32 resource, struct UiWindow *window, s32 x, s32 y)
Loads resource resource in loading mode mode into a VRAM slot and shows it as a 16x16 sprite at (x,...
Definition outputs.c:63
struct RenderOutput * RenderOutput_CreateWithTransform(s32 icon, struct UiWindow *window, s32 x, s32 y)
Builds a 16x16 icon from frame pattern 1 with overlay pattern icon drawn over it, and shows it at (x,...
Definition outputs.c:96
void Ui_LoadCharacterEntryForSlot(u32 side, s32 character, s32 unused)
Reloads the portrait image of character into portrait slot side (0 or 1), keeping its sprite: used to...
Definition outputs.c:185
void UiWindow_FillScreenBlockRect(s32 unused0, s32 unused1, u32 width, u32 height, s32 value)
Fills the top-left width x height tiles of the 32-tile-wide BG screen block at 0x06002000 with the ti...
Definition outputs.c:256
void RenderOutput_SetInvertedSentinel(void *output, s32 priority)
Sets the draw layer of the sprite output output to 255 - priority, so a higher priority draws on a lo...
Definition outputs.c:228
struct RenderOutput * RenderOutput_CreateLoaded(s32 icon, s32 layers, struct UiWindow *window, s32 x, s32 y)
Copies icon icon (with layers passed on to the copier) into a free VRAM slot and shows it as a 16x16 ...
Definition outputs.c:78
void(*) WindowSpanRoutine(u16 *spans, u16 *tilemap)
Definition outputs.c:233
struct RenderOutput * CreateSideObject(s32 character, s32 unused, s32 side, struct UiWindow *window, s32 x, s32 y)
Shows the 32x32 portrait of character at (x, y) in window, in portrait slot side (0 or 1,...
Definition outputs.c:138
#define Ram_VramBlockCache
Definition ram_buffer.h:38
#define RamCode_Load(to, code, bytes)
Allocates a heap copy; release it with MemFree when finished.
Definition ramcode.h:15
s32 Resource_LoadByMode(s32 mode, s32 value)
Loads the icon of an entry of kind mode (1 and 6 commands, 2 items, 4 Psynergy, 9 fixed images) into ...
Definition selection.c:1011
#define NULL
Definition bilibin.h:6
u8 gWindowWork[]
A render output: a sprite in a window's output list (a character, an icon or a portrait),...
struct RenderOam oam
u16 y
screen pixels
u8 sentinel
depth slot it is drawn at (254 for glyphs)
s8 active
its UI_SPRITE_ motion; 0 while free
struct RenderOutput * next
the next output in its list
u16 animStep
step of its motion's animation
u16 x
screen pixels
s8 kind
0 for a glyph; otherwise it owns VRAM cache slot index, freed with it, and 2 (a portrait) also its pa...
s8 index
VRAM cache slot, or a glyph's tile after glyphTiles.
The window system's work: the windows' tilemap, the windows, the three text channels,...
Definition window.h:19
u8 mode
Set while Mind Read shows thoughts: round frame corners, colour 8 text with no shadow,...
Definition window.h:35
u16 outputIds[2]
VRAM cache slot of each portrait slot's picture.
Definition window.h:59
u16 resourceIds[2]
picture shown in each portrait slot; 999 when free
Definition window.h:58
A window: a framed rectangle of the tilemap with its sprite outputs, its opening or closing animation...
Definition uiwindow.h:11
u16 y
tiles
Definition uiwindow.h:16
u16 x
tiles
Definition uiwindow.h:15
struct RenderOutputList output
the sprites the window carries
Definition uiwindow.h:12
A sprite slot of the VRAM cache: the size of its block and where the block starts in OBJ VRAM.
Definition vram_tab.h:23
u16 offset
bytes from the start of OBJ VRAM
Definition vram_tab.h:25
signed int s32
Definition types.h:14
unsigned int u32
Definition types.h:15
signed short s16
Definition types.h:12
unsigned short u16
Definition types.h:13
#define UI_TILEMAP_VRAM
The UI tilemap in VRAM (BG screen block 4), which UiWork_UploadDirtyBlocks copies the work block's ti...
Definition window.h:51
#define UI_WORK
Definition window.h:267
s32 Resource_ResetEntry(u32 no)
Frees cache entry no: its blocks go back and the entry is marked free (offset 0xffff).
Definition vram_cache.c:106
s32 Resource_FindFreeEntry(void)
Returns the number of the first free cache entry, or VRAM_CACHE_ENTRY_COUNT when all are taken.
Definition vram_cache.c:211
@ VRAM_CACHE_ENTRY_COUNT
Definition vram_tab.h:12
s32 UiIcon_CopyResourceToSlot(s32 inventoryCode, s32 layers, s32 cacheSlot)
Composes an inventory icon with the requested layers and loads it into cacheSlot.
Definition icons.c:166
s32 RenderResource_LoadTableEntry(u32 value, s32 unused, u32 slot)
Loads one of four small fixed images into the sprite tile slot named by slot.
Definition icons.c:190
void Ui_BuildPairedPatternsToSlot(s32 overlayIcon, s32 frameIcon, s32 *slot, s32 *tileOut, s32 reuse)
Builds a command icon (overlay overlayIcon over frame frameIcon) and loads it into a sprite tile slot...
Definition icons.c:20
void UiGlyph_LoadEntryWithPalette(u32 icon, s32 unused, s32 *slot, s32 *tile, s32 palette, s32 reuse)
Loads a 32x32 icon from the icon resource into sprite tile slot *slot (a free slot unless reuse is se...
Definition icons.c:291
s32 Localization_LookupEntryId(u32 value)
Returns the portrait of a character (ids below 20) or another speaker's sprite (128 and up for those)...
Definition messages.c:486
void RenderOutput_AppendToList(struct RenderOutputList *list, struct RenderOutput *node)
Adds a render output to the end of a list; NULL lists are ignored.
Definition windows.c:478
struct RenderOutput * RenderOutput_AcquireFree(void)
Takes the first render output from the free list, or returns NULL when every output is in use.
Definition windows.c:9