Skip to content

Commit 02f6ad7

Browse files
committed
refactored gbc video function to make it use defined variables instead of hardcoded numbers for clarity
1 parent 349abe5 commit 02f6ad7

File tree

1 file changed

+23
-18
lines changed

1 file changed

+23
-18
lines changed

components/gbc/src/gameboy.cpp

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818

1919
static const size_t GAMEBOY_SCREEN_WIDTH = 160;
2020
static const size_t GAMEBOY_SCREEN_HEIGHT = 144;
21+
static const size_t SCREEN_WIDTH = 320;
22+
static const size_t SCREEN_HEIGHT = 240;
2123

2224
extern "C" {
2325
#include <gnuboy/loader.h>
@@ -69,20 +71,24 @@ bool video_task(std::mutex &m, std::condition_variable& cv) {
6971
return false;
7072
}
7173

72-
static int vram_index = 0;
74+
static constexpr int num_lines_to_write = NUM_ROWS_IN_FRAME_BUFFER;
75+
static int vram_index = 0; // has to be static so that it persists between calls
7376
if (scaled || filled) {
74-
int x_offset = filled ? 0 : (320-266)/2;
75-
int y_offset = 0;
77+
// to fill the screen vertically we scale the y axis by 240/144, or 1.667
78+
// This will create an x offset for centering of either 0 (if we fill) or
79+
// (320-266)/2 = 27 if we scale. 266 is the width of the scaled screen (160*1.667)
80+
int x_offset = filled ? 0 : (SCREEN_WIDTH-267)/2;
7681
// since the screen is 320x240 and the gameboy screen is 160x144
7782
// we need to scale the gameboy by 240/144 to fit the screen
7883
// and by 320/160 to fill the screen
7984
float y_scale = 1.667f;
8085
float x_scale = scaled ? y_scale : 2.0f;
81-
int max_y = 240;
82-
int max_x = std::clamp((int)(x_scale * 160.0f), 0, 320);
86+
int max_y = SCREEN_HEIGHT;
87+
int max_x = std::clamp<int>(x_scale * 160.0f, 0, SCREEN_WIDTH);
8388

84-
static constexpr int num_lines_to_write = NUM_ROWS_IN_FRAME_BUFFER;
8589
for (int y=0; y<max_y; y+=num_lines_to_write) {
90+
// each iteration of the loop, we swap the vram index so that we can
91+
// write to the other buffer while the other one is being transmitted
8692
uint16_t* _buf = vram_index ? (uint16_t*)get_vram1() : (uint16_t*)get_vram0();
8793
vram_index = vram_index ? 0 : 1;
8894
int i = 0;
@@ -94,21 +100,20 @@ bool video_task(std::mutex &m, std::condition_variable& cv) {
94100
int source_y = (float)_y/y_scale;
95101
for (int x=0; x<max_x; x++) {
96102
int source_x = (float)x/x_scale;
97-
_buf[i*max_x + x] = _frame[source_y*160 + source_x];
103+
_buf[i*max_x + x] = _frame[source_y*GAMEBOY_SCREEN_WIDTH + source_x];
98104
}
99105
}
100106
lcd_write_frame(0 + x_offset, y, max_x, i, (uint8_t*)&_buf[0]);
101107
}
102108
} else {
103-
constexpr int x_offset = (320-160)/2;
104-
constexpr int y_offset = (240-144)/2;
105-
static constexpr int num_lines_to_write = NUM_ROWS_IN_FRAME_BUFFER;
106-
for (int y=0; y<144; y+= num_lines_to_write) {
109+
constexpr int x_offset = (SCREEN_WIDTH-GAMEBOY_SCREEN_WIDTH)/2;
110+
constexpr int y_offset = (SCREEN_HEIGHT-GAMEBOY_SCREEN_HEIGHT)/2;
111+
for (int y=0; y<GAMEBOY_SCREEN_HEIGHT; y+= num_lines_to_write) {
107112
uint16_t* _buf = vram_index ? (uint16_t*)get_vram1() : (uint16_t*)get_vram0();
108113
vram_index = vram_index ? 0 : 1;
109-
int num_lines = std::min(num_lines_to_write, 144-y);
110-
memcpy(_buf, &_frame[y*160], num_lines*160*2);
111-
lcd_write_frame(x_offset, y + y_offset, 160, num_lines, (uint8_t*)&_buf[0]);
114+
int num_lines = std::min<int>(num_lines_to_write, GAMEBOY_SCREEN_HEIGHT-y);
115+
memcpy(_buf, &_frame[y*GAMEBOY_SCREEN_WIDTH], num_lines*GAMEBOY_SCREEN_WIDTH*2);
116+
lcd_write_frame(x_offset, y + y_offset, GAMEBOY_SCREEN_WIDTH, num_lines, (uint8_t*)&_buf[0]);
112117
}
113118
}
114119
// we don't have to worry here since we know there was an item in the queue
@@ -129,7 +134,7 @@ bool run_to_vblank(std::mutex &m, std::condition_variable& cv) {
129134

130135
/* FIXME: R_LY >= 0; comparsion to zero can also be removed
131136
altogether, R_LY is always 0 at this point */
132-
while (R_LY > 0 && R_LY < 144)
137+
while (R_LY > 0 && R_LY < GAMEBOY_SCREEN_HEIGHT)
133138
{
134139
emu_step();
135140
}
@@ -152,7 +157,7 @@ bool run_to_vblank(std::mutex &m, std::condition_variable& cv) {
152157
currentAudioBufferPtr = audioBuffer[currentAudioBuffer];
153158
currentAudioSampleCount = pcm.pos;
154159

155-
audio_play_frame((uint8_t*)currentAudioBufferPtr, currentAudioSampleCount * 2);
160+
audio_play_frame((uint8_t*)currentAudioBufferPtr, currentAudioSampleCount*2);
156161

157162
// Swap buffers
158163
// currentAudioBuffer = currentAudioBuffer ? 0 : 1;
@@ -218,8 +223,8 @@ void init_gameboy(const std::string& rom_filename, uint8_t *romdata, size_t rom_
218223
audioBuffer[1] = (int32_t*)get_audio_buffer();
219224

220225
memset(&fb, 0, sizeof(fb));
221-
fb.w = 160;
222-
fb.h = 144;
226+
fb.w = GAMEBOY_SCREEN_WIDTH;
227+
fb.h = GAMEBOY_SCREEN_HEIGHT;
223228
fb.pelsize = 2;
224229
fb.pitch = fb.w * fb.pelsize;
225230
fb.indexed = 0;

0 commit comments

Comments
 (0)