Skip to content

Commit b2d5e3a

Browse files
committed
Improve framebuffer rotation
1 parent 5695c15 commit b2d5e3a

2 files changed

Lines changed: 69 additions & 76 deletions

File tree

src/lcd_screen.cpp

Lines changed: 69 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,53 @@
2424
#include "no_bios.h"
2525
#include "no_power.h"
2626

27+
template<typename Pixel, GLYNX_Rotation rotation>
28+
static void ConvertAndRotateFrameBuffer(const u16* src, Pixel* dst,
29+
const Pixel* palette)
30+
{
31+
const int width = GLYNX_SCREEN_WIDTH;
32+
const int height = GLYNX_SCREEN_HEIGHT;
33+
const int pixel_count = width * height;
34+
35+
if (rotation == GLYNX_ROTATION_180)
36+
{
37+
for (int i = 0; i < pixel_count; ++i)
38+
dst[pixel_count - 1 - i] = palette[src[i] & 0x0FFF];
39+
return;
40+
}
41+
42+
for (int y = 0; y < height; ++y)
43+
{
44+
for (int x = 0; x < width; ++x)
45+
{
46+
const int src_index = y * width + x;
47+
const int dst_index = (rotation == GLYNX_ROTATION_LEFT)
48+
? (width - 1 - x) * height + y
49+
: x * height + (height - 1 - y);
50+
dst[dst_index] = palette[src[src_index] & 0x0FFF];
51+
}
52+
}
53+
}
54+
55+
template<typename Pixel>
56+
static void ConvertRotatedFrameBuffer(const u16* src, Pixel* dst,
57+
const Pixel* palette, GLYNX_Rotation rotation)
58+
{
59+
switch (rotation)
60+
{
61+
case GLYNX_ROTATION_LEFT:
62+
ConvertAndRotateFrameBuffer<Pixel, GLYNX_ROTATION_LEFT>(src, dst, palette);
63+
break;
64+
case GLYNX_ROTATION_180:
65+
ConvertAndRotateFrameBuffer<Pixel, GLYNX_ROTATION_180>(src, dst, palette);
66+
break;
67+
case GLYNX_ROTATION_RIGHT:
68+
default:
69+
ConvertAndRotateFrameBuffer<Pixel, GLYNX_ROTATION_RIGHT>(src, dst, palette);
70+
break;
71+
}
72+
}
73+
2774
LcdScreen::LcdScreen(Mikey* mikey, Memory* memory, Bus* bus)
2875
{
2976
m_mikey = mikey;
@@ -83,23 +130,37 @@ void LcdScreen::EndFrame(GLYNX_Rotation rotation)
83130
if (m_pixel_format == GLYNX_PIXEL_RGB565)
84131
{
85132
u16* dst = (u16*)m_frame_buffer;
86-
for (int i = 0; i < pixel_count; ++i)
133+
134+
if (rotation == GLYNX_ROTATION_DISABLED)
87135
{
88-
u16 color_12bit = src[i] & 0x0FFF;
89-
dst[i] = m_rgb565_palette[color_12bit];
136+
for (int i = 0; i < pixel_count; ++i)
137+
{
138+
u16 color_12bit = src[i] & 0x0FFF;
139+
dst[i] = m_rgb565_palette[color_12bit];
140+
}
141+
return;
90142
}
143+
144+
ConvertRotatedFrameBuffer(src, dst, m_rgb565_palette,
145+
rotation);
91146
}
92147
else
93148
{
94149
u32* dst = (u32*)m_frame_buffer;
95-
for (int i = 0; i < pixel_count; ++i)
150+
151+
if (rotation == GLYNX_ROTATION_DISABLED)
96152
{
97-
u16 color_12bit = src[i] & 0x0FFF;
98-
dst[i] = m_rgba8888_palette[color_12bit];
153+
for (int i = 0; i < pixel_count; ++i)
154+
{
155+
u16 color_12bit = src[i] & 0x0FFF;
156+
dst[i] = m_rgba8888_palette[color_12bit];
157+
}
158+
return;
99159
}
100-
}
101160

102-
RotateFrameBuffer(rotation);
161+
ConvertRotatedFrameBuffer(src, dst, m_rgba8888_palette,
162+
rotation);
163+
}
103164
}
104165

