Alchemy
Loading...
Searching...
No Matches

map_layers.c

Go to the documentation of this file.
1/// @file
2/// Layered maps: loading, drawing and scrolling, and copying cells.
3/// Part of field.c, the field object, compiled only through it.
4
5#include "../field_internal.h"
6
7/// Remaps byteCount bytes in place through gRuntime_ByteRemapTable. Called
8/// through Runtime_RemapBytesByTableFar by RenderResource_LoadFrame, which
9/// remaps the colours of a command icon's first 768 bytes.
10void Runtime_RemapBytesByTable(u8 *bytes, s32 byteCount) {
11 s32 remaining;
12 u8 *cursor;
13 u8 *remapTable;
14
15 cursor = bytes;
16 remapTable = gRuntime_ByteRemapTable;
17 remaining = byteCount - 1;
18 if (remaining != -1) {
19 do {
20 remaining -= 1;
21 *cursor = remapTable[*cursor];
22 cursor += 1;
23 } while (remaining != -1);
24 }
25}
26
27/// Unpacks the staged block data into gMapBlocks. Byte 1 of the staged buffer
28/// (Ram_MapCellBuffer) is the method, and the
29/// 16-bit data follows from byte 2. size counts the method byte too (an even
30/// size means no data). Methods:
31/// 0: copy as it is
32/// 1: all the high bytes, then all the low bytes; each value is XORed with
33/// the one before
34/// 2: each value is XORed with the one before
35///
36/// Called by Map_LoadLayeredScene with the size Resource_DecodeType01
37/// returns; the packed stream is decoded to Ram_MapCellBuffer + 1 so that
38/// its method byte lands at byte 1 and the halfwords at byte 2 are aligned.
40 u16 *destinationWords;
41 u16 *sourceWords;
42 s32 wordCount;
43 s32 i;
44
45 sourceWords = (u16 *)(Ram_MapCellBuffer + 2);
46 destinationWords = (u16 *)gMapBlocks;
47 wordCount = (size - 1) / 2;
48 if (size & 1) {
49 switch (((u8 *)gMapCellBuffer)[1]) {
50 case 0:
51 for (i = 0; i < wordCount; i++)
52 *destinationWords++ = *sourceWords++;
53 break;
54 case 1: {
55 u32 previousWord = 0;
56 u8 *highBytes = Ram_MapCellBuffer + 2;
57 u8 *lowBytes = highBytes + wordCount;
58
59 for (i = 0; i < wordCount; i++) {
60 u32 decodedWord = ((*highBytes++ << 8) | *lowBytes++) ^ previousWord;
61 *destinationWords++ = decodedWord;
62 previousWord = decodedWord;
63 }
64 break;
65 }
66 case 2: {
67 s32 previousWord = 0;
68
69 for (i = 0; i < wordCount; i++) {
70 s32 decodedWord = *sourceWords++ ^ previousWord;
71 *destinationWords++ = decodedWord;
72 previousWord = decodedWord;
73 }
74 break;
75 }
76 }
77 }
78}
79
80typedef void (*TilemapConvertFn)(void *dst, const void *src, const void *saved);
81
82/// Gives each map cell whose block number is 0xfff (a placeholder) a number
83/// of its own, counting up from 0 in map order.
85 u32 *cell = (u32 *)gMapCellBuffer;
86 u32 remaining = 128 << 7;
87 u32 mask = 0xfff;
88 s32 nextPlaceholderBlock = -1;
89
90 do {
91 u32 value = *cell++;
92 u32 blockId = value & mask;
93
94 if (blockId == mask) {
95 if (nextPlaceholderBlock != blockId) {
96 nextPlaceholderBlock++;
97 }
98 value = value + nextPlaceholderBlock - blockId;
99 cell[-1] = value;
100 }
101 remaining--;
102 } while (remaining != 0);
103}
104
105/// Converts the map's cells in place with Tile_ConvertMap, run from RAM, from
106/// a saved copy of the staged buffer. Called by Map_LoadLayeredScene once the
107/// cell planes are decoded. Copies the first 32 KB of Ram_MapCellBuffer to a
108/// block from the alternate pool and loads the routine into RAM; frees both
109/// when done.
111 u8 *savedCells;
112 TilemapConvertFn convertMap;
113 u32 savedBytes;
114
115 savedBytes = 0x8000;
116 savedCells = Runtime_BumpAllocateAlternatePool(savedBytes);
117 Iwram_CopyWords(savedCells, Ram_MapCellBuffer, savedBytes);
119 convertMap(((u8 *)gMapCellBuffer + 0x8000), Ram_MapCellBuffer, savedCells);
120 MemFree(convertMap);
121 MemFree(savedCells);
122}
123
124/// Copies one tile column of a block (metatile) into a BG map: its top and
125/// bottom tile entries, choosing the left or right half with tileHalf.
126static __inline__ void Map_CopyMetatileHalfColumn(u32 *cell, u8 *screenMap,
127 u32 screenRowOffset,
128 u32 screenColumnOffset,
129 u32 tileHalf) {
130 u16 *metatileEntry;
131 u8 *screenTile;
132 u32 index = ((*cell << 20) >> 18) + tileHalf;
133
134 metatileEntry = (u16 *)Ram_MapBlocks;
135 metatileEntry += index;
136 screenTile =
137 screenMap + (screenRowOffset + screenColumnOffset + tileHalf) * 2;
138 *(u16 *)screenTile = *metatileEntry;
139 metatileEntry = (u16 *)(Ram_MapBlocks + 4);
140 metatileEntry += index;
141 *(u16 *)(screenTile + 64) = *metatileEntry;
142}
143
144/// Copies a whole block (metatile) into a BG map: its top two tile entries
145/// and its bottom two, a map row (64 bytes) below.
146static __inline__ void Map_CopyMetatileToScreen(u32 *cell, u8 *screenMap,
147 u32 screenRowOffset,
148 u32 screenColumnOffset) {
149 u32 *metatileRows;
150 u8 *screenTile;
151 u32 index = (*cell << 20) >> 19;
152
153 metatileRows = (u32 *)Ram_MapBlocks;
154 metatileRows += index;
155 screenTile = screenMap + screenRowOffset * 2 + screenColumnOffset * 2;
156 *(u32 *)screenTile = *metatileRows;
157 metatileRows = (u32 *)(Ram_MapBlocks + 4);
158 metatileRows += index;
159 *(u32 *)(screenTile + 64) = *metatileRows;
160}
161
162/// A row of gMap_LayeredScenes: a layered map's resources, counted from
163/// ResourceId_Map001: its header, palette, three tile sheets and layer data.
166};
167
169
170/// One background layer's setup in a layered map's header: its origin, its
171/// parallax and drift, and where it wraps.
173 u8 x; ///< 8-pixel tiles
174 u8 y; ///< 8-pixel tiles
175 s8 scrollX; ///< sixteenths of the view's motion
176 s8 scrollY; ///< sixteenths of the view's motion
177 s8 speedX; ///< 1/16 pixels per frame
178 s8 speedY; ///< 1/16 pixels per frame
179 u8 periodX; ///< 8-pixel tiles
180 u8 periodY; ///< 8-pixel tiles
181};
182
183/// A layered map's header: the camera's bounds, the layers' priorities, tile
184/// bases and setup, and the offsets of its packed tiles, collision, tilemap,
185/// tile animation, blend script and marker list.
187 u8 origin[4]; ///< 8-pixel tiles
197 s32 markers; ///< the chests and Psynergy stones (Field_PlaceMapMarkers)
198};
199
200/// Loads layered scene index from gMap_LayeredScenes: its blocks, collision,
201/// cells, tile animations, blend script and marker list; sets up the three
202/// background layers' origins, parallax and wrap from the scene header; loads
203/// the palette and tile graphics unless FLAG_KEEP_LAYER_GRAPHICS says they are
204/// loaded; and starts the layer scrolling. Returns 2.
205///
206/// Called through Map_LoadLayeredSceneFar when a scene with a layered map
207/// starts (index is gGameState.map). Allocates and clears the map work in
208/// HEAP_SLOT_MAP; writes the BG palette (keeping the backdrop colour), char
209/// blocks 1 to 3, gMapLayerData, BG1CNT to BG3CNT, REG_MOSAIC, REG_BLDCNT and
210/// REG_DISPCNT; and registers Map_UpdateLayerScroll with the scheduler.
212 struct LayeredSceneEntry *sceneResources;
213 struct MapScrollWork *work;
214 struct LayeredSceneHeader *sceneHeader;
215 struct MapLayerScroll *mapLayer;
216 struct LayeredSceneLayer *layerSource;
217 s32 *viewX;
218 s32 *viewY;
219 s32 layerIndex;
220 u8 *graphicsBuffer;
221 s32 backdrop;
222 u8 *encodedData;
223 s32 displayFlags;
224
225 // Hide the map layers and sprites while their memory is replaced.
229 sceneResources = &gMap_LayeredScenes[index];
230 work = Runtime_AllocateBlock(HEAP_SLOT_MAP, sizeof(struct MapScrollWork));
231 Iwram_ClearWords(work, sizeof(struct MapScrollWork));
232 sceneHeader = (struct LayeredSceneHeader *)Resource_GetTableEntry(
233 sceneResources->resources[0] + (u32)&ResourceId_Map001);
234 // The header's offsets count from the header itself. The blocks are
235 // staged in the cell buffer, which the cell planes then overwrite.
236 encodedData = (u8 *)sceneHeader + sceneHeader->tiles;
238 Resource_DecodeType01(encodedData, Ram_MapCellBuffer + 1));
239 encodedData = (u8 *)sceneHeader + sceneHeader->collision;
241 encodedData = (u8 *)sceneHeader + sceneHeader->tilemap;
244 // The tile animation and blend scripts are optional (offset 0), and decode
245 // into the space after the shapes in Ram_MapCollision.
246 if (sceneHeader->animation != 0) {
247 encodedData = (u8 *)sceneHeader + sceneHeader->animation;
248 Resource_DecodeType01(encodedData, Ram_MapCollision + 0x1000);
250 }
251 if (sceneHeader->blend != 0) {
252 encodedData = (u8 *)sceneHeader + sceneHeader->blend;
253 Resource_DecodeType01(encodedData, Ram_MapCollision + 0x1e00);
255 }
256 // The marker list is not decoded: Field_PlaceMapMarkers reads it in place
257 // through this pointer (MarkerMap.markers).
258 work->script = (u8 *)sceneHeader + sceneHeader->markers;
259 // The header's bounds and origins are in 8-pixel tiles; << 19 makes them
260 // 16.16 pixels. The view starts at (0, 0) until the camera is centred.
261 work->minX = sceneHeader->origin[0] << 19;
262 work->minY = sceneHeader->origin[1] << 19;
263 work->maxX = sceneHeader->origin[2] << 19;
264 work->maxY = sceneHeader->origin[3] << 19;
265 viewX = &work->viewX;
266 *viewX = 0;
267 viewY = &work->viewY;
268 *viewY = 0;
269 work->enabled[0] = sceneHeader->priority[0];
270 work->enabled[1] = sceneHeader->priority[1];
271 work->enabled[2] = sceneHeader->priority[2];
272 mapLayer = work->layers;
273 layerSource = sceneHeader->layers;
274 for (layerIndex = 0; layerIndex < 3; layerIndex++) {
275 u32 x = layerSource->x;
276 u32 y = layerSource->y;
277 s32 scrollX;
278 s32 scrollY;
279 s32 baseX;
280 s32 baseY;
281
282 mapLayer->offsetX = baseX = x << 19;
283 mapLayer->offsetY = baseY = y << 19;
284 // Parallax and drift are signed sixteenths; * 4096 makes them 16.16.
285 scrollX = layerSource->scrollX * 4096;
286 scrollY = layerSource->scrollY * 4096;
287 mapLayer->scaleX = scrollX;
288 mapLayer->scaleY = scrollY;
289 mapLayer->speedX = layerSource->speedX * 4096;
290 mapLayer->speedY = layerSource->speedY * 4096;
291 mapLayer->maskX = layerSource->periodX;
292 mapLayer->maskY = layerSource->periodY;
293 mapLayer->phaseX = 0;
294 mapLayer->phaseY = 0;
295 // The layer's window starts at the cell under its origin tile (a cell is
296 // 2x2 tiles, 128 cells to a row).
297 mapLayer->cells =
298 (struct MapCell *)Ram_MapCellBuffer + (y >> 1) * 128 + (x >> 1);
299 mapLayer->x = Iwram_MulQ16(*viewX, scrollX) + baseX;
300 mapLayer->y = Iwram_MulQ16(*viewY, scrollY) + baseY;
301 layerSource++;
302 mapLayer++;
303 }
304 // Layers 0 to 2 show on BG3, BG2 and BG1, a layer only where its priority
305 // is not zero. Each BGCNT takes the priority as it is, its char block from
306 // the header and screen blocks 5, 6 and 7.
307 work->flags = DISPCNT_OBJ_ON;
308 if (work->enabled[0] != 0)
310 if (work->enabled[1] != 0)
311 work->flags |= DISPCNT_BG2_ON;
312 if (work->enabled[2] != 0)
313 work->flags |= DISPCNT_BG1_ON;
314 displayFlags = work->enabled[0] | BGCNT_CHAR_BASE(sceneHeader->charBase[0]) |
316 REG_BG3CNT = displayFlags;
317 Io_Write16(work->enabled[1] | BGCNT_CHAR_BASE(sceneHeader->charBase[1]) |
319 &REG_BG2CNT);
320 Io_Write16(work->enabled[2] | BGCNT_CHAR_BASE(sceneHeader->charBase[2]) |
322 &REG_BG1CNT);
323 // A set FLAG_KEEP_LAYER_GRAPHICS skips loading the graphics once, and is
324 // cleared.
327 } else {
328 // One 16 KB buffer takes each resource in turn: the palette (0x1c0
329 // bytes, 14 of the 16 BG palettes), the three 16 KB tile sheets, and
330 // last the layer data, which decodes straight to gMapLayerData. Without
331 // the memory, nothing is loaded.
332 graphicsBuffer = MemAlloc(0x4000);
333 if (graphicsBuffer != NULL) {
334 // Colour 0 of BG palette 0 is the backdrop; it survives the new palette.
335 backdrop = *(s16 *)BG_PLTT;
337 Resource_GetTableEntry(sceneResources->resources[1] +
339 graphicsBuffer);
340 *(s16 *)graphicsBuffer = backdrop;
341 /* FAKEMATCH(wrapper): these four copies call the fixed entry itself, past
342 * the IWRAM call layer; as Iwram_CopyWords, 103 of 349 instructions
343 * differ in tbs-en. */
344 Iwram_CopyWordsEntry((void *)BG_PLTT, graphicsBuffer, 0x1c0);
347 graphicsBuffer);
348 Iwram_CopyWordsEntry(BG_CHAR_BLOCK(1), graphicsBuffer, 0x4000);
351 graphicsBuffer);
352 Iwram_CopyWordsEntry(BG_CHAR_BLOCK(2), graphicsBuffer, 0x4000);
355 graphicsBuffer);
356 Iwram_CopyWordsEntry(BG_CHAR_BLOCK(3), graphicsBuffer, 0x4000);
360 MemFree(graphicsBuffer);
361 }
362 }
363 // Only BG0, the windows, is shown here; DisplayTransition_Start ORs
364 // work->flags into REG_DISPCNT when the scene fades in.
365 displayFlags = 0;
366 REG_MOSAIC = displayFlags;
367 REG_BLDCNT = displayFlags;
368 displayFlags = DISPCNT_BG0_ON | DISPCNT_OBJ_1D_MAP;
369 REG_DISPCNT = displayFlags;
370 // UB: the scheduler returns s32; call it through its declared type.
371#ifdef UBFIX
373#else
374 // Called through a cast as void (*)(void (*)(void), s32); called as its
375 // prototype, 2 of 349 instructions differ in tbs-en.
376 ((void (*)(void (*)(void), s32))Scheduler_AddOrUpdateCallback)(
377 Map_UpdateLayerScroll, 0xc85);
378#endif
379 return 2;
380}
381
382/// Centres the camera on the point the map follows (origin: x, height, z),
383/// or on (0, 0) when there is none, and scrolls the layers there. Called
384/// through Map_CenterOnFollowedPointFar when a layered scene starts, by the
385/// camera event commands after they move the camera, and by about 35 scene
386/// scripts through Engine_MapRedraw.
388 struct MapScrollWork *work = gMapWork[0];
389 s32 x;
390 s32 depth;
391 s32 height;
392 s32 *followedPosition;
393
394 followedPosition = work->origin;
395 x = 0;
396 height = 0;
397 depth = 0;
398 if (followedPosition != NULL) {
399 x = *followedPosition++;
400 height = *followedPosition++;
401 depth = *followedPosition;
402 }
403 Map_SetCameraCenter(x, depth - height);
405}
406
407/// Draws a row of 16 blocks (32 tiles) of a layer's cells into its BG map
408/// (screen block 5 + layer), starting at tile (tileX, tileY); the BG map
409/// wraps every 32 tiles. Called by Map_UpdateLayerScroll when a layer
410/// scrolls onto a new row of blocks.
411void Map_RenderMetatileRow(u32 layer, s32 tileX, s32 tileY) {
412 u8 *screenMap = BG_SCREEN_BLOCK(5) + (layer << 11);
413 u32 sourceRow = ((tileY / 2) & 0x7F) << 7;
414 u32 screenRowOffset = (tileY & 30) << 5;
415 u32 sourceColumn = (tileX / 2) & 0x7F;
416 u32 screenColumnOffset = tileX & 30;
417 u32 metatileIndex;
418
419 for (metatileIndex = 0; metatileIndex <= 15; metatileIndex++) {
420 u32 *sourceCell = (u32 *)Ram_MapCellBuffer;
421 u32 *metatileRows;
422 u8 *screenTile;
423 u32 metatileWordOffset;
424
425 sourceCell += sourceRow + sourceColumn;
426 metatileWordOffset = (*sourceCell << 20) >> 19;
427 metatileRows = (u32 *)Ram_MapBlocks;
428 metatileRows += metatileWordOffset;
429 screenTile = screenMap + (screenRowOffset + screenColumnOffset) * 2;
430 *(u32 *)screenTile = *metatileRows;
431 metatileRows = (u32 *)(Ram_MapBlocks + 4);
432 metatileRows += metatileWordOffset;
433 *(u32 *)(screenTile + 64) = *metatileRows;
434 sourceColumn = (sourceColumn + 1) & 0x7F;
435 screenColumnOffset = (screenColumnOffset + 2) & 30;
436 }
437}
438
439/// Draws a column of 11 blocks of a layer's cells, one tile wide, into its BG
440/// map, starting at tile (tileX, tileY). Called by Map_UpdateLayerScroll when
441/// a layer scrolls onto a new column of tiles; tileX's low bit picks the
442/// block's left or right half.
443void Map_RenderMetatileColumn(u32 layer, s32 tileX, s32 tileY) {
444 u8 *screenMap = BG_SCREEN_BLOCK(5) + (layer << 11);
445 u32 sourceRow = ((tileY / 2) & 0x7F) << 7;
446 u32 screenRowOffset = (tileY & 30) << 5;
447 u32 sourceColumn = (tileX / 2) & 0x7F;
448 u32 screenColumnOffset = tileX & 30;
449 u32 tileHalf = tileX & 1;
450 u32 metatileIndex;
451
452 for (metatileIndex = 0; metatileIndex <= 10; metatileIndex++) {
453 u32 *sourceCell = (u32 *)Ram_MapCellBuffer;
454
455 sourceCell += sourceRow + sourceColumn;
456 Map_CopyMetatileHalfColumn(sourceCell, screenMap, screenRowOffset,
457 screenColumnOffset, tileHalf);
458
459 sourceRow = (sourceRow + 128) & 0x3F80;
460 screenRowOffset = (screenRowOffset + 64) & 0x3C0;
461 }
462}
463
464/// Each frame on a layered map: centres the view on the point the map follows
465/// (origin), clamped to the map's bounds and shaken by any decaying screen
466/// shake; then scrolls each of the three layers by its parallax scale and
467/// automatic scroll (wrapping at its period), draws the block column or row
468/// that scrolls into view, and sets its BG scroll.
469///
470/// Registered with the scheduler by Map_LoadLayeredScene (priority 0xc85),
471/// and called by Map_CenterOnFollowedPoint. Sets work->viewX and viewY,
472/// decays work->shakeX and shakeY, advances each drifting layer's phase, and
473/// writes each layer's position and gBgScroll entry.
475 struct MapScrollWork *work;
476 struct MapLayerScroll *layer;
477 s32 *origin;
478 s32 x, y;
479 s32 minX, minY, maxX, maxY;
480 s32 baseX, baseY;
481 u32 layerIndex;
482
483 work = gMapWork[0];
484 origin = work->origin;
485 layer = work->layers;
486 if (origin == 0)
487 return;
488
489 // Height projects the followed point above its ground position.
490 baseX = *origin++ - FIELD_VIEW_FOCUS_X;
491 {
492 s32 height = *origin++;
493 baseY = *origin - height - FIELD_VIEW_FOCUS_Y;
494 }
495 // The bounds shrink by the shake so a shaken view stays on the map; the
496 // right and bottom bounds lose the 240x160 screen. A map smaller than
497 // that keeps its top left in view.
498 minX = work->minX + work->shakeX;
499 maxX = work->maxX - work->shakeX - FIELD_VIEW_WIDTH;
500 minY = work->minY + work->shakeY;
501 maxY = work->maxY - work->shakeY - FIELD_VIEW_HEIGHT;
502 if (minX > maxX)
503 maxX = minX;
504 if (minY > maxY)
505 maxY = minY;
506 CLAMP(baseX, minX, maxX);
507 CLAMP(baseY, minY, maxY);
508
509 // A shake offsets the view by the amplitude times the difference of two
510 // random fractions (between -1 and 1), then scales the amplitude by
511 // shakeDecay for the next frame.
512 if (work->shakeX != 0) {
513 s32 shakeRollA = Random16();
514 s32 shakeRollB = Random16();
515 s32 shakeAmplitude = work->shakeX;
516 baseX += Iwram_MulQ16(shakeAmplitude, shakeRollA - shakeRollB);
517 work->shakeX = Iwram_MulQ16(shakeAmplitude, work->shakeDecay);
518 }
519 if (work->shakeY != 0) {
520 s32 shakeRollA = Random16();
521 s32 shakeRollB = Random16();
522 s32 shakeAmplitude = work->shakeY;
523 baseY += Iwram_MulQ16(shakeAmplitude, shakeRollA - shakeRollB);
524 work->shakeY = Iwram_MulQ16(shakeAmplitude, work->shakeDecay);
525 }
526 work->viewX = baseX;
527 work->viewY = baseY;
528 for (layerIndex = 0; layerIndex < 3; layerIndex++, layer++) {
529 baseX = Iwram_MulQ16(work->viewX, layer->scaleX);
530 baseY = Iwram_MulQ16(work->viewY, layer->scaleY);
531 // A drifting layer wraps at its period: maskX and maskY are in 8-pixel
532 // tiles, and the mask keeps the pixel and fraction bits below them.
533 if (layer->speedX != 0) {
534 layer->phaseX += layer->speedX;
535 baseX = (baseX + layer->phaseX) & ((layer->maskX << 19) | 0x7ffff);
536 }
537 if (layer->speedY != 0) {
538 layer->phaseY += layer->speedY;
539 baseY = (baseY + layer->phaseY) & ((layer->maskY << 19) | 0x7ffff);
540 }
541 baseX += layer->offsetX;
542 baseY += layer->offsetY;
543 // x and y are in 8-pixel tiles. A new tile column (bit 19) or block row
544 // (bit 20, 16 pixels) has come into view: draw it at the leading edge,
545 // 30 tiles to the right or 20 below when scrolling that way.
546 x = baseX / 0x80000;
547 y = baseY / 0x80000;
548 if ((layer->x ^ baseX) & 0x80000) {
549 if (layer->x < baseX)
550 Map_RenderMetatileColumn(layerIndex, x + 30, y);
551 else
552 Map_RenderMetatileColumn(layerIndex, x, y);
553 }
554 if ((layer->y ^ baseY) & 0x100000) {
555 if (layer->y < baseY)
556 Map_RenderMetatileRow(layerIndex, x, y + 20);
557 else
558 Map_RenderMetatileRow(layerIndex, x, y);
559 }
560 // Layer 0 scrolls BG3, layer 2 BG1.
561 gBgScroll[3 - layerIndex].x = baseX >> 16;
562 gBgScroll[3 - layerIndex].y = baseY >> 16;
563 layer->x = baseX;
564 layer->y = baseY;
565 }
566}
567
568/// Centres the view on (x, y) in 16.16 pixels, clamped to the map's bounds,
569/// and redraws every enabled layer's BG map around it. Called by
570/// Map_CenterOnFollowedPoint. Sets work->viewX and viewY, and advances each
571/// drifting layer's phase by one frame.
573 u32 layerIndex;
574 u8 *screenMap;
575 struct MapScrollWork *work = gMapWork[0];
576 struct MapLayerScroll *layer = work->layers;
577
580 CLAMP(x, work->minX, work->maxX - FIELD_VIEW_WIDTH);
581 CLAMP(y, work->minY, work->maxY - FIELD_VIEW_HEIGHT);
582 work->viewX = x;
583 work->viewY = y;
584
585 for (layerIndex = 0; layerIndex < 3; layerIndex++) {
586 if (work->enabled[layerIndex]) {
587 u32 rows = 22;
588 u32 sourceRow, sourceColumn, screenRowOffset, screenColumnOffset,
589 metatileRow, metatileColumn;
590
591 x = Iwram_MulQ16(work->viewX, layer->scaleX);
592 y = Iwram_MulQ16(work->viewY, layer->scaleY);
593 if (layer->speedX) {
594 layer->phaseX += layer->speedX;
595 x = (x + layer->phaseX) & ((layer->maskX << 19) | 0x7ffff);
596 }
597 if (layer->speedY) {
598 layer->phaseY += layer->speedY;
599 y = (y + layer->phaseY) & ((layer->maskY << 19) | 0x7ffff);
600 // A layer drifting vertically gets its whole 32-row BG map, others
601 // the 22 rows (11 blocks) a 160-pixel screen can show.
602 // XXX: why only vertical drift fills the whole map; a scene with a
603 // vertically drifting layer and a look at its BG map would settle it.
604 rows = 32;
605 }
606 x += layer->offsetX;
607 y += layer->offsetY;
608 layer++;
609 x /= 0x80000;
610 y /= 0x80000;
611 screenMap = BG_SCREEN_BLOCK(5) + (layerIndex << 11);
612 sourceRow = ((y / 2) & 127) << 7;
613 screenRowOffset = (y & 30) << 5;
614 for (metatileRow = 0; metatileRow < rows / 2; metatileRow++) {
615 sourceColumn = (x / 2) & 127;
616 screenColumnOffset = x & 30;
617 for (metatileColumn = 0; metatileColumn <= 15; metatileColumn++) {
618 u32 *map = (u32 *)Ram_MapCellBuffer;
619 map += sourceRow + sourceColumn;
620 Map_CopyMetatileToScreen(map, screenMap, screenRowOffset,
621 screenColumnOffset);
622 sourceColumn = (sourceColumn + 1) & 127;
623 screenColumnOffset = (screenColumnOffset + 2) & 30;
624 }
625 sourceRow = (sourceRow + 128) & 0x3f80;
626 screenRowOffset = (screenRowOffset + 64) & 0x3c0;
627 }
628 }
629 }
630}
631
632/// The top left of a layer's visible area, in cells.
635};
636
637/// Copies the block numbers of a rectangle of cells from (srcX, srcY) to
638/// (dstX, dstY), width by height cells, keeping each destination's
639/// attributes, and redraws the copied cells that are on screen. It does what
640/// Map_CopyCellIndexRect does, with the destination before the size.
641///
642/// Called by Map_PlayMetatileCopySequence, and by about 40 scene scripts
643/// through Map_CopyMetatileIndicesRectFar (Engine_MapCopyCellsTo).
644void Map_CopyMetatileIndicesRect(s32 srcX, s32 srcY, u32 dstX, u32 dstY,
645 u32 width, u32 height) {
646 /* FAKEMATCH(temporary): the chains of temporaries set the registers and the
647 * schedule of the cell loop; as a plain body (the offset computed once, two
648 * word stores), 96 of 141 instructions differ in tbs-en. */
649 u32 *sourceCells = (u32 *)Ram_MapCellBuffer + (srcY * 128 + srcX);
650 u32 *destinationCells = (u32 *)Ram_MapCellBuffer + (dstY * 128 + dstX);
651 struct MapLayerScroll *layer = ((struct MapScrollWork *)gMapWork[0])->layers;
652 struct MapTilePos visibleLayers[3];
653 s32 i;
654 struct MapTilePos *visibleLayer = visibleLayers;
655 u32 y;
656 u32 x;
657
658 // The three layers' visible areas: their scroll positions in cells.
659 for (i = 2; i >= 0; i--) {
660 visibleLayer->x = layer->x >> 20;
661 visibleLayer->y = layer->y >> 20;
662 visibleLayer++;
663 layer++;
664 }
665 for (y = dstY; y < dstY + height; y++) {
666 for (x = dstX; x < dstX + width; x++) {
667 u32 sourceCell = *sourceCells++;
668 u32 metatileId = sourceCell & 0xfff;
669 u32 offset;
670 u32 tmp3;
671 u32 n;
672 u32 tmp6;
673 u32 tmp9;
674 u32 tmp12;
675 u32 tmp11;
676 u32 tmp13;
677 u32 tmp15;
678 tmp9 = *destinationCells;
679 tmp3 = tmp9 & -0x1000;
680 tmp12 = x & 15;
681 destinationCells[0] = metatileId | tmp3;
682 tmp6 = tmp12;
683 destinationCells++;
684 i = 0;
685 tmp15 = y & 15;
686 tmp3 = tmp15;
687 visibleLayer = visibleLayers;
688 tmp13 = tmp3 << 5;
689 tmp12 = tmp13;
690 n = tmp12;
691 n += tmp6;
692 tmp13 = 4 * n;
693 tmp11 = tmp13;
694 tmp6 = tmp11;
695 offset = tmp6;
696 // The first layer whose visible area (16x12 cells) holds the cell has
697 // the block written to its BG map too; offset is the cell's place in
698 // a 32x32 BG map, 0x800 bytes per layer from screen block 5.
699 for (; i < 3; i++) {
700 if (visibleLayer->x <= (s32)x && 16 + visibleLayer->x > (s32)x &&
701 visibleLayer->y <= (s32)y && visibleLayer->y + 12 > (s32)y) {
702 u32 screenAddress, metatileAddress;
703 u8 *screenTile, *metatileRows;
704
705 screenAddress = 0x06002800;
706 screenTile = (u8 *)screenAddress;
707 screenTile += offset;
708 tmp11 = metatileId * 8;
709 metatileAddress = (u32)Ram_MapBlocks;
710 metatileRows = (u8 *)metatileAddress;
711 metatileRows += tmp11;
712 *(u32 *)screenTile = *(u32 *)metatileRows;
713
714 metatileAddress = (u32)Ram_MapBlocks + 4;
715 metatileRows = (u8 *)metatileAddress;
716 metatileRows += tmp11;
717 screenAddress = 0x06002840;
718 screenTile = (u8 *)screenAddress;
719 screenTile += offset;
720 *(u32 *)screenTile = *(u32 *)metatileRows;
721 break;
722 }
723 offset += 0x800;
724 visibleLayer++;
725 }
726 }
727 sourceCells += 128 - width;
728 destinationCells += 128 - width;
729 }
730}
731
732/// One step of a map edit sequence: the rectangle of cells to copy from and the
733/// wait after it.
737} __attribute__((packed, aligned(2)));
738typedef char MapCopyCommandSize[(sizeof(struct MapCopyCommand) == 10) ? 1 : -1];
739
740/// Plays a map edit sequence (struct MapCopyCommand records, ended by a
741/// source of 0xffff): copies each record's rectangle of block numbers to
742/// (destinationX, destinationY) and waits its delay in frames. Doors and
743/// other changing scenery are drawn this way.
744///
745/// Called by about 30 scene scripts through Map_PlayMetatileCopySequenceFar
746/// (Engine_MapAnimateCells); it returns only when the sequence ends, so it
747/// blocks the script that calls it.
748void Map_PlayMetatileCopySequence(u16 *sequence, s32 destinationX,
749 u32 destinationY) {
750 struct MapCopyCommand *copyCommand = (struct MapCopyCommand *)sequence;
751 u32 sourceX = copyCommand->source;
752 u32 endMarker = 0xffff;
753 u32 firstSourceCopy = sourceX;
754
755 /* FAKEMATCH(dead): the updates that cancel out emit nothing but end CSE
756 * before the comparison, keeping its ip copy while source stays in r0;
757 * without them, 2 of 53 instructions differ in tbs-en. */
758 if (copyCommand) {
759 sourceX ^= firstSourceCopy;
760 sourceX ^= firstSourceCopy;
761 }
762 if (firstSourceCopy != endMarker) {
763 u32 endMarkerCopy = endMarker;
764 s16 *rectangleArgs = (s16 *)(sequence + 1);
765
766 while (1) {
767 s32 sourceY = rectangleArgs[0];
768 s32 width = rectangleArgs[1];
769 s32 height = rectangleArgs[2];
770 s32 delay = rectangleArgs[3];
771 rectangleArgs += 5;
772
773 Map_CopyMetatileIndicesRect(sourceX, (u16)sourceY, destinationX,
774 destinationY, (u16)width, (u16)height);
775 copyCommand++;
777 sourceX = copyCommand->source;
778 {
779 u32 nextSourceCopy = sourceX;
780
781 /* FAKEMATCH(barrier): the same ip copy after the wait, which CSE's copy
782 * swap or combine removes in every plain form tried; without the
783 * barrier, 2 of 53 instructions differ in tbs-en. */
784 __asm__("" : "+r"(nextSourceCopy));
785 if (nextSourceCopy == endMarkerCopy)
786 break;
787 }
788 }
789 }
790}
791
792// Map: copying rectangles of cells.
793
794#define MAP_CELLS ((u32 *)gMapCellBuffer)
795#define MAP_CELL_TILE_MASK 0x00000fff ///< the block (metatile) number
796#define MAP_CELL_ATTRIBUTE_MASK 0xfffff000 ///< the cell's attributes
797
798/// Copies a rectangle of cells (16x16 pixels each) as they are, from
799/// (srcX, srcY) to (dstX, dstY), width by height cells. Where a copied cell
800/// lies in a layer's visible area (16x12 cells), its block's 2x2 tiles go to
801/// that layer's BG map in VRAM too. Called by about 15 scene scripts through
802/// Map_CopyMetatileCellsRectFar (Engine_MapCopyCells).
804 s32 dstX, s32 dstY) {
805 s32 y = dstY;
806 u32 *sourceCells = (u32 *)Ram_MapCellBuffer + (srcY * 128 + srcX);
807 u32 *destinationCells = &((u32 *)Ram_MapCellBuffer)[y * 128 + dstX];
808 struct MapLayerScroll *layer = ((struct MapScrollWork *)*gMapWork)->layers;
809 struct MapTilePos visibleLayers[3];
810 s32 i;
811 struct MapTilePos *visibleLayer = visibleLayers;
812 s32 x;
813
814 // The three layers' visible areas: their scroll positions in cells.
815 i = 2;
816 while (i >= 0) {
817 s32 tmp5;
818
819 tmp5 = layer->x >> 20;
820 visibleLayer->x = tmp5;
821 tmp5 = (*layer).y;
822 visibleLayer->y = tmp5 >> 20;
823 visibleLayer++;
824 layer++;
825 i--;
826 }
827 if (y < dstY + height) {
828 do {
829 for (x = dstX; x < dstX + width; x++) {
830 u32 sourceCell = *sourceCells++;
831 u32 metatileId;
832 u32 offset;
833 u32 tmp3;
834 u32 *screenTile;
835 u32 n;
836 u32 *metatileRows;
837 u32 tmp6;
838 u32 tmp12;
839 u32 tmp13;
840
841 destinationCells[0] = sourceCell;
842 metatileId = sourceCell & 0xfff;
843 tmp12 = x & 15;
844 tmp6 = tmp12;
845 destinationCells += 1;
846 tmp3 = y & 15;
847 tmp13 = tmp3 << 5;
848 visibleLayer = visibleLayers;
849 tmp12 = tmp13;
850 n = tmp12;
851 n += tmp6;
852 tmp13 = n * 4;
853 i = 0;
854 tmp6 = tmp13;
855 offset = tmp6;
856 // In a layer's visible area, write its BG map in VRAM too (0x800
857 // bytes per layer).
858 for (; i < 3; i += 1) {
859 if (visibleLayer->x <= x && 16 + (*visibleLayer).x > x &&
860 visibleLayer->y <= y && visibleLayer->y + 12 > y) {
861 // The block's (8 bytes) top two tiles, and its bottom two 0x40
862 // bytes further on.
863 u32 *tmp;
864 u32 tmp2;
865 u32 tmp4;
866 u32 *tmp7;
867 u32 tmp10;
868 u32 tmp14;
869 u32 tmp16;
870 /* FAKEMATCH(temporary): the copy chain through tmp2 to tmp17 sets
871 * the registers and slots of the 36-byte frame; as two plain word
872 * stores, 65 of 137 instructions differ in tbs-en. */
873 u32 bytes = metatileId * 8;
874 u32 tmp8;
875 u32 tmp17;
876
877 metatileId = bytes / 8;
878 tmp = (u32 *)Ram_MapBlocks;
879 tmp8 = 0x06002800 + offset;
880 metatileRows = tmp;
881 tmp2 = tmp8;
882 tmp = (u32 *)tmp2;
883 screenTile = tmp;
884 metatileRows = (u32 *)((u8 *)metatileRows + bytes);
885 tmp16 = *metatileRows;
886 tmp14 = tmp16;
887 tmp17 = 0x06002840 + offset;
888 tmp10 = tmp14;
889 *screenTile = tmp10;
890 tmp7 = (u32 *)(Ram_MapBlocks + 4);
891 metatileRows = tmp7;
892 metatileRows = (u32 *)((u8 *)metatileRows + bytes);
893 tmp8 = tmp17;
894 tmp14 = tmp8;
895 tmp17 = metatileRows[0];
896 tmp16 = tmp17;
897 tmp10 = tmp16;
898 tmp4 = tmp10;
899 tmp2 = tmp4;
900 tmp4 = tmp14;
901 tmp7 = (u32 *)tmp4;
902 screenTile = tmp7;
903 *screenTile = tmp2;
904 break;
905 }
906 n = 0x800; // the next layer's BG map
907 offset += n;
908 visibleLayer++;
909 }
910 }
911 sourceCells += (128 - width);
912 destinationCells = 128 - width + destinationCells;
913 y++;
914 } while (y < dstY + height);
915 }
916}
917
918/// Copies only the attributes of a rectangle of cells, from (srcX, srcY) to
919/// (dstX, dstY), width by height cells, keeping each destination cell's
920/// block number. Nothing is redrawn: the attributes (flags, collision code and
921/// shape) do not show. Called by about 65 scene scripts through
922/// Map_CopyCellAttributeRectFar (Engine_MapCopyCellAttributes).
923void Map_CopyCellAttributeRect(s32 srcX, s32 srcY, s32 width, s32 height,
924 s32 dstX, s32 dstY) {
925 u32 *destinationCells = MAP_CELLS;
926 u32 *sourceCells = destinationCells;
927 u16 rowIndex;
928 u16 columnIndex;
929
930 destinationCells += (dstY << 7) + dstX;
931 sourceCells += (srcY << 7) + srcX;
932
933 for (rowIndex = 0; rowIndex < height; rowIndex++) {
934 u32 *destinationCell = destinationCells + (rowIndex << 7);
935 u32 *sourceCell = sourceCells + (rowIndex << 7);
936
937 for (columnIndex = 0; columnIndex < width; columnIndex++) {
938 *destinationCell = (*destinationCell & MAP_CELL_TILE_MASK) |
939 (*sourceCell++ & MAP_CELL_ATTRIBUTE_MASK);
940 destinationCell++;
941 }
942 }
943}
944
945/// Copies only the block numbers of a rectangle of cells, from (srcX, srcY)
946/// to (dstX, dstY), width by height cells, keeping each destination cell's
947/// attributes; cells in a visible area update the BG maps too. Called by
948/// seven scene scripts through Map_CopyCellIndexRectFar
949/// (Engine_MapCopyCellsLayered).
950void Map_CopyCellIndexRect(s32 srcX, s32 srcY, s32 width, s32 height, s32 dstX,
951 s32 dstY) {
952 /* FAKEMATCH(temporary): the word and index temporaries set the registers and
953 * the 36-byte frame; as a plain body (the offset computed once, two word
954 * stores), 94 of 142 instructions differ in tbs-en. */
955 s32 y;
956 u32 *sourceCells = (u32 *)Ram_MapCellBuffer + (srcY * 128 + srcX);
957 u32 *destinationCells = &((u32 *)Ram_MapCellBuffer)[dstY * 128 + dstX];
958 struct MapLayerScroll *layer = ((struct MapScrollWork *)*gMapWork)->layers;
959 struct MapTilePos visibleLayers[3];
960 s32 i;
961 struct MapTilePos *visibleLayer = visibleLayers;
962 s32 x;
963
964 // The three layers' visible areas: their scroll positions in cells.
965 i = 2;
966 while (i >= 0) {
967 s32 tmp5;
968
969 tmp5 = layer->x >> 20;
970 visibleLayer->x = tmp5;
971 tmp5 = (*layer).y;
972 visibleLayer->y = tmp5 >> 20;
973 visibleLayer++;
974 layer++;
975 i--;
976 }
977 y = dstY;
978 if (y < dstY + height) {
979 do {
980 for (x = dstX; x < dstX + width; x++) {
981 u32 sourceCell = *sourceCells++;
982 u32 metatileId;
983 u32 offset;
984 u32 tmp3;
985 u32 n;
986 u32 tmp6;
987 u32 tmp12;
988 u32 tmp13;
989
990 metatileId = sourceCell & MAP_CELL_TILE_MASK;
991 destinationCells[0] =
992 (destinationCells[0] & MAP_CELL_ATTRIBUTE_MASK) | metatileId;
993 tmp12 = x & 15;
994 tmp6 = tmp12;
995 destinationCells += 1;
996 i = 0;
997 tmp3 = y & 15;
998 tmp13 = tmp3 << 5;
999 visibleLayer = visibleLayers;
1000 tmp12 = tmp13;
1001 n = tmp12;
1002 n += tmp6;
1003 tmp13 = n * 4;
1004 tmp6 = tmp13;
1005 offset = tmp6;
1006 // In a layer's visible area, write its BG map in VRAM too (0x800
1007 // bytes per layer).
1008 for (; i < 3; i += 1) {
1009 if (visibleLayer->x <= x && 16 + (*visibleLayer).x > x &&
1010 visibleLayer->y <= y && visibleLayer->y + 12 > y) {
1011 // The block's (8 bytes) top two tiles, and its bottom two 0x40
1012 // bytes further on.
1013 u32 screenAddress, metatileAddress;
1014 u8 *screenTile, *metatileRows;
1015
1016 screenAddress = 0x06002800;
1017 screenTile = (u8 *)screenAddress;
1018 screenTile += offset;
1019 tmp13 = metatileId * 8;
1020 metatileAddress = (u32)Ram_MapBlocks;
1021 metatileRows = (u8 *)metatileAddress;
1022 metatileRows += tmp13;
1023 *(u32 *)screenTile = *(u32 *)metatileRows;
1024
1025 metatileAddress = (u32)Ram_MapBlocks + 4;
1026 metatileRows = (u8 *)metatileAddress;
1027 metatileRows += tmp13;
1028 screenAddress = 0x06002840;
1029 screenTile = (u8 *)screenAddress;
1030 screenTile += offset;
1031 *(u32 *)screenTile = *(u32 *)metatileRows;
1032 break;
1033 }
1034 n = 0x800; // the next layer's BG map
1035 offset += n;
1036 visibleLayer++;
1037 }
1038 }
1039 sourceCells = sourceCells + (128 - width);
1040 destinationCells = 128 - width + destinationCells;
1041 y++;
1042 } while (y < dstY + height);
1043 }
1044}
1045
1046/// Sets which of BG1-BG3 the map shows (bits 9-11 of its display flags, as in
1047/// REG_DISPCNT) from layerFlags, keeping its other flags. Called by Lunpa
1048/// Fortress's scene through Map_SetShownLayersFar
1049/// (Engine_MapSetWorkFlagBits9To11).
1050void Map_SetShownLayers(u32 layerFlags) {
1051 struct MapState *mapState = gMapWork[0];
1052 u32 mask = layerFlags & (DISPCNT_BG1_ON | DISPCNT_BG2_ON | DISPCNT_BG3_ON);
1053 u32 flags = mapState->flags;
1054
1055 // A halfword mask: as ~(...) without the cast, the mask in the literal pool
1056 // is 0xfffff1ff, where the ROM has 0xf1ff.
1057 flags =
1059 mapState->flags = flags;
1060}
1061
1062#undef MAP_CELLS
1063#undef MAP_CELL_TILE_MASK
1064#undef MAP_CELL_ATTRIBUTE_MASK
void Fade_FromBlack(s32 frames)
Fades in from black.
Definition fade.c:79
s32 GameFlag_TestFar(s32 flag)
void GameFlag_ClearBitFar(s32 flag)
u8 gRuntime_ByteRemapTable[]
What every part of the field object shares: its includes and the few names more than one part uses.
@ FIELD_VIEW_FOCUS_X
@ FIELD_VIEW_HEIGHT
@ FIELD_VIEW_FOCUS_Y
@ FIELD_VIEW_WIDTH
#define FLAG_KEEP_LAYER_GRAPHICS
Definition flags.h:95
void WaitFrames(s32 frames)
The game's frame loop: runs frames frames and returns.
Definition frame.c:97
struct EffectStep gMapCellBuffer[]
Map cells; battle effects reuse this as a particle array.
void * gMapWork[]
u8 Tile_ConvertMapCodeSize[]
const u8 Tile_ConvertMap[]
void * Runtime_BumpAllocateAlternatePool(s32 size)
As MemAlloc, but tries EWRAM first.
Definition heap.c:140
void * MemAlloc(s32 size)
Allocates size bytes (rounded up to words) with no slot, from IWRAM when they fit and EWRAM otherwise...
Definition heap.c:115
void * Runtime_AllocateBlock(s32 kind, s32 size)
As Runtime_AllocateHeapBlock, but tries EWRAM first, for blocks that need room more than speed: the b...
Definition heap.c:80
@ HEAP_SLOT_MAP
Definition heap_state.h:36
#define BGCNT_CHAR_BASE(block)
Definition io_reg.h:25
#define BG_SCREEN_BLOCK(n)
Definition io_reg.h:167
#define REG_BG3CNT
Definition io_reg.h:22
#define BG_CHAR_BLOCK(n)
Definition io_reg.h:166
@ DISPCNT_OBJ_ON
Definition io_reg.h:44
@ DISPCNT_WIN0_ON
Definition io_reg.h:45
@ DISPCNT_BG3_ON
Definition io_reg.h:43
@ DISPCNT_BG0_ON
Definition io_reg.h:40
@ DISPCNT_OBJ_1D_MAP
Definition io_reg.h:39
@ DISPCNT_BG2_ON
Definition io_reg.h:42
@ DISPCNT_BG1_ON
Definition io_reg.h:41
#define REG_DISPCNT
Definition io_reg.h:9
#define BGCNT_SCREEN_BASE(block)
Definition io_reg.h:28
#define REG_BG2CNT
Definition io_reg.h:21
#define BG_PLTT
Definition io_reg.h:157
#define REG_BLDCNT
Definition io_reg.h:119
#define REG_BG1CNT
Definition io_reg.h:20
#define REG_MOSAIC
Definition io_reg.h:118
#define Io_Write16(v, reg)
Writes a value to a 16-bit register or memory location.
Definition iowrite.h:14
static s32 Iwram_CopyWords(volatile void *destination, const volatile void *source, s32 size)
Definition iwram_call.h:85
#define Iwram_CopyWordsEntry
Definition iwram_call.h:46
#define Iwram_MulQ16(left, right)
Definition iwram_call.h:127
static s32 Iwram_ClearWords(void *destination, s32 size)
Definition iwram_call.h:55
#define CLAMP(v, low, high)
Keeps v within low to high, the low bound tested first.
Definition macros.h:23
u32 gMapBlocks[]
u8 gMapLayerData[]
void DisplayBlend_StartScript(u16 *script)
Starts a map's blend script, unless it is empty.
void MapAnimation_StartChannels(const u16 *script)
Starts the tile animation channels a map's animation script lists: each 0xfdNN marker starts channel ...
struct LayeredSceneEntry gMap_LayeredScenes[]
void Map_SetCameraCenter(s32 x, s32 y)
Centres the view on (x, y) in 16.16 pixels, clamped to the map's bounds, and redraws every enabled la...
Definition map_layers.c:572
void Tilemap_DecodeStagedBuffer(s32 size)
Unpacks the staged block data into gMapBlocks.
Definition map_layers.c:39
void Map_CopyMetatileCellsRect(s32 srcX, s32 srcY, s32 width, s32 height, s32 dstX, s32 dstY)
Copies a rectangle of cells (16x16 pixels each) as they are, from (srcX, srcY) to (dstX,...
Definition map_layers.c:803
char MapCopyCommandSize[(sizeof(struct MapCopyCommand)==10) ? 1 :-1]
Definition map_layers.c:738
static __inline__ void Map_CopyMetatileHalfColumn(u32 *cell, u8 *screenMap, u32 screenRowOffset, u32 screenColumnOffset, u32 tileHalf)
Copies one tile column of a block (metatile) into a BG map: its top and bottom tile entries,...
Definition map_layers.c:126
void Map_CopyCellIndexRect(s32 srcX, s32 srcY, s32 width, s32 height, s32 dstX, s32 dstY)
Copies only the block numbers of a rectangle of cells, from (srcX, srcY) to (dstX,...
Definition map_layers.c:950
static __inline__ void Map_CopyMetatileToScreen(u32 *cell, u8 *screenMap, u32 screenRowOffset, u32 screenColumnOffset)
Copies a whole block (metatile) into a BG map: its top two tile entries and its bottom two,...
Definition map_layers.c:146
void Tilemap_ConvertBuffer(void)
Converts the map's cells in place with Tile_ConvertMap, run from RAM, from a saved copy of the staged...
Definition map_layers.c:110
void Map_CopyMetatileIndicesRect(s32 srcX, s32 srcY, u32 dstX, u32 dstY, u32 width, u32 height)
Copies the block numbers of a rectangle of cells from (srcX, srcY) to (dstX, dstY),...
Definition map_layers.c:644
void Map_UpdateLayerScroll(void)
Each frame on a layered map: centres the view on the point the map follows (origin),...
Definition map_layers.c:474
void Map_RenderMetatileRow(u32 layer, s32 tileX, s32 tileY)
Draws a row of 16 blocks (32 tiles) of a layer's cells into its BG map (screen block 5 + layer),...
Definition map_layers.c:411
#define MAP_CELLS
Definition map_layers.c:794
#define MAP_CELL_ATTRIBUTE_MASK
the cell's attributes
Definition map_layers.c:796
void Map_RenderMetatileColumn(u32 layer, s32 tileX, s32 tileY)
Draws a column of 11 blocks of a layer's cells, one tile wide, into its BG map, starting at tile (til...
Definition map_layers.c:443
#define MAP_CELL_TILE_MASK
the block (metatile) number
Definition map_layers.c:795
void Map_PlayMetatileCopySequence(u16 *sequence, s32 destinationX, u32 destinationY)
Plays a map edit sequence (struct MapCopyCommand records, ended by a source of 0xffff): copies each r...
Definition map_layers.c:748
void Map_CenterOnFollowedPoint(void)
Centres the camera on the point the map follows (origin: x, height, z), or on (0, 0) when there is no...
Definition map_layers.c:387
void Map_SetShownLayers(u32 layerFlags)
Sets which of BG1-BG3 the map shows (bits 9-11 of its display flags, as in REG_DISPCNT) from layerFla...
s32 Map_LoadLayeredScene(s32 index)
Loads layered scene index from gMap_LayeredScenes: its blocks, collision, cells, tile animations,...
Definition map_layers.c:211
void Runtime_RemapBytesByTable(u8 *bytes, s32 byteCount)
Remaps byteCount bytes in place through gRuntime_ByteRemapTable.
Definition map_layers.c:10
void Map_CopyCellAttributeRect(s32 srcX, s32 srcY, s32 width, s32 height, s32 dstX, s32 dstY)
Copies only the attributes of a rectangle of cells, from (srcX, srcY) to (dstX, dstY),...
Definition map_layers.c:923
void(*) TilemapConvertFn(void *dst, const void *src, const void *saved)
Definition map_layers.c:80
UNUSED void Tilemap_NumberPlaceholderBlocks(void)
Gives each map cell whose block number is 0xfff (a placeholder) a number of its own,...
Definition map_layers.c:84
struct BgScroll gBgScroll[]
u32 Random16(void)
Advances the game's random number generator (the C library's classic linear congruential one),...
Definition math.c:10
void MemFree(void *buffer)
#define Ram_MapBlocks
Definition ram_buffer.h:12
#define Ram_MapCollision
Definition ram_buffer.h:13
#define Ram_MapCellBuffer
Definition ram_buffer.h:10
#define RamCode_Load(to, code, bytes)
Allocates a heap copy; release it with MemFree when finished.
Definition ramcode.h:15
char ResourceId_Map001
s32 Resource_DecodeType01(const void *source, void *destination)
Decodes a type-01 resource and returns its unpacked byte count.
Definition decompress.c:31
s32 Resource_DecodeType2(const void *source, void *destination)
Decodes a type-02 resource and returns its unpacked byte count.
Definition decompress.c:34
s32 Scheduler_AddOrUpdateCallback(SchedulerCallback callback, s32 order)
Schedules callback with order, or gives a task already running it the new order, and re-sorts the tab...
Definition scheduler.c:102
#define NULL
Definition bilibin.h:6
u16 y
pixels
Definition map_scroll.h:65
A row of gMap_LayeredScenes: a layered map's resources, counted from ResourceId_Map001: its header,...
Definition map_layers.c:164
A layered map's header: the camera's bounds, the layers' priorities, tile bases and setup,...
Definition map_layers.c:186
u8 origin[4]
8-pixel tiles
Definition map_layers.c:187
s32 markers
the chests and Psynergy stones (Field_PlaceMapMarkers)
Definition map_layers.c:197
struct LayeredSceneLayer layers[3]
Definition map_layers.c:191
One background layer's setup in a layered map's header: its origin, its parallax and drift,...
Definition map_layers.c:172
s8 scrollX
sixteenths of the view's motion
Definition map_layers.c:175
u8 x
8-pixel tiles
Definition map_layers.c:173
s8 speedY
1/16 pixels per frame
Definition map_layers.c:178
s8 speedX
1/16 pixels per frame
Definition map_layers.c:177
u8 y
8-pixel tiles
Definition map_layers.c:174
s8 scrollY
sixteenths of the view's motion
Definition map_layers.c:176
u8 periodX
8-pixel tiles
Definition map_layers.c:179
u8 periodY
8-pixel tiles
Definition map_layers.c:180
One cell of a map layer: its metatile and flags, its collision code and an attribute indexing the col...
Definition map.h:13
One step of a map edit sequence: the rectangle of cells to copy from and the wait after it.
Definition map_layers.c:734
One background layer of the field map: its scroll position, origin, parallax against the view,...
Definition map_scroll.h:14
s32 scaleY
16.16 fixed point, 0x10000 moves with the view
Definition map_scroll.h:17
s32 speedY
16.16 fixed-point pixels per frame
Definition map_scroll.h:18
u16 maskY
a drifting layer's wrap mask, in 8-pixel tiles
Definition map_scroll.h:20
s32 y
16.16 fixed-point pixels
Definition map_scroll.h:15
s32 phaseY
16.16 fixed-point pixels
Definition map_scroll.h:19
struct MapCell * cells
the layer's first cell in the map cell buffer
Definition map_scroll.h:21
s32 offsetY
16.16 fixed-point pixels
Definition map_scroll.h:16
The field map's work: the followed position, screen shake, tile animations, blend script,...
Definition map_scroll.h:27
s32 viewY
the view's top left, 16.16 fixed-point pixels
Definition map_scroll.h:40
struct MapLayerScroll layers[3]
BG3, BG2 and BG1, in that order.
Definition map_scroll.h:49
s32 shakeX
Screen shake amplitudes in 16.16 fixed-point pixels, and the 16.16 factor that scales them each frame...
Definition map_scroll.h:33
u16 flags
REG_DISPCNT bits: objects and the BG1 to BG3 shown.
Definition map_scroll.h:35
u8 * script
set from the layered scene's header; not read by name
Definition map_scroll.h:34
s32 * origin
The followed point, read as x, height and z in 16.16 fixed-point pixels; Camera_FollowActor points it...
Definition map_scroll.h:30
s32 maxY
16.16 fixed-point pixels
Definition map_scroll.h:41
u8 enabled[3]
Each layer's BG priority, written into its BGCNT; zero hides the layer.
Definition map_scroll.h:47
The map work in heap slot 8 (struct MapScrollWork), seen as its tile animation channels,...
Definition map.h:49
u16 flags
REG_DISPCNT bits; Map_SetShownLayers sets BG1 to BG3.
Definition map.h:51
The top left of a layer's visible area, in cells.
Definition map_layers.c:633
void * Resource_GetTableEntry(s32 index)
Returns the ROM address of resource index from the resource directory.
Definition system.c:150
signed int s32
Definition types.h:14
unsigned int u32
Definition types.h:15
signed char s8
Definition types.h:10
signed short s16
Definition types.h:12
unsigned short u16
Definition types.h:13
#define UNUSED
Definition types.h:22
unsigned char u8
Definition types.h:11