src/gba/renderers/software-mode0.c (view raw)
1/* Copyright (c) 2013-2015 Jeffrey Pfau
2 *
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6#include "gba/renderers/software-private.h"
7
8#include <mgba/internal/gba/gba.h>
9
10#define BACKGROUND_TEXT_SELECT_CHARACTER \
11 localX = tileX * 8 + inX; \
12 xBase = localX & 0xF8; \
13 if (background->size & 1) { \
14 xBase += (localX & 0x100) << 5; \
15 } \
16 screenBase = background->screenBase + yBase + (xBase >> 2); \
17 uint16_t* screenBlock = renderer->d.vramBG[screenBase >> VRAM_BLOCK_OFFSET]; \
18 LOAD_16(mapData, screenBase & VRAM_BLOCK_MASK, screenBlock); \
19 localY = inY & 0x7; \
20 if (GBA_TEXT_MAP_VFLIP(mapData)) { \
21 localY = 7 - localY; \
22 }
23
24#define DRAW_BACKGROUND_MODE_0_TILE_SUFFIX_16(BLEND, OBJWIN) \
25 paletteData = GBA_TEXT_MAP_PALETTE(mapData) << 4; \
26 palette = &mainPalette[paletteData]; \
27 charBase = (background->charBase + (GBA_TEXT_MAP_TILE(mapData) << 5)) + (localY << 2); \
28 vram = renderer->d.vramBG[charBase >> VRAM_BLOCK_OFFSET]; \
29 if (LIKELY(vram)) { \
30 LOAD_32(tileData, charBase & VRAM_BLOCK_MASK, vram); \
31 if (!GBA_TEXT_MAP_HFLIP(mapData)) { \
32 tileData >>= 4 * mod8; \
33 for (; outX < end; ++outX, ++pixel) { \
34 BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN, 0); \
35 } \
36 } else { \
37 for (outX = end - 1; outX >= renderer->start; --outX) { \
38 uint32_t* pixel = &renderer->row[outX]; \
39 BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN, 0); \
40 } \
41 } \
42 }
43
44#define DRAW_BACKGROUND_MODE_0_TILE_PREFIX_16(BLEND, OBJWIN) \
45 charBase = (background->charBase + (GBA_TEXT_MAP_TILE(mapData) << 5)) + (localY << 2); \
46 vram = renderer->d.vramBG[charBase >> VRAM_BLOCK_OFFSET]; \
47 if (UNLIKELY(!vram)) { \
48 return; \
49 } \
50 LOAD_32(tileData, charBase & VRAM_BLOCK_MASK, vram); \
51 paletteData = GBA_TEXT_MAP_PALETTE(mapData) << 4; \
52 palette = &mainPalette[paletteData]; \
53 pixel = &renderer->row[outX]; \
54 if (!GBA_TEXT_MAP_HFLIP(mapData)) { \
55 if (outX < renderer->start) { \
56 tileData >>= 4 * (renderer->start - outX); \
57 outX = renderer->start; \
58 pixel = &renderer->row[outX]; \
59 } \
60 for (; outX < renderer->end; ++outX, ++pixel) { \
61 BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN, 0); \
62 } \
63 } else { \
64 tileData >>= 4 * (0x8 - mod8); \
65 int end = renderer->end - 8; \
66 if (end < -1) { \
67 end = -1; \
68 } \
69 outX = renderer->end - 1; \
70 pixel = &renderer->row[outX]; \
71 for (; outX > end; --outX, --pixel) { \
72 BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN, 0); \
73 } \
74 /* Needed for consistency checks */ \
75 if (VIDEO_CHECKS) { \
76 outX = renderer->end; \
77 pixel = &renderer->row[outX]; \
78 } \
79 }
80
81#define DRAW_BACKGROUND_MODE_0_MOSAIC_16(BLEND, OBJWIN) \
82 x = inX & 7; \
83 if (mosaicWait) { \
84 int baseX = x - (mosaicH - mosaicWait); \
85 if (baseX < 0) { \
86 int disturbX = (16 + baseX) >> 3; \
87 inX -= disturbX << 3; \
88 BACKGROUND_TEXT_SELECT_CHARACTER; \
89 baseX -= disturbX << 3; \
90 inX += disturbX << 3; \
91 } else { \
92 BACKGROUND_TEXT_SELECT_CHARACTER; \
93 } \
94 charBase = (background->charBase + (GBA_TEXT_MAP_TILE(mapData) << 5)) + (localY << 2); \
95 vram = renderer->d.vramBG[charBase >> VRAM_BLOCK_OFFSET]; \
96 if (UNLIKELY(!vram)) { \
97 carryData = 0; \
98 } else { \
99 paletteData = GBA_TEXT_MAP_PALETTE(mapData) << 4; \
100 palette = &mainPalette[paletteData]; \
101 LOAD_32(tileData, charBase & VRAM_BLOCK_MASK, vram); \
102 if (!GBA_TEXT_MAP_HFLIP(mapData)) { \
103 tileData >>= 4 * baseX; \
104 } else { \
105 tileData >>= 4 * (7 - baseX); \
106 } \
107 tileData &= 0xF; \
108 tileData |= tileData << 4; \
109 tileData |= tileData << 8; \
110 tileData |= tileData << 16; \
111 carryData = tileData; \
112 } \
113 } \
114 for (; length; ++tileX) { \
115 BACKGROUND_TEXT_SELECT_CHARACTER; \
116 charBase = (background->charBase + (GBA_TEXT_MAP_TILE(mapData) << 5)) + (localY << 2); \
117 vram = renderer->d.vramBG[charBase >> VRAM_BLOCK_OFFSET]; \
118 tileData = carryData; \
119 for (; x < 8 && length; ++x, --length) { \
120 if (!mosaicWait) { \
121 if (UNLIKELY(!vram)) { \
122 carryData = 0; \
123 } else { \
124 paletteData = GBA_TEXT_MAP_PALETTE(mapData) << 4; \
125 palette = &mainPalette[paletteData]; \
126 LOAD_32(tileData, charBase & VRAM_BLOCK_MASK, vram); \
127 if (!GBA_TEXT_MAP_HFLIP(mapData)) { \
128 tileData >>= x * 4; \
129 } else { \
130 tileData >>= (7 - x) * 4; \
131 } \
132 tileData &= 0xF; \
133 tileData |= tileData << 4; \
134 tileData |= tileData << 8; \
135 tileData |= tileData << 16; \
136 carryData = tileData; \
137 } \
138 mosaicWait = mosaicH; \
139 } \
140 --mosaicWait; \
141 BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN, 0); \
142 ++pixel; \
143 } \
144 x = 0; \
145 }
146
147#define DRAW_BACKGROUND_MODE_0_TILES_16(BLEND, OBJWIN) \
148 for (; tileX < tileEnd; ++tileX) { \
149 BACKGROUND_TEXT_SELECT_CHARACTER; \
150 paletteData = GBA_TEXT_MAP_PALETTE(mapData) << 4; \
151 palette = &mainPalette[paletteData]; \
152 charBase = (background->charBase + (GBA_TEXT_MAP_TILE(mapData) << 5)) + (localY << 2); \
153 vram = renderer->d.vramBG[charBase >> VRAM_BLOCK_OFFSET]; \
154 if (UNLIKELY(!vram)) { \
155 pixel += 8; \
156 continue; \
157 } \
158 LOAD_32(tileData, charBase & VRAM_BLOCK_MASK, vram); \
159 if (tileData) { \
160 if (!GBA_TEXT_MAP_HFLIP(mapData)) { \
161 BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN, 0); \
162 BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN, 1); \
163 BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN, 2); \
164 BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN, 3); \
165 BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN, 4); \
166 BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN, 5); \
167 BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN, 6); \
168 BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN, 7); \
169 } else { \
170 BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN, 7); \
171 BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN, 6); \
172 BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN, 5); \
173 BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN, 4); \
174 BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN, 3); \
175 BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN, 2); \
176 BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN, 1); \
177 BACKGROUND_DRAW_PIXEL_16(BLEND, OBJWIN, 0); \
178 } \
179 } \
180 pixel += 8; \
181 }
182
183#define DRAW_BACKGROUND_MODE_0_TILE_SUFFIX_256(BLEND, OBJWIN) \
184 charBase = (background->charBase + (GBA_TEXT_MAP_TILE(mapData) << 6)) + (localY << 3); \
185 vram = renderer->d.vramBG[charBase >> VRAM_BLOCK_OFFSET]; \
186 int end2 = end - 4; \
187 if (!GBA_TEXT_MAP_HFLIP(mapData)) { \
188 int shift = inX & 0x3; \
189 if (LIKELY(vram)) { \
190 if (end2 > outX) { \
191 LOAD_32(tileData, charBase & VRAM_BLOCK_MASK, vram); \
192 tileData >>= 8 * shift; \
193 shift = 0; \
194 for (; outX < end2; ++outX, ++pixel) { \
195 BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 0); \
196 } \
197 } \
198 } \
199 \
200 if (LIKELY(vram)) { \
201 LOAD_32(tileData, (charBase + 4) & VRAM_BLOCK_MASK, vram); \
202 tileData >>= 8 * shift; \
203 for (; outX < end; ++outX, ++pixel) { \
204 BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 0); \
205 } \
206 } \
207 } else { \
208 int start = outX; \
209 outX = end - 1; \
210 pixel = &renderer->row[outX]; \
211 if (LIKELY(vram)) { \
212 if (end2 > start) { \
213 LOAD_32(tileData, charBase & VRAM_BLOCK_MASK, vram); \
214 for (; outX >= end2; --outX, --pixel) { \
215 BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 0); \
216 } \
217 charBase += 4; \
218 } \
219 } \
220 \
221 if (LIKELY(vram)) { \
222 LOAD_32(tileData, charBase, vram); \
223 for (; outX >= renderer->start; --outX, --pixel) { \
224 BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 0); \
225 } \
226 } \
227 outX = end; \
228 pixel = &renderer->row[outX]; \
229 }
230
231#define DRAW_BACKGROUND_MODE_0_TILE_PREFIX_256(BLEND, OBJWIN) \
232 charBase = (background->charBase + (GBA_TEXT_MAP_TILE(mapData) << 6)) + (localY << 3); \
233 vram = renderer->d.vramBG[charBase >> VRAM_BLOCK_OFFSET]; \
234 if (UNLIKELY(!vram)) { \
235 return; \
236 } \
237 int end = mod8 - 4; \
238 pixel = &renderer->row[outX]; \
239 if (!GBA_TEXT_MAP_HFLIP(mapData)) { \
240 if (end > 0) { \
241 LOAD_32(tileData, charBase & VRAM_BLOCK_MASK, vram); \
242 for (; outX < renderer->end - end; ++outX, ++pixel) { \
243 BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 0); \
244 } \
245 charBase += 4; \
246 } \
247 \
248 LOAD_32(tileData, charBase & VRAM_BLOCK_MASK, vram); \
249 for (; outX < renderer->end; ++outX, ++pixel) { \
250 BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 0); \
251 } \
252 } else { \
253 int shift = (8 - mod8) & 0x3; \
254 int start = outX; \
255 outX = renderer->end - 1; \
256 pixel = &renderer->row[outX]; \
257 if (end > 0) { \
258 LOAD_32(tileData, charBase & VRAM_BLOCK_MASK, vram); \
259 tileData >>= 8 * shift; \
260 for (; outX >= start + 4; --outX, --pixel) { \
261 BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 0); \
262 } \
263 shift = 0; \
264 } \
265 \
266 LOAD_32(tileData, (charBase + 4) & VRAM_BLOCK_MASK, vram); \
267 tileData >>= 8 * shift; \
268 for (; outX >= start; --outX, --pixel) { \
269 BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 0); \
270 } \
271 /* Needed for consistency checks */ \
272 if (VIDEO_CHECKS) { \
273 outX = renderer->end; \
274 pixel = &renderer->row[outX]; \
275 } \
276 }
277
278#define DRAW_BACKGROUND_MODE_0_TILES_256(BLEND, OBJWIN) \
279 for (; tileX < tileEnd; ++tileX) { \
280 BACKGROUND_TEXT_SELECT_CHARACTER; \
281 charBase = (background->charBase + (GBA_TEXT_MAP_TILE(mapData) << 6)) + (localY << 3); \
282 vram = renderer->d.vramBG[charBase >> VRAM_BLOCK_OFFSET]; \
283 if (UNLIKELY(!vram)) { \
284 pixel += 8; \
285 continue; \
286 } \
287 if (!GBA_TEXT_MAP_HFLIP(mapData)) { \
288 LOAD_32(tileData, charBase & VRAM_BLOCK_MASK, vram); \
289 if (tileData) { \
290 BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 0); \
291 BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 1); \
292 BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 2); \
293 BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 3); \
294 } \
295 pixel += 4; \
296 LOAD_32(tileData, (charBase + 4) & VRAM_BLOCK_MASK, vram); \
297 if (tileData) { \
298 BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 0); \
299 BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 1); \
300 BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 2); \
301 BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 3); \
302 } \
303 pixel += 4; \
304 } else { \
305 LOAD_32(tileData, (charBase + 4) & VRAM_BLOCK_MASK, vram); \
306 if (tileData) { \
307 BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 3); \
308 BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 2); \
309 BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 1); \
310 BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 0); \
311 } \
312 pixel += 4; \
313 LOAD_32(tileData, charBase & VRAM_BLOCK_MASK, vram); \
314 if (tileData) { \
315 BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 3); \
316 BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 2); \
317 BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 1); \
318 BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 0); \
319 } \
320 pixel += 4; \
321 } \
322 }
323
324#define DRAW_BACKGROUND_MODE_0_MOSAIC_256(BLEND, OBJWIN) \
325 for (; tileX < tileEnd; ++tileX) { \
326 BACKGROUND_TEXT_SELECT_CHARACTER; \
327 charBase = (background->charBase + (GBA_TEXT_MAP_TILE(mapData) << 6)) + (localY << 3); \
328 vram = renderer->d.vramBG[charBase >> VRAM_BLOCK_OFFSET]; \
329 tileData = carryData; \
330 for (x = 0; x < 8; ++x) { \
331 if (!mosaicWait) { \
332 if (UNLIKELY(!vram)) { \
333 carryData = 0; \
334 } else { \
335 if (!GBA_TEXT_MAP_HFLIP(mapData)) { \
336 if (x >= 4) { \
337 LOAD_32(tileData, (charBase + 4) & VRAM_BLOCK_MASK, vram); \
338 tileData >>= (x - 4) * 8; \
339 } else { \
340 LOAD_32(tileData, charBase & VRAM_BLOCK_MASK, vram); \
341 tileData >>= x * 8; \
342 } \
343 } else { \
344 if (x >= 4) { \
345 LOAD_32(tileData, charBase & VRAM_BLOCK_MASK, vram); \
346 tileData >>= (7 - x) * 8; \
347 } else { \
348 LOAD_32(tileData, (charBase + 4) & VRAM_BLOCK_MASK, vram); \
349 tileData >>= (3 - x) * 8; \
350 } \
351 } \
352 tileData &= 0xFF; \
353 carryData = tileData; \
354 } \
355 mosaicWait = mosaicH; \
356 } \
357 tileData |= tileData << 8; \
358 --mosaicWait; \
359 BACKGROUND_DRAW_PIXEL_256(BLEND, OBJWIN, 0); \
360 ++pixel; \
361 } \
362 }
363
364#define DRAW_BACKGROUND_MODE_0(BPP, BLEND, OBJWIN) \
365 uint32_t* pixel = &renderer->row[outX]; \
366 if (background->mosaic && GBAMosaicControlGetBgH(renderer->mosaic)) { \
367 int mosaicH = GBAMosaicControlGetBgH(renderer->mosaic) + 1; \
368 int x; \
369 int mosaicWait = (mosaicH - outX + VIDEO_HORIZONTAL_PIXELS * mosaicH) % mosaicH; \
370 int carryData = 0; \
371 paletteData = 0; /* Quiets compiler warning */ \
372 DRAW_BACKGROUND_MODE_0_MOSAIC_ ## BPP (BLEND, OBJWIN) \
373 return; \
374 } \
375 \
376 if (inX & 0x7) { \
377 BACKGROUND_TEXT_SELECT_CHARACTER; \
378 \
379 int mod8 = inX & 0x7; \
380 int end = outX + 0x8 - mod8; \
381 if (end > renderer->end) { \
382 end = renderer->end; \
383 } \
384 if (UNLIKELY(end == outX)) { \
385 return; \
386 } \
387 if (UNLIKELY(end < outX)) { \
388 mLOG(GBA_VIDEO, FATAL, "Out of bounds background draw!"); \
389 return; \
390 } \
391 DRAW_BACKGROUND_MODE_0_TILE_SUFFIX_ ## BPP (BLEND, OBJWIN) \
392 outX = end; \
393 if (tileX < tileEnd) { \
394 ++tileX; \
395 } else if (VIDEO_CHECKS && UNLIKELY(tileX > tileEnd)) { \
396 mLOG(GBA_VIDEO, FATAL, "Invariant doesn't hold in background draw! tileX (%u) > tileEnd (%u)", tileX, tileEnd); \
397 return; \
398 } \
399 length -= end - renderer->start; \
400 } \
401 /*! TODO: Make sure these lines can be removed */ \
402 /*!*/ pixel = &renderer->row[outX]; \
403 outX += (tileEnd - tileX) * 8; \
404 /*!*/ if (VIDEO_CHECKS && UNLIKELY(outX > VIDEO_HORIZONTAL_PIXELS)) { \
405 /*!*/ mLOG(GBA_VIDEO, FATAL, "Out of bounds background draw would occur!"); \
406 /*!*/ return; \
407 /*!*/ } \
408 DRAW_BACKGROUND_MODE_0_TILES_ ## BPP (BLEND, OBJWIN) \
409 if (length & 0x7) { \
410 BACKGROUND_TEXT_SELECT_CHARACTER; \
411 \
412 int mod8 = length & 0x7; \
413 if (VIDEO_CHECKS && UNLIKELY(outX + mod8 != renderer->end)) { \
414 mLOG(GBA_VIDEO, FATAL, "Invariant doesn't hold in background draw!"); \
415 return; \
416 } \
417 DRAW_BACKGROUND_MODE_0_TILE_PREFIX_ ## BPP (BLEND, OBJWIN) \
418 } \
419 if (VIDEO_CHECKS && UNLIKELY(&renderer->row[outX] != pixel)) { \
420 mLOG(GBA_VIDEO, FATAL, "Background draw ended in the wrong place! Diff: %" PRIXPTR, &renderer->row[outX] - pixel); \
421 } \
422 if (VIDEO_CHECKS && UNLIKELY(outX > VIDEO_HORIZONTAL_PIXELS)) { \
423 mLOG(GBA_VIDEO, FATAL, "Out of bounds background draw occurred!"); \
424 return; \
425 }
426
427void GBAVideoSoftwareRendererDrawBackgroundMode0(struct GBAVideoSoftwareRenderer* renderer, struct GBAVideoSoftwareBackground* background, int y) {
428 int inX = renderer->start + background->x;
429 int length = renderer->end - renderer->start;
430 if (background->mosaic) {
431 int mosaicV = GBAMosaicControlGetBgV(renderer->mosaic) + 1;
432 y -= y % mosaicV;
433 }
434 int inY = y + background->y;
435 uint16_t mapData;
436
437 unsigned yBase = inY & 0xF8;
438 if (background->size == 2) {
439 yBase += inY & 0x100;
440 } else if (background->size == 3) {
441 yBase += (inY & 0x100) << 1;
442 }
443 yBase <<= 3;
444
445 int localX;
446 int localY;
447
448 unsigned xBase;
449
450 uint32_t flags = (background->priority << OFFSET_PRIORITY) | (background->index << OFFSET_INDEX) | FLAG_IS_BACKGROUND;
451 flags |= FLAG_TARGET_2 * background->target2;
452 int objwinFlags = FLAG_TARGET_1 * (background->target1 && renderer->blendEffect == BLEND_ALPHA && GBAWindowControlIsBlendEnable(renderer->objwin.packed));
453 objwinFlags |= flags;
454 flags |= FLAG_TARGET_1 * (background->target1 && renderer->blendEffect == BLEND_ALPHA && GBAWindowControlIsBlendEnable(renderer->currentWindow.packed));
455 if (renderer->blendEffect == BLEND_ALPHA && renderer->blda == 0x10 && renderer->bldb == 0) {
456 flags &= ~(FLAG_TARGET_1 | FLAG_TARGET_2);
457 objwinFlags &= ~(FLAG_TARGET_1 | FLAG_TARGET_2);
458 }
459
460 uint32_t screenBase;
461 uint32_t charBase;
462 int variant = background->target1 && GBAWindowControlIsBlendEnable(renderer->currentWindow.packed) && (renderer->blendEffect == BLEND_BRIGHTEN || renderer->blendEffect == BLEND_DARKEN);
463 color_t* mainPalette = renderer->normalPalette;
464 if (variant) {
465 mainPalette = renderer->variantPalette;
466 }
467 color_t* palette = mainPalette;
468 PREPARE_OBJWIN;
469
470 int outX = renderer->start;
471
472 uint32_t tileData;
473 uint32_t current;
474 int pixelData;
475 int paletteData;
476 int tileX = 0;
477 int tileEnd = ((length + inX) >> 3) - (inX >> 3);
478 uint16_t* vram = NULL;
479
480 if (!objwinSlowPath) {
481 if (!(flags & FLAG_TARGET_2)) {
482 if (!background->multipalette) {
483 DRAW_BACKGROUND_MODE_0(16, NoBlend, NO_OBJWIN);
484 } else {
485 DRAW_BACKGROUND_MODE_0(256, NoBlend, NO_OBJWIN);
486 }
487 } else {
488 if (!background->multipalette) {
489 DRAW_BACKGROUND_MODE_0(16, Blend, NO_OBJWIN);
490 } else {
491 DRAW_BACKGROUND_MODE_0(256, Blend, NO_OBJWIN);
492 }
493 }
494 } else {
495 if (!(flags & FLAG_TARGET_2)) {
496 if (!background->multipalette) {
497 DRAW_BACKGROUND_MODE_0(16, NoBlend, OBJWIN);
498 } else {
499 DRAW_BACKGROUND_MODE_0(256, NoBlend, OBJWIN);
500 }
501 } else {
502 if (!background->multipalette) {
503 DRAW_BACKGROUND_MODE_0(16, Blend, OBJWIN);
504 } else {
505 DRAW_BACKGROUND_MODE_0(256, Blend, OBJWIN);
506 }
507 }
508 }
509}