all repos — mgba @ f836a67863e66499c812c8d963d37ff56ad10638

mGBA Game Boy Advance Emulator

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