mirror of
https://github.com/TomHarte/CLK.git
synced 2025-01-13 22:32:03 +00:00
At last a genuine bug fixed: was nudging the wrong amount in intermediate shaders.
This commit is contained in:
parent
1142c86811
commit
9485ef2c8c
@ -77,6 +77,11 @@ class Atari2600Document: MachineDocument {
|
||||
atari2600.setState(true, forDigitalInput: input)
|
||||
}
|
||||
|
||||
if event.keyCode == 49 {
|
||||
self.runForNumberOfCycles(Int32(self.intendedCyclesPerSecond / 60))
|
||||
self.openGLView.drawViewOnlyIfDirty(true)
|
||||
}
|
||||
|
||||
if event.keyCode == 36 {
|
||||
atari2600.setResetLineEnabled(true)
|
||||
}
|
||||
|
@ -36,12 +36,16 @@ class MachineDocument: NSDocument, CSOpenGLViewDelegate, CSOpenGLViewResponderDe
|
||||
private var cycleCountError: Int64 = 0
|
||||
private var lastTime: CVTimeStamp?
|
||||
private var skippedFrames = 0
|
||||
// private var frameSkip = 0
|
||||
private var frameSkip = 0
|
||||
final func openGLView(view: CSOpenGLView, didUpdateToTime time: CVTimeStamp, didSkipPreviousUpdate : Bool, frequency : Double) {
|
||||
// frameSkip = frameSkip + 1
|
||||
// let modFrameSkip = frameSkip % 10
|
||||
// if modFrameSkip == 0 {
|
||||
// if modFrameSkip == 0 && frameSkip < 500 {
|
||||
// runForNumberOfCycles(Int32(intendedCyclesPerSecond / 60))
|
||||
// view.drawViewOnlyIfDirty(true)
|
||||
// view.performWithGLContext({ () -> Void in
|
||||
// self.openGLView(view, drawViewOnlyIfDirty: true)
|
||||
// })
|
||||
// }
|
||||
if let lastTime = lastTime {
|
||||
// perform (time passed in seconds) * (intended cycles per second), converting and
|
||||
|
@ -75,4 +75,6 @@
|
||||
|
||||
- (void)performWithGLContext:(nonnull dispatch_block_t)action;
|
||||
|
||||
- (void)drawViewOnlyIfDirty:(BOOL)onlyIfDirty;
|
||||
|
||||
@end
|
||||
|
@ -60,6 +60,7 @@ static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt
|
||||
BOOL didSkip = _hasSkipped;
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
|
||||
[self.delegate openGLView:self didUpdateToTime:time didSkipPreviousUpdate:didSkip frequency:frequency];
|
||||
[self drawViewOnlyIfDirty:YES];
|
||||
OSAtomicTestAndClear(processingMask, &_updateIsOngoing);
|
||||
});
|
||||
_hasSkipped = NO;
|
||||
@ -68,13 +69,13 @@ static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt
|
||||
// Draw the display only if a previous draw is not still ongoing. -drawViewOnlyIfDirty: is guaranteed
|
||||
// to be safe to call concurrently with -openGLView:updateToTime: so there's no need to worry about
|
||||
// the above interrupting the below or vice versa.
|
||||
if(!OSAtomicTestAndSet(drawingMask, &_updateIsOngoing))
|
||||
{
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
|
||||
[self drawViewOnlyIfDirty:YES];
|
||||
OSAtomicTestAndClear(drawingMask, &_updateIsOngoing);
|
||||
});
|
||||
}
|
||||
// if(!OSAtomicTestAndSet(drawingMask, &_updateIsOngoing))
|
||||
// {
|
||||
// dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
|
||||
// [self drawViewOnlyIfDirty:YES];
|
||||
// OSAtomicTestAndClear(drawingMask, &_updateIsOngoing);
|
||||
// });
|
||||
// }
|
||||
}
|
||||
|
||||
- (void)invalidate
|
||||
@ -134,7 +135,7 @@ static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt
|
||||
|
||||
- (void)drawRect:(NSRect)dirtyRect
|
||||
{
|
||||
[self drawViewOnlyIfDirty:NO];
|
||||
// [self drawViewOnlyIfDirty:NO];
|
||||
}
|
||||
|
||||
- (void)drawViewOnlyIfDirty:(BOOL)onlyIfDirty
|
||||
|
@ -141,7 +141,6 @@ void CRT::advance_cycles(unsigned int number_of_cycles, unsigned int source_divi
|
||||
// [0/1] 3
|
||||
if(next_run)
|
||||
{
|
||||
// printf("%d -> %d", tex_y, _openGL_output_builder->get_composite_output_y());
|
||||
source_input_position_x(0) = tex_x;
|
||||
source_input_position_y(0) = source_input_position_y(1) = tex_y;
|
||||
source_output_position_x(0) = (uint16_t)_horizontal_flywheel->get_current_output_position();
|
||||
@ -194,7 +193,6 @@ void CRT::advance_cycles(unsigned int number_of_cycles, unsigned int source_divi
|
||||
uint8_t *next_run = _openGL_output_builder->get_next_output_run();
|
||||
if(next_run)
|
||||
{
|
||||
// printf("{%d -> %0.2f}", _openGL_output_builder->get_composite_output_y(), (float)_vertical_flywheel->get_current_output_position() / (float)_vertical_flywheel->get_scan_period());
|
||||
output_position_x(0) = output_position_x(1) = output_position_x(2) = (uint16_t)_horizontal_flywheel->get_current_output_position();
|
||||
output_position_y(0) = output_position_y(1) = output_position_y(2) = (uint16_t)(_vertical_flywheel->get_current_output_position() / _vertical_flywheel_output_divider);
|
||||
output_tex_x(0) = output_tex_x(1) = output_tex_x(2) = (uint16_t)_horizontal_flywheel->get_current_output_position();
|
||||
@ -215,7 +213,6 @@ void CRT::advance_cycles(unsigned int number_of_cycles, unsigned int source_divi
|
||||
// if this is vertical retrace then adcance a field
|
||||
if(next_run_length == time_until_vertical_sync_event && next_vertical_sync_event == Flywheel::SyncEvent::EndRetrace)
|
||||
{
|
||||
// printf("\n!%d!\n", _openGL_output_builder->get_composite_output_y());
|
||||
// TODO: eliminate the below; it's to aid with debug, aligning the top of the
|
||||
// input buffer with the top of the incoming frame.
|
||||
_openGL_output_builder->release_source_buffer_write_pointer();
|
||||
@ -326,7 +323,6 @@ void CRT::output_data(unsigned int number_of_cycles, unsigned int source_divider
|
||||
{
|
||||
if(_openGL_output_builder->reduce_previous_allocation_to(number_of_cycles / source_divider))
|
||||
{
|
||||
// printf("[%d with %d]", (_vertical_flywheel->get_current_time() * 262) / _vertical_flywheel->get_scan_period(), _openGL_output_builder->get_last_write_y_posititon());
|
||||
Scan scan {
|
||||
.type = Scan::Type::Data,
|
||||
.number_of_cycles = number_of_cycles,
|
||||
|
@ -33,11 +33,11 @@ const GLsizei SourceVertexSize = 16;
|
||||
|
||||
// These constants hold the size of the rolling buffer to which the CPU writes
|
||||
const GLsizei InputBufferBuilderWidth = 2048;
|
||||
const GLsizei InputBufferBuilderHeight = 1024; // 1024
|
||||
const GLsizei InputBufferBuilderHeight = 512;
|
||||
|
||||
// This is the size of the intermediate buffers used during composite to RGB conversion
|
||||
const GLsizei IntermediateBufferWidth = 2048;
|
||||
const GLsizei IntermediateBufferHeight = 2048;
|
||||
const GLsizei IntermediateBufferHeight = 512;
|
||||
|
||||
// Some internal buffer sizes
|
||||
const GLsizeiptr OutputVertexBufferDataSize = 44928; // a multiple of 6 * OutputVertexSize
|
||||
|
@ -42,7 +42,7 @@ void CRTInputBufferBuilder::allocate_write_area(size_t required_length)
|
||||
|
||||
_write_x_position = _next_write_x_position + 1;
|
||||
_write_y_position = _next_write_y_position;
|
||||
// printf("#%d,%d#", _write_x_position, _write_y_position);
|
||||
// printf("#%d,%d#\n", _write_x_position, _write_y_position);
|
||||
_write_target_pointer = (_write_y_position * InputBufferBuilderWidth) + _write_x_position;
|
||||
_next_write_x_position += required_length + 2;
|
||||
}
|
||||
@ -53,6 +53,7 @@ void CRTInputBufferBuilder::release_write_pointer()
|
||||
if(_should_reset)
|
||||
{
|
||||
_next_write_x_position = _next_write_y_position = 0;
|
||||
// printf("#Reset!#\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -185,15 +185,6 @@ void OpenGLOutputBuilder::draw_frame(unsigned int output_width, unsigned int out
|
||||
int number_of_clearing_zones = getCircularRanges(_cleared_composite_output_y, _composite_src_output_y, IntermediateBufferHeight, 1, clearing_zones);
|
||||
int number_of_source_drawing_zones = getCircularRanges(_drawn_source_buffer_data_pointer, _source_buffer_data_pointer, SourceVertexBufferDataSize, 2*SourceVertexSize, source_drawing_zones);
|
||||
int number_of_output_drawing_zones = getCircularRanges(_drawn_output_buffer_data_pointer, _output_buffer_data_pointer, OutputVertexBufferDataSize, 6*OutputVertexSize, output_drawing_zones);
|
||||
|
||||
// for(int c = 0; c < number_of_output_drawing_zones; c++)
|
||||
// {
|
||||
// printf("\n(%d->%d)\n", output_drawing_zones[c*2], output_drawing_zones[c*2] + output_drawing_zones[c*2 + 1]);
|
||||
// }
|
||||
|
||||
// if(number_of_output_drawing_zones)
|
||||
// printf("\n\n");
|
||||
|
||||
uint16_t completed_texture_y = _buffer_builder->get_and_finalise_current_line();
|
||||
|
||||
_composite_src_output_y %= IntermediateBufferHeight;
|
||||
@ -315,8 +306,6 @@ void OpenGLOutputBuilder::draw_frame(unsigned int output_width, unsigned int out
|
||||
|
||||
if(number_of_output_drawing_zones)
|
||||
{
|
||||
// glClearColor(0.5, 0.5, 0.5, 1.0);
|
||||
// glClear(GL_COLOR_BUFFER_BIT);
|
||||
glEnable(GL_BLEND);
|
||||
|
||||
// Ensure we're back on the output framebuffer, drawing from the output array buffer
|
||||
@ -336,7 +325,6 @@ void OpenGLOutputBuilder::draw_frame(unsigned int output_width, unsigned int out
|
||||
{
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, output_drawing_zones[c*2] / OutputVertexSize, output_drawing_zones[c*2 + 1] / OutputVertexSize);
|
||||
}
|
||||
// glDrawArrays(GL_TRIANGLE_STRIP, 0, OutputVertexBufferDataSize / OutputVertexSize);
|
||||
}
|
||||
|
||||
// copy framebuffer to the intended place
|
||||
@ -346,7 +334,6 @@ void OpenGLOutputBuilder::draw_frame(unsigned int output_width, unsigned int out
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
framebuffer->draw((float)output_width / (float)output_height);
|
||||
// filteredYTexture->draw((float)output_width / (float)output_height);
|
||||
|
||||
// drawing commands having been issued, reclaim the array buffer pointer
|
||||
glBindBuffer(GL_ARRAY_BUFFER, output_array_buffer);
|
||||
|
@ -57,7 +57,7 @@ class OpenGLOutputBuilder {
|
||||
|
||||
// the run and input data buffers
|
||||
std::unique_ptr<CRTInputBufferBuilder> _buffer_builder;
|
||||
std::shared_ptr<std::mutex> _output_mutex;
|
||||
std::unique_ptr<std::mutex> _output_mutex;
|
||||
|
||||
// transient buffers indicating composite data not yet decoded
|
||||
uint16_t _composite_src_output_y, _cleared_composite_output_y;
|
||||
|
@ -78,7 +78,7 @@ std::unique_ptr<IntermediateShader> IntermediateShader::make_shader(const char *
|
||||
"phaseAndAmplitudeVarying.x = (phaseCyclesPerTick * (extendedOutputPosition.x - phaseTime) + phaseAndAmplitude.x) * 2.0 * 3.141592654;"
|
||||
"phaseAndAmplitudeVarying.y = 0.33;" // TODO: reinstate connection with phaseAndAmplitude
|
||||
|
||||
"vec2 eyePosition = 2.0*(extendedOutputPosition / outputTextureSize) - vec2(1.0) + vec2(0.5)/textureSize;"
|
||||
"vec2 eyePosition = 2.0*(extendedOutputPosition / outputTextureSize) - vec2(1.0) + vec2(0.5)/outputTextureSize;"
|
||||
"gl_Position = vec4(eyePosition, 0.0, 1.0);"
|
||||
"}", sampler_type, input_variable);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user