105166
void LcdScreen::RenderNoBiosScreen(u8* frame_buffer)
@@ -116,72 +177,6 @@ void LcdScreen::RenderNoPowerScreen(u8* frame_buffer)
116177
memcpy(frame_buffer, no_power_image, byte_count);
117178
}
118179

119-
void LcdScreen::RotateFrameBuffer(GLYNX_Rotation rotation)
120-
{
121-
if (rotation == GLYNX_ROTATION_DISABLED)
122-
return;
123-
124-
const int width = GLYNX_SCREEN_WIDTH;
125-
const int height = GLYNX_SCREEN_HEIGHT;
126-
const int pixel_count = width * height;
127-
128-
if (m_pixel_format == GLYNX_PIXEL_RGB565)
129-
{
130-
const u16* src = reinterpret_cast<const u16*>(m_frame_buffer);
131-
u16* dst = reinterpret_cast<u16*>(m_rotated_frame_buffer);
132-
133-
if (rotation == GLYNX_ROTATION_180)
134-
{
135-
for (int i = 0; i < pixel_count; i++)
136-
dst[pixel_count - 1 - i] = src[i];
137-
138-
memcpy(m_frame_buffer, m_rotated_frame_buffer, pixel_count * sizeof(u16));
139-
return;
140-
}
141-
142-
for (int y = 0; y < height; ++y)
143-
{
144-
for (int x = 0; x < width; ++x)
145-
{
146-
const int src_index = y * width + x;
147-
const int dst_index = (rotation == GLYNX_ROTATION_LEFT)
148-
? (width - 1 - x) * height + y
149-
: x * height + (height - 1 - y);
150-
dst[dst_index] = src[src_index];
151-
}
152-
}
153-
154-
memcpy(m_frame_buffer, m_rotated_frame_buffer, pixel_count * sizeof(u16));
155-
return;
156-
}
157-
158-
const u32* src = reinterpret_cast<const u32*>(m_frame_buffer);
159-
u32* dst = reinterpret_cast<u32*>(m_rotated_frame_buffer);
160-
161-
if (rotation == GLYNX_ROTATION_180)
162-
{
163-
for (int i = 0; i < pixel_count; i++)
164-
dst[pixel_count - 1 - i] = src[i];
165-
166-
memcpy(m_frame_buffer, m_rotated_frame_buffer, pixel_count * sizeof(u32));
167-
return;
168-
}
169-
170-
for (int y = 0; y < height; ++y)
171-
{
172-
for (int x = 0; x < width; ++x)
173-
{
174-
const int src_index = y * width + x;
175-
const int dst_index = (rotation == GLYNX_ROTATION_LEFT)
176-
? (width - 1 - x) * height + y
177-
: x * height + (height - 1 - y);
178-
dst[dst_index] = src[src_index];
179-
}
180-
}
181-
182-
memcpy(m_frame_buffer, m_rotated_frame_buffer, pixel_count * sizeof(u32));
183-
}
184-
185180
void LcdScreen::SaveState(std::ostream& stream)
186181
{
187182
StateSerializer serializer(stream);

src/lcd_screen.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,6 @@ class LcdScreen
8181
void InitPalettes();
8282
void DoDMA();
8383
void DrawPixel();
84-
void RotateFrameBuffer(GLYNX_Rotation rotation);
8584
void Serialize(StateSerializer& s);
8685

8786
private:
@@ -91,7 +90,6 @@ class LcdScreen
9190
u8* m_ram;
9291
u8* m_frame_buffer;
9392
u16 m_screen_buffer[GLYNX_SCREEN_WIDTH * GLYNX_SCREEN_HEIGHT] = {};
94-
u8 m_rotated_frame_buffer[GLYNX_SCREEN_WIDTH * GLYNX_SCREEN_HEIGHT * 4] = {};
9593
LcdScreen_State m_state;
9694
GLYNX_Pixel_Format m_pixel_format;
9795
u32 m_rgba8888_palette[4096] = {};

0 commit comments

Comments
 (0)