mirror of
https://github.com/TomHarte/CLK.git
synced 2024-07-07 08:28:57 +00:00
Formally gave the 2600 responsibility for providing the code that decodes one of the things it has put into a buffer into a composite sample.
This commit is contained in:
parent
ac8fc9a1a0
commit
80cf3d9301
@ -148,9 +148,22 @@ void Machine::get_output_pixel(uint8_t *pixel, int offset)
|
|||||||
|
|
||||||
// map that colour to separate Y and phase components
|
// map that colour to separate Y and phase components
|
||||||
pixel[0] = (outputColour << 4)&0xe0;
|
pixel[0] = (outputColour << 4)&0xe0;
|
||||||
pixel[1] = outputColour&0xf0;
|
pixel[1] = outputColour&0xf0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *Machine::get_signal_decoder()
|
||||||
|
{
|
||||||
|
return
|
||||||
|
"float sample(vec2 coordinate, float phase)\n"
|
||||||
|
"{\n"
|
||||||
|
"vec2 c = texture(texID, coordinate).rg;"
|
||||||
|
"float y = 0.1 + c.x * 0.91071428571429;\n"
|
||||||
|
"float aOffset = 6.283185308 * c.y;\n"
|
||||||
|
"return y + step(0.0625, c.y) * 0.1 * sin(phase + aOffset);\n"
|
||||||
|
"}";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// in imputing the knowledge that all we're dealing with is the rollover from 159 to 0,
|
// in imputing the knowledge that all we're dealing with is the rollover from 159 to 0,
|
||||||
// this is faster than the straightforward +1)%160 per profiling
|
// this is faster than the straightforward +1)%160 per profiling
|
||||||
#define increment_object_counter(c) _objectCounter[c] = (_objectCounter[c]+1)&~((158-_objectCounter[c]) >> 8)
|
#define increment_object_counter(c) _objectCounter[c] = (_objectCounter[c]+1)&~((158-_objectCounter[c]) >> 8)
|
||||||
|
@ -32,6 +32,8 @@ class Machine: public CPU6502::Processor<Machine> {
|
|||||||
|
|
||||||
Outputs::CRT *get_crt() { return _crt; }
|
Outputs::CRT *get_crt() { return _crt; }
|
||||||
|
|
||||||
|
const char *get_signal_decoder();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint8_t *_rom, *_romPages[4], _ram[128];
|
uint8_t *_rom, *_romPages[4], _ram[128];
|
||||||
size_t _rom_size;
|
size_t _rom_size;
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
@property (nonatomic, weak) CSCathodeRayView *view;
|
@property (nonatomic, weak) CSCathodeRayView *view;
|
||||||
|
|
||||||
- (void)runForNumberOfCycles:(int)cycles;
|
- (void)runForNumberOfCycles:(int)cycles;
|
||||||
- (void)setROM:(NSData *)rom;
|
- (void)setROM:(NSData * __nonnull)rom;
|
||||||
|
|
||||||
- (void)setState:(BOOL)state forDigitalInput:(Atari2600DigitalInput)digitalInput;
|
- (void)setState:(BOOL)state forDigitalInput:(Atari2600DigitalInput)digitalInput;
|
||||||
- (void)setResetLineEnabled:(BOOL)enabled;
|
- (void)setResetLineEnabled:(BOOL)enabled;
|
||||||
|
@ -93,6 +93,11 @@ typedef NS_ENUM(NSInteger, CSAtari2600RunningState) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)setView:(CSCathodeRayView *)view {
|
||||||
|
_view = view;
|
||||||
|
_view.signalDecoder = [NSString stringWithUTF8String:_atari2600.get_signal_decoder()];
|
||||||
|
}
|
||||||
|
|
||||||
- (instancetype)init {
|
- (instancetype)init {
|
||||||
self = [super init];
|
self = [super init];
|
||||||
|
|
||||||
|
@ -30,5 +30,6 @@
|
|||||||
- (void)invalidate;
|
- (void)invalidate;
|
||||||
|
|
||||||
- (BOOL)pushFrame:(CRTFrame * __nonnull)crtFrame;
|
- (BOOL)pushFrame:(CRTFrame * __nonnull)crtFrame;
|
||||||
|
- (void)setSignalDecoder:(NSString * __nonnull)signalDecoder;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
@import CoreVideo;
|
@import CoreVideo;
|
||||||
#import <OpenGL/gl3.h>
|
#import <OpenGL/gl3.h>
|
||||||
#import <OpenGL/gl3ext.h>
|
#import <OpenGL/gl3ext.h>
|
||||||
|
#import <libkern/OSAtomic.h>
|
||||||
|
|
||||||
|
|
||||||
@implementation CSCathodeRayView {
|
@implementation CSCathodeRayView {
|
||||||
@ -30,6 +31,10 @@
|
|||||||
CRTSize _textureSize;
|
CRTSize _textureSize;
|
||||||
|
|
||||||
CRTFrame *_crtFrame;
|
CRTFrame *_crtFrame;
|
||||||
|
|
||||||
|
NSString *_signalDecoder;
|
||||||
|
int32_t _signalDecoderGeneration;
|
||||||
|
int32_t _compiledSignalDecoderGeneration;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)prepareOpenGL
|
- (void)prepareOpenGL
|
||||||
@ -52,7 +57,6 @@
|
|||||||
// get the shader ready, set the clear colour
|
// get the shader ready, set the clear colour
|
||||||
[self.openGLContext makeCurrentContext];
|
[self.openGLContext makeCurrentContext];
|
||||||
glClearColor(0.0, 0.0, 0.0, 1.0);
|
glClearColor(0.0, 0.0, 0.0, 1.0);
|
||||||
[self prepareShader];
|
|
||||||
|
|
||||||
// Activate the display link
|
// Activate the display link
|
||||||
CVDisplayLinkStart(displayLink);
|
CVDisplayLinkStart(displayLink);
|
||||||
@ -172,8 +176,8 @@ static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt
|
|||||||
// the main job of the vertex shader is just to map from an input area of [0,1]x[0,1], with the origin in the
|
// the main job of the vertex shader is just to map from an input area of [0,1]x[0,1], with the origin in the
|
||||||
// top left to OpenGL's [-1,1]x[-1,1] with the origin in the lower left, and to convert input data coordinates
|
// top left to OpenGL's [-1,1]x[-1,1] with the origin in the lower left, and to convert input data coordinates
|
||||||
// from integral to floating point.
|
// from integral to floating point.
|
||||||
const char *vertexShader =
|
static NSString *const vertexShader =
|
||||||
"#version 150\n"
|
@"#version 150\n"
|
||||||
"\n"
|
"\n"
|
||||||
"in vec2 position;\n"
|
"in vec2 position;\n"
|
||||||
"in vec2 srcCoordinates;\n"
|
"in vec2 srcCoordinates;\n"
|
||||||
@ -201,8 +205,8 @@ const char *vertexShader =
|
|||||||
|
|
||||||
// TODO: this should be factored out and be per project
|
// TODO: this should be factored out and be per project
|
||||||
|
|
||||||
const char *fragmentShader =
|
static NSString *const fragmentShader =
|
||||||
"#version 150\n"
|
@"#version 150\n"
|
||||||
"\n"
|
"\n"
|
||||||
"in vec2 srcCoordinatesVarying[7];\n"
|
"in vec2 srcCoordinatesVarying[7];\n"
|
||||||
"in float lateralVarying;\n"
|
"in float lateralVarying;\n"
|
||||||
@ -212,13 +216,7 @@ const char *fragmentShader =
|
|||||||
"uniform sampler2D texID;\n"
|
"uniform sampler2D texID;\n"
|
||||||
"uniform float alpha;\n"
|
"uniform float alpha;\n"
|
||||||
"\n"
|
"\n"
|
||||||
"float sample(vec2 coordinate, float angle)\n"
|
"%@"
|
||||||
"{\n"
|
|
||||||
"vec2 c = texture(texID, coordinate).rg;"
|
|
||||||
"float y = 0.1 + c.x * 0.91071428571429;\n"
|
|
||||||
"float aOffset = 6.283185308 * c.y;\n"
|
|
||||||
"return y + step(0.0625, c.y) * 0.1 * sin(angle + aOffset);\n"
|
|
||||||
"}\n"
|
|
||||||
"\n"
|
"\n"
|
||||||
"void main(void)\n"
|
"void main(void)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
@ -230,12 +228,12 @@ const char *fragmentShader =
|
|||||||
"angles[1] = angle + vec4(2.5132741232, 5.6548667772, 0.6283185308, 0.0);\n"
|
"angles[1] = angle + vec4(2.5132741232, 5.6548667772, 0.6283185308, 0.0);\n"
|
||||||
"\n"
|
"\n"
|
||||||
"samples[0] = vec4("
|
"samples[0] = vec4("
|
||||||
" sample(srcCoordinatesVarying[0], angles[0].x),"
|
" sample(srcCoordinatesVarying[0], angles[0].x),"
|
||||||
" sample(srcCoordinatesVarying[1], angles[0].y),"
|
" sample(srcCoordinatesVarying[1], angles[0].y),"
|
||||||
" sample(srcCoordinatesVarying[2], angles[0].z),"
|
" sample(srcCoordinatesVarying[2], angles[0].z),"
|
||||||
" sample(srcCoordinatesVarying[3], angles[0].w));\n"
|
" sample(srcCoordinatesVarying[3], angles[0].w));\n"
|
||||||
"samples[1] = vec4("
|
"samples[1] = vec4("
|
||||||
" sample(srcCoordinatesVarying[4], angles[1].x),"
|
" sample(srcCoordinatesVarying[4], angles[1].x),"
|
||||||
" sample(srcCoordinatesVarying[5], angles[1].y),"
|
" sample(srcCoordinatesVarying[5], angles[1].y),"
|
||||||
" sample(srcCoordinatesVarying[6], angles[1].z),"
|
" sample(srcCoordinatesVarying[6], angles[1].z),"
|
||||||
" 1.0);\n"
|
" 1.0);\n"
|
||||||
@ -279,11 +277,27 @@ const char *fragmentShader =
|
|||||||
return shader;
|
return shader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)setSignalDecoder:(NSString * __nonnull)signalDecoder
|
||||||
|
{
|
||||||
|
_signalDecoder = [signalDecoder copy];
|
||||||
|
OSAtomicIncrement32(&_signalDecoderGeneration);
|
||||||
|
}
|
||||||
|
|
||||||
- (void)prepareShader
|
- (void)prepareShader
|
||||||
{
|
{
|
||||||
|
if(_shaderProgram)
|
||||||
|
{
|
||||||
|
glDeleteProgram(_shaderProgram);
|
||||||
|
glDeleteShader(_vertexShader);
|
||||||
|
glDeleteShader(_fragmentShader);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!_signalDecoder)
|
||||||
|
return;
|
||||||
|
|
||||||
_shaderProgram = glCreateProgram();
|
_shaderProgram = glCreateProgram();
|
||||||
_vertexShader = [self compileShader:vertexShader type:GL_VERTEX_SHADER];
|
_vertexShader = [self compileShader:[vertexShader UTF8String] type:GL_VERTEX_SHADER];
|
||||||
_fragmentShader = [self compileShader:fragmentShader type:GL_FRAGMENT_SHADER];
|
_fragmentShader = [self compileShader:[[NSString stringWithFormat:fragmentShader, _signalDecoder] UTF8String] type:GL_FRAGMENT_SHADER];
|
||||||
|
|
||||||
glAttachShader(_shaderProgram, _vertexShader);
|
glAttachShader(_shaderProgram, _vertexShader);
|
||||||
glAttachShader(_shaderProgram, _fragmentShader);
|
glAttachShader(_shaderProgram, _fragmentShader);
|
||||||
@ -334,6 +348,11 @@ const char *fragmentShader =
|
|||||||
[self.openGLContext makeCurrentContext];
|
[self.openGLContext makeCurrentContext];
|
||||||
CGLLockContext([[self openGLContext] CGLContextObj]);
|
CGLLockContext([[self openGLContext] CGLContextObj]);
|
||||||
|
|
||||||
|
while(!_shaderProgram || (_signalDecoderGeneration != _compiledSignalDecoderGeneration)) {
|
||||||
|
_compiledSignalDecoderGeneration = _signalDecoderGeneration;
|
||||||
|
[self prepareShader];
|
||||||
|
}
|
||||||
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
if (_crtFrame)
|
if (_crtFrame)
|
||||||
|
Loading…
Reference in New Issue
Block a user