all repos — mgba @ 270ce0cba344a65f0e73d7071e3d07193491bf58

mGBA Game Boy Advance Emulator

src/gba/renderers/software-bg.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
 10void GBAVideoSoftwareRendererDrawBackgroundMode2(struct GBAVideoSoftwareRenderer* renderer, struct GBAVideoSoftwareBackground* background, int inY) {
 11	int sizeAdjusted = 0x8000 << background->size;
 12
 13	BACKGROUND_BITMAP_INIT;
 14
 15	uint32_t screenBase = background->screenBase;
 16	uint32_t charBase = background->charBase;
 17	uint8_t mapData;
 18	uint8_t tileData = 0;
 19
 20	int outX;
 21	uint32_t* pixel;
 22	for (outX = renderer->start, pixel = &renderer->row[outX]; outX < renderer->end; ++outX, ++pixel) {
 23		x += background->dx;
 24		y += background->dy;
 25
 26		if (!mosaicWait) {
 27			if (background->overflow) {
 28				localX = x & (sizeAdjusted - 1);
 29				localY = y & (sizeAdjusted - 1);
 30			} else if ((x | y) & ~(sizeAdjusted - 1)) {
 31				continue;
 32			} else {
 33				localX = x;
 34				localY = y;
 35			}
 36			mapData = ((uint8_t*)renderer->d.vram)[screenBase + (localX >> 11) + (((localY >> 7) & 0x7F0) << background->size)];
 37			tileData = ((uint8_t*)renderer->d.vram)[charBase + (mapData << 6) + ((localY & 0x700) >> 5) + ((localX & 0x700) >> 8)];
 38
 39			mosaicWait = mosaicH;
 40		} else {
 41			--mosaicWait;
 42		}
 43
 44		uint32_t current = *pixel;
 45		if (tileData && IS_WRITABLE(current)) {
 46			if (!objwinSlowPath) {
 47				_compositeBlendNoObjwin(renderer, pixel, palette[tileData] | flags, current);
 48			} else if (objwinForceEnable || !(current & FLAG_OBJWIN) == objwinOnly) {
 49				color_t* currentPalette = (current & FLAG_OBJWIN) ? objwinPalette : palette;
 50				unsigned mergedFlags = flags;
 51				if (current & FLAG_OBJWIN) {
 52					mergedFlags = objwinFlags;
 53				}
 54				_compositeBlendObjwin(renderer, pixel, currentPalette[tileData] | mergedFlags, current);
 55			}
 56		}
 57	}
 58}
 59
 60void GBAVideoSoftwareRendererDrawBackgroundMode3(struct GBAVideoSoftwareRenderer* renderer, struct GBAVideoSoftwareBackground* background, int inY) {
 61	BACKGROUND_BITMAP_INIT;
 62
 63	uint32_t color = renderer->normalPalette[0];
 64
 65	int outX;
 66	uint32_t* pixel;
 67	for (outX = renderer->start, pixel = &renderer->row[outX]; outX < renderer->end; ++outX, ++pixel) {
 68		BACKGROUND_BITMAP_ITERATE(VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS);
 69
 70		if (!mosaicWait) {
 71			LOAD_16(color, ((localX >> 8) + (localY >> 8) * VIDEO_HORIZONTAL_PIXELS) << 1, renderer->d.vram);
 72#ifndef COLOR_16_BIT
 73			unsigned color32;
 74			color32 = 0;
 75			color32 |= (color << 3) & 0xF8;
 76			color32 |= (color << 6) & 0xF800;
 77			color32 |= (color << 9) & 0xF80000;
 78			color = color32;
 79#elif COLOR_5_6_5
 80			uint16_t color16 = 0;
 81			color16 |= (color & 0x001F) << 11;
 82			color16 |= (color & 0x03E0) << 1;
 83			color16 |= (color & 0x7C00) >> 10;
 84			color = color16;
 85#endif
 86			mosaicWait = mosaicH;
 87		} else {
 88			--mosaicWait;
 89		}
 90
 91		uint32_t current = *pixel;
 92		if (!objwinSlowPath || !(current & FLAG_OBJWIN) != objwinOnly) {
 93			unsigned mergedFlags = flags;
 94			if (current & FLAG_OBJWIN) {
 95				mergedFlags = objwinFlags;
 96			}
 97			if (!variant) {
 98				_compositeBlendObjwin(renderer, pixel, color | mergedFlags, current);
 99			} else if (renderer->blendEffect == BLEND_BRIGHTEN) {
100				_compositeBlendObjwin(renderer, pixel, _brighten(color, renderer->bldy) | mergedFlags, current);
101			} else if (renderer->blendEffect == BLEND_DARKEN) {
102				_compositeBlendObjwin(renderer, pixel, _darken(color, renderer->bldy) | mergedFlags, current);
103			}
104		}
105	}
106}
107
108void GBAVideoSoftwareRendererDrawBackgroundMode4(struct GBAVideoSoftwareRenderer* renderer, struct GBAVideoSoftwareBackground* background, int inY) {
109	BACKGROUND_BITMAP_INIT;
110
111	uint16_t color = renderer->normalPalette[0];
112	uint32_t offset = 0;
113	if (GBARegisterDISPCNTIsFrameSelect(renderer->dispcnt)) {
114		offset = 0xA000;
115	}
116
117	int outX;
118	uint32_t* pixel;
119	for (outX = renderer->start, pixel = &renderer->row[outX]; outX < renderer->end; ++outX, ++pixel) {
120		BACKGROUND_BITMAP_ITERATE(VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS);
121
122		if (!mosaicWait) {
123			color = ((uint8_t*)renderer->d.vram)[offset + (localX >> 8) + (localY >> 8) * VIDEO_HORIZONTAL_PIXELS];
124
125			mosaicWait = mosaicH;
126		} else {
127			--mosaicWait;
128		}
129
130		uint32_t current = *pixel;
131		if (color && IS_WRITABLE(current)) {
132			if (!objwinSlowPath) {
133				_compositeBlendNoObjwin(renderer, pixel, palette[color] | flags, current);
134			} else if (objwinForceEnable || !(current & FLAG_OBJWIN) == objwinOnly) {
135				color_t* currentPalette = (current & FLAG_OBJWIN) ? objwinPalette : palette;
136				unsigned mergedFlags = flags;
137				if (current & FLAG_OBJWIN) {
138					mergedFlags = objwinFlags;
139				}
140				_compositeBlendObjwin(renderer, pixel, currentPalette[color] | mergedFlags, current);
141			}
142		}
143	}
144}
145
146void GBAVideoSoftwareRendererDrawBackgroundMode5(struct GBAVideoSoftwareRenderer* renderer, struct GBAVideoSoftwareBackground* background, int inY) {
147	BACKGROUND_BITMAP_INIT;
148
149	uint32_t color = renderer->normalPalette[0];
150	uint32_t offset = 0;
151	if (GBARegisterDISPCNTIsFrameSelect(renderer->dispcnt)) {
152		offset = 0xA000;
153	}
154
155	int outX;
156	uint32_t* pixel;
157	for (outX = renderer->start, pixel = &renderer->row[outX]; outX < renderer->end; ++outX, ++pixel) {
158		BACKGROUND_BITMAP_ITERATE(160, 128);
159
160		if (!mosaicWait) {
161			LOAD_16(color, offset + (localX >> 8) * 2 + (localY >> 8) * 320, renderer->d.vram);
162#ifndef COLOR_16_BIT
163			unsigned color32 = 0;
164			color32 |= (color << 9) & 0xF80000;
165			color32 |= (color << 3) & 0xF8;
166			color32 |= (color << 6) & 0xF800;
167			color = color32;
168#elif COLOR_5_6_5
169			uint16_t color16 = 0;
170			color16 |= (color & 0x001F) << 11;
171			color16 |= (color & 0x03E0) << 1;
172			color16 |= (color & 0x7C00) >> 10;
173			color = color16;
174#endif
175			mosaicWait = mosaicH;
176		} else {
177			--mosaicWait;
178		}
179
180		uint32_t current = *pixel;
181		if (!objwinSlowPath || !(current & FLAG_OBJWIN) != objwinOnly) {
182			unsigned mergedFlags = flags;
183			if (current & FLAG_OBJWIN) {
184				mergedFlags = objwinFlags;
185			}
186			if (!variant) {
187				_compositeBlendObjwin(renderer, pixel, color | mergedFlags, current);
188			} else if (renderer->blendEffect == BLEND_BRIGHTEN) {
189				_compositeBlendObjwin(renderer, pixel, _brighten(color, renderer->bldy) | mergedFlags, current);
190			} else if (renderer->blendEffect == BLEND_DARKEN) {
191				_compositeBlendObjwin(renderer, pixel, _darken(color, renderer->bldy) | mergedFlags, current);
192			}
193		}
194	}
195}