From 6dbd20ffdec45cab3bbfde8a079eb1b38e7ce5b6 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Tue, 5 Apr 2016 20:32:55 -0400 Subject: [PATCH] Expanded interface to rgb_sample to eliminate its need to make assumptions about globals, used expanded interface to compact Electron data to two pixels per byte. --- Machines/Electron/Electron.cpp | 64 ++++++++++++----------------- Outputs/CRT/Internals/CRTOpenGL.cpp | 5 ++- 2 files changed, 31 insertions(+), 38 deletions(-) diff --git a/Machines/Electron/Electron.cpp b/Machines/Electron/Electron.cpp index 75f160022..d96e0f151 100644 --- a/Machines/Electron/Electron.cpp +++ b/Machines/Electron/Electron.cpp @@ -59,10 +59,10 @@ void Machine::setup_output() { _crt = std::unique_ptr(new Outputs::CRT::CRT(crt_cycles_per_line, 8, Outputs::CRT::DisplayType::PAL50, 1)); _crt->set_rgb_sampling_function( - "vec4 rgb_sample(vec2 coordinate)" + "vec4 rgb_sample(usampler2D sampler, vec2 coordinate, vec2 icoordinate)" "{" - "uint texValue = texture(texID, coordinate).r;" - "return vec4(texValue & 4u, texValue & 2u, texValue & 1u, 1.0);" + "uint texValue = texture(sampler, coordinate).r;" + "return mix(vec4(texValue & 64u, texValue & 32u, texValue & 16u, 1.0), vec4(texValue & 4u, texValue & 2u, texValue & 1u, 1.0), int(icoordinate.x * 2) & 1);" "}"); _crt->set_output_device(Outputs::CRT::Monitor); @@ -523,9 +523,9 @@ inline void Machine::output_pixels(unsigned int number_of_cycles) unsigned int divider = 0; switch(_screen_mode) { - case 0: case 3: divider = 1; break; - case 1: case 4: case 6: divider = 2; break; - case 2: case 5: divider = 4; break; + case 0: case 3: divider = 2; break; + case 1: case 4: case 6: divider = 4; break; + case 2: case 5: divider = 8; break; } if(!_current_output_target || divider != _current_output_divider) @@ -535,6 +535,7 @@ inline void Machine::output_pixels(unsigned int number_of_cycles) _initial_output_target = _current_output_target = _crt->allocate_write_area(640 / _current_output_divider); } +#define pack(a, b) (uint8_t)((a << 4) | (b)) while(number_of_cycles--) { if(!(_current_pixel_column&1) || _screen_mode < 4) @@ -553,33 +554,27 @@ inline void Machine::output_pixels(unsigned int number_of_cycles) case 3: case 0: { - _current_output_target[0] = _palette[(_last_pixel_byte&0x80) >> 4]; - _current_output_target[1] = _palette[(_last_pixel_byte&0x40) >> 3]; - _current_output_target[2] = _palette[(_last_pixel_byte&0x20) >> 2]; - _current_output_target[3] = _palette[(_last_pixel_byte&0x10) >> 1]; - _current_output_target[4] = _palette[(_last_pixel_byte&0x08) >> 0]; - _current_output_target[5] = _palette[(_last_pixel_byte&0x04) << 1]; - _current_output_target[6] = _palette[(_last_pixel_byte&0x02) << 2]; - _current_output_target[7] = _palette[(_last_pixel_byte&0x01) << 3]; - _current_output_target += 8; + _current_output_target[0] = pack(_palette[(_last_pixel_byte&0x80) >> 4], _palette[(_last_pixel_byte&0x40) >> 3]); + _current_output_target[1] = pack(_palette[(_last_pixel_byte&0x20) >> 2], _palette[(_last_pixel_byte&0x10) >> 1]); + _current_output_target[2] = pack(_palette[(_last_pixel_byte&0x08) >> 0], _palette[(_last_pixel_byte&0x04) << 1]); + _current_output_target[3] = pack(_palette[(_last_pixel_byte&0x02) << 2], _palette[(_last_pixel_byte&0x01) << 3]); + _current_output_target += 4; } break; case 1: { - _current_output_target[0] = _palette[((_last_pixel_byte&0x80) >> 4) | ((_last_pixel_byte&0x08) >> 2)]; - _current_output_target[1] = _palette[((_last_pixel_byte&0x40) >> 3) | ((_last_pixel_byte&0x04) >> 1)]; - _current_output_target[2] = _palette[((_last_pixel_byte&0x20) >> 2) | ((_last_pixel_byte&0x02) >> 0)]; - _current_output_target[3] = _palette[((_last_pixel_byte&0x10) >> 1) | ((_last_pixel_byte&0x01) << 1)]; - _current_output_target += 4; + _current_output_target[0] = pack(_palette[((_last_pixel_byte&0x80) >> 4) | ((_last_pixel_byte&0x08) >> 2)], _palette[((_last_pixel_byte&0x40) >> 3) | ((_last_pixel_byte&0x04) >> 1)]); + _current_output_target[1] = pack(_palette[((_last_pixel_byte&0x20) >> 2) | ((_last_pixel_byte&0x02) >> 0)], _palette[((_last_pixel_byte&0x10) >> 1) | ((_last_pixel_byte&0x01) << 1)]); + _current_output_target += 2; } break; case 2: { - _current_output_target[0] = _palette[((_last_pixel_byte&0x80) >> 4) | ((_last_pixel_byte&0x20) >> 3) | ((_last_pixel_byte&0x08) >> 2) | ((_last_pixel_byte&0x02) >> 1)]; - _current_output_target[1] = _palette[((_last_pixel_byte&0x40) >> 3) | ((_last_pixel_byte&0x10) >> 2) | ((_last_pixel_byte&0x04) >> 1) | ((_last_pixel_byte&0x01) >> 0)]; - _current_output_target += 2; + _current_output_target[0] = pack( _palette[((_last_pixel_byte&0x80) >> 4) | ((_last_pixel_byte&0x20) >> 3) | ((_last_pixel_byte&0x08) >> 2) | ((_last_pixel_byte&0x02) >> 1)], + _palette[((_last_pixel_byte&0x40) >> 3) | ((_last_pixel_byte&0x10) >> 2) | ((_last_pixel_byte&0x04) >> 1) | ((_last_pixel_byte&0x01) >> 0)]); + _current_output_target += 1; } break; @@ -588,19 +583,15 @@ inline void Machine::output_pixels(unsigned int number_of_cycles) { if(_current_pixel_column&1) { - _current_output_target[0] = _palette[(_last_pixel_byte&0x08) >> 0]; - _current_output_target[1] = _palette[(_last_pixel_byte&0x04) << 1]; - _current_output_target[2] = _palette[(_last_pixel_byte&0x02) << 2]; - _current_output_target[3] = _palette[(_last_pixel_byte&0x01) << 3]; + _current_output_target[0] = pack(_palette[(_last_pixel_byte&0x08) >> 0], _palette[(_last_pixel_byte&0x04) << 1]); + _current_output_target[1] = pack(_palette[(_last_pixel_byte&0x02) << 2], _palette[(_last_pixel_byte&0x01) << 3]); } else { - _current_output_target[0] = _palette[(_last_pixel_byte&0x80) >> 4]; - _current_output_target[1] = _palette[(_last_pixel_byte&0x40) >> 3]; - _current_output_target[2] = _palette[(_last_pixel_byte&0x20) >> 2]; - _current_output_target[3] = _palette[(_last_pixel_byte&0x10) >> 1]; + _current_output_target[0] = pack(_palette[(_last_pixel_byte&0x80) >> 4], _palette[(_last_pixel_byte&0x40) >> 3]); + _current_output_target[1] = pack(_palette[(_last_pixel_byte&0x20) >> 2], _palette[(_last_pixel_byte&0x10) >> 1]); } - _current_output_target += 4; + _current_output_target += 2; } break; @@ -608,18 +599,17 @@ inline void Machine::output_pixels(unsigned int number_of_cycles) { if(_current_pixel_column&1) { - _current_output_target[0] = _palette[((_last_pixel_byte&0x20) >> 2) | ((_last_pixel_byte&0x02) >> 0)]; - _current_output_target[1] = _palette[((_last_pixel_byte&0x10) >> 1) | ((_last_pixel_byte&0x01) << 1)]; + _current_output_target[0] = pack(_palette[((_last_pixel_byte&0x20) >> 2) | ((_last_pixel_byte&0x02) >> 0)], _palette[((_last_pixel_byte&0x10) >> 1) | ((_last_pixel_byte&0x01) << 1)]); } else { - _current_output_target[0] = _palette[((_last_pixel_byte&0x80) >> 4) | ((_last_pixel_byte&0x08) >> 2)]; - _current_output_target[1] = _palette[((_last_pixel_byte&0x40) >> 3) | ((_last_pixel_byte&0x04) >> 1)]; + _current_output_target[0] = pack(_palette[((_last_pixel_byte&0x80) >> 4) | ((_last_pixel_byte&0x08) >> 2)], _palette[((_last_pixel_byte&0x40) >> 3) | ((_last_pixel_byte&0x04) >> 1)]); } - _current_output_target += 2; + _current_output_target += 1; } break; } +#undef pack _current_pixel_column++; } diff --git a/Outputs/CRT/Internals/CRTOpenGL.cpp b/Outputs/CRT/Internals/CRTOpenGL.cpp index 86075d479..bc9c90f44 100644 --- a/Outputs/CRT/Internals/CRTOpenGL.cpp +++ b/Outputs/CRT/Internals/CRTOpenGL.cpp @@ -361,6 +361,7 @@ char *OpenGLOutputBuilder::get_output_vertex_shader() "const float shadowMaskMultiple = 600;" "out vec2 srcCoordinatesVarying;" + "out vec2 iSrcCoordinatesVarying;" "void main(void)" "{" @@ -369,6 +370,7 @@ char *OpenGLOutputBuilder::get_output_vertex_shader() "shadowMaskCoordinates = position * vec2(shadowMaskMultiple, shadowMaskMultiple * 0.85057471264368);" "ivec2 textureSize = textureSize(texID, 0);" + "iSrcCoordinatesVarying = srcCoordinates;" "srcCoordinatesVarying = vec2(srcCoordinates.x / textureSize.x, (srcCoordinates.y + 0.5) / textureSize.y);" "float age = (timestampBase[int(lateralAndTimestampBaseOffset.y)] - timestamp) / ticksPerFrame;" "alpha = 10.0 * exp(-age * 2.0);" @@ -407,6 +409,7 @@ char *OpenGLOutputBuilder::get_output_fragment_shader(const char *sampling_funct "in float alpha;" "in vec2 shadowMaskCoordinates;" "in vec2 srcCoordinatesVarying;" + "in vec2 iSrcCoordinatesVarying;" "out vec4 fragColour;" @@ -417,7 +420,7 @@ char *OpenGLOutputBuilder::get_output_fragment_shader(const char *sampling_funct "void main(void)" "{" - "fragColour = rgb_sample(srcCoordinatesVarying) * vec4(1.0, 1.0, 1.0, alpha * sin(lateralVarying));" // + "fragColour = rgb_sample(texID, srcCoordinatesVarying, iSrcCoordinatesVarying) * vec4(1.0, 1.0, 1.0, alpha);" // * sin(lateralVarying) "}" , sampling_function); }