1818
1919static const size_t GAMEBOY_SCREEN_WIDTH = 160 ;
2020static const size_t GAMEBOY_SCREEN_HEIGHT = 144 ;
21+ static const size_t SCREEN_WIDTH = 320 ;
22+ static const size_t SCREEN_HEIGHT = 240 ;
2123
2224extern " 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