1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-02-27 15:29:34 +00:00

Merge pull request #544 from TomHarte/MSXColours

Corrects composition-time over-saturation.
This commit is contained in:
Thomas Harte 2018-09-09 20:39:13 -04:00 committed by GitHub
commit 224b3163f2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 63 additions and 62 deletions

View File

@ -20,7 +20,7 @@ VideoBase::VideoBase(bool is_iie, std::function<void(Cycles)> &&target) :
crt_->set_composite_sampling_function(
"float composite_sample(usampler2D sampler, vec2 coordinate, vec2 icoordinate, float phase, float amplitude)"
"{"
"return clamp(texture(sampler, coordinate).r, 0.0, 0.7);"
"return clamp(texture(sampler, coordinate).r, 0.0, 1.0);"
"}");
// Show only the centre 75% of the TV frame.

View File

@ -31,7 +31,7 @@ class MOS6502InterruptTests: XCTestCase {
machine.setValue(0x4000, for: CSTestMachine6502Register.programCounter)
}
func testIRQLine() {
func testIRQLine() {
// run for six cycles; check that no interrupt has occurred
machine.runForNumber(ofCycles: 6)
XCTAssert(machine.value(for: .programCounter) == 0x4003, "No interrupt should have occurred with line low")
@ -46,9 +46,9 @@ class MOS6502InterruptTests: XCTestCase {
XCTAssert(machine.value(for: .programCounter) != 0x1234, "Interrupt routine should not yet have begun")
machine.runForNumber(ofCycles: 1)
XCTAssert(machine.value(for: .programCounter) == 0x1234, "Interrupt routine should just have begun")
}
}
func testIFlagSet() {
func testIFlagSet() {
// enable the interrupt line, run for eleven cycles to get past the CLIP and the following NOP and into the interrupt routine
machine.irqLine = true
machine.runForNumber(ofCycles: 11)
@ -57,7 +57,7 @@ class MOS6502InterruptTests: XCTestCase {
XCTAssert(machine.value(for: .flags) & 0x04 == 0x04, "Interrupt status flag should be set")
}
func testCLISEIFlagClear() {
func testCLISEIFlagClear() {
// set up an SEI as the second instruction, enable the IRQ line
machine.setValue(0x78, forAddress: 0x4001)
machine.irqLine = true

View File

@ -287,16 +287,16 @@ std::string final_path_component(const std::string &path) {
Executes @c command and returns its STDOUT.
*/
std::string system_get(const char *command) {
std::unique_ptr<FILE, decltype((pclose))> pipe(popen(command, "r"), pclose);
if(!pipe) return "";
std::unique_ptr<FILE, decltype((pclose))> pipe(popen(command, "r"), pclose);
if(!pipe) return "";
std::string result;
while(!feof(pipe.get())) {
while(!feof(pipe.get())) {
std::array<char, 256> buffer;
if (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr)
result += buffer.data();
}
return result;
if(fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr)
result += buffer.data();
}
return result;
}
}

View File

@ -240,10 +240,14 @@ std::unique_ptr<IntermediateShader> IntermediateShader::make_chroma_luma_separat
"texture(texID, inputPositionsVarying[5]).r,"
"texture(texID, inputPositionsVarying[6]).r"
");"
// calculate luminance as either the straight average of the samples, if a colour subcarrier
// was present, or else a weighted sample around the third sample if not.
"float luminance = mix(dot(samples, vec4(0.25)), dot(samples, vec4(0.0, 0.16, 0.66, 0.16)), step(phaseAndAmplitudeVarying.z, 0.0));"
// define chroma to be whatever was here, minus luma
"float chrominance = 0.5 * (samples.z - luminance) * phaseAndAmplitudeVarying.z;"
// scale luminance up to the range [0, 1)
"luminance /= (1.0 - abs(phaseAndAmplitudeVarying.y));"
// split choma colours here, as the most direct place, writing out

View File

@ -83,7 +83,7 @@ std::unique_ptr<OutputShader> OutputShader::make_shader(const char *fragment_met
"void main(void)"
"{"
"fragColour = vec4(pow(" << colour_expression << ", vec3(gamma)), 0.8);"//*cos(lateralVarying)
"fragColour = vec4(pow(" << colour_expression << ", vec3(gamma)), 0.64);"//*cos(lateralVarying)
"}";
return std::unique_ptr<OutputShader>(new OutputShader(vertex_shader.str(), fragment_shader.str(), {

View File

@ -239,17 +239,16 @@ void Shader::set_uniform_matrix(const std::string &name, GLint size, bool transp
void Shader::set_uniform_matrix(const std::string &name, GLint size, GLsizei count, bool transpose, const GLfloat *values) {
std::size_t number_of_values = static_cast<std::size_t>(count) * static_cast<std::size_t>(size) * static_cast<std::size_t>(size);
GLfloat *values_copy = new GLfloat[number_of_values];
std::memcpy(values_copy, values, sizeof(*values) * number_of_values);
std::vector<GLfloat> values_copy(number_of_values);
std::memcpy(values_copy.data(), values, sizeof(*values) * number_of_values);
enqueue_function([name, size, count, transpose, values_copy, this] {
GLboolean glTranspose = transpose ? GL_TRUE : GL_FALSE;
switch(size) {
case 2: glUniformMatrix2fv(location(), count, glTranspose, values_copy); break;
case 3: glUniformMatrix3fv(location(), count, glTranspose, values_copy); break;
case 4: glUniformMatrix4fv(location(), count, glTranspose, values_copy); break;
case 2: glUniformMatrix2fv(location(), count, glTranspose, values_copy.data()); break;
case 3: glUniformMatrix3fv(location(), count, glTranspose, values_copy.data()); break;
case 4: glUniformMatrix4fv(location(), count, glTranspose, values_copy.data()); break;
}
delete[] values_copy;
});
}

View File

@ -179,7 +179,7 @@ void NIB::set_tracks(const std::map<Track::Address, std::shared_ptr<Track>> &tra
// Lock the file and spool out.
std::lock_guard<std::mutex> lock_guard(file_.get_file_access_mutex());
for(const auto &track: tracks_by_address) {
file_.seek(file_offset(track.first), SEEK_SET);
file_.write(track.second);
file_.seek(file_offset(track.first), SEEK_SET);
file_.write(track.second);
}
}

View File

@ -42,55 +42,55 @@ FileHolder::FileHolder(const std::string &file_name, FileMode ideal_mode)
}
uint32_t FileHolder::get32le() {
uint32_t result = static_cast<uint32_t>(std::fgetc(file_));
result |= static_cast<uint32_t>(std::fgetc(file_)) << 8;
result |= static_cast<uint32_t>(std::fgetc(file_)) << 16;
result |= static_cast<uint32_t>(std::fgetc(file_)) << 24;
uint32_t result = static_cast<uint32_t>(std::fgetc(file_));
result |= static_cast<uint32_t>(std::fgetc(file_)) << 8;
result |= static_cast<uint32_t>(std::fgetc(file_)) << 16;
result |= static_cast<uint32_t>(std::fgetc(file_)) << 24;
return result;
return result;
}
uint32_t FileHolder::get32be() {
uint32_t result = static_cast<uint32_t>(std::fgetc(file_)) << 24;
result |= static_cast<uint32_t>(std::fgetc(file_)) << 16;
result |= static_cast<uint32_t>(std::fgetc(file_)) << 8;
result |= static_cast<uint32_t>(std::fgetc(file_));
uint32_t result = static_cast<uint32_t>(std::fgetc(file_)) << 24;
result |= static_cast<uint32_t>(std::fgetc(file_)) << 16;
result |= static_cast<uint32_t>(std::fgetc(file_)) << 8;
result |= static_cast<uint32_t>(std::fgetc(file_));
return result;
return result;
}
uint32_t FileHolder::get24le() {
uint32_t result = static_cast<uint32_t>(std::fgetc(file_));
result |= static_cast<uint32_t>(std::fgetc(file_)) << 8;
result |= static_cast<uint32_t>(std::fgetc(file_)) << 16;
uint32_t result = static_cast<uint32_t>(std::fgetc(file_));
result |= static_cast<uint32_t>(std::fgetc(file_)) << 8;
result |= static_cast<uint32_t>(std::fgetc(file_)) << 16;
return result;
return result;
}
uint32_t FileHolder::get24be() {
uint32_t result = static_cast<uint32_t>(std::fgetc(file_)) << 16;
result |= static_cast<uint32_t>(std::fgetc(file_)) << 8;
result |= static_cast<uint32_t>(std::fgetc(file_));
uint32_t result = static_cast<uint32_t>(std::fgetc(file_)) << 16;
result |= static_cast<uint32_t>(std::fgetc(file_)) << 8;
result |= static_cast<uint32_t>(std::fgetc(file_));
return result;
return result;
}
uint16_t FileHolder::get16le() {
uint16_t result = static_cast<uint16_t>(std::fgetc(file_));
result |= static_cast<uint16_t>(static_cast<uint16_t>(std::fgetc(file_)) << 8);
uint16_t result = static_cast<uint16_t>(std::fgetc(file_));
result |= static_cast<uint16_t>(static_cast<uint16_t>(std::fgetc(file_)) << 8);
return result;
return result;
}
uint16_t FileHolder::get16be() {
uint16_t result = static_cast<uint16_t>(static_cast<uint16_t>(std::fgetc(file_)) << 8);
result |= static_cast<uint16_t>(std::fgetc(file_));
uint16_t result = static_cast<uint16_t>(static_cast<uint16_t>(std::fgetc(file_)) << 8);
result |= static_cast<uint16_t>(std::fgetc(file_));
return result;
return result;
}
uint8_t FileHolder::get8() {
return static_cast<uint8_t>(std::fgetc(file_));
return static_cast<uint8_t>(std::fgetc(file_));
}
void FileHolder::put16be(uint16_t value) {
@ -118,7 +118,7 @@ std::vector<uint8_t> FileHolder::read(std::size_t size) {
}
std::size_t FileHolder::read(uint8_t *buffer, std::size_t size) {
return std::fread(buffer, 1, size, file_);
return std::fread(buffer, 1, size, file_);
}
std::size_t FileHolder::write(const std::vector<uint8_t> &buffer) {
@ -126,7 +126,7 @@ std::size_t FileHolder::write(const std::vector<uint8_t> &buffer) {
}
std::size_t FileHolder::write(const uint8_t *buffer, std::size_t size) {
return std::fwrite(buffer, 1, size, file_);
return std::fwrite(buffer, 1, size, file_);
}
void FileHolder::seek(long offset, int whence) {
@ -160,24 +160,22 @@ bool FileHolder::check_signature(const char *signature, std::size_t length) {
}
std::string FileHolder::extension() {
std::size_t pointer = name_.size() - 1;
while(pointer > 0 && name_[pointer] != '.') pointer--;
if(name_[pointer] == '.') pointer++;
std::size_t pointer = name_.size() - 1;
while(pointer > 0 && name_[pointer] != '.') pointer--;
if(name_[pointer] == '.') pointer++;
std::string extension = name_.substr(pointer);
std::transform(extension.begin(), extension.end(), extension.begin(), ::tolower);
return extension;
std::string extension = name_.substr(pointer);
std::transform(extension.begin(), extension.end(), extension.begin(), ::tolower);
return extension;
}
void FileHolder::ensure_is_at_least_length(long length) {
std::fseek(file_, 0, SEEK_END);
long bytes_to_write = length - ftell(file_);
if(bytes_to_write > 0) {
uint8_t *empty = new uint8_t[static_cast<std::size_t>(bytes_to_write)];
std::memset(empty, 0, static_cast<std::size_t>(bytes_to_write));
std::fwrite(empty, sizeof(uint8_t), static_cast<std::size_t>(bytes_to_write), file_);
delete[] empty;
}
std::fseek(file_, 0, SEEK_END);
long bytes_to_write = length - ftell(file_);
if(bytes_to_write > 0) {
std::vector<uint8_t> empty(static_cast<std::size_t>(bytes_to_write), 0);
std::fwrite(empty.data(), sizeof(uint8_t), static_cast<std::size_t>(bytes_to_write), file_);
}
}
bool FileHolder::get_is_known_read_only() {