mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-25 16:31:42 +00:00
Introduces a new scan source data type, motivated by the reasoning used by the Oric.
Specifically: it'll allow PCM sampling of the potentially arbitrary composite generation logic of various machines.
This commit is contained in:
parent
e39ecf59ef
commit
fd579a019b
@ -530,7 +530,7 @@ template <Analyser::Static::Oric::Target::DiskInterface disk_interface> class Co
|
|||||||
}
|
}
|
||||||
|
|
||||||
void set_display_type(Outputs::Display::DisplayType display_type) override {
|
void set_display_type(Outputs::Display::DisplayType display_type) override {
|
||||||
video_output_.set_display_type(display_type);
|
// video_output_.set_display_type(display_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
Configurable::SelectionSet get_accurate_selections() override {
|
Configurable::SelectionSet get_accurate_selections() override {
|
||||||
|
@ -40,12 +40,12 @@ namespace {
|
|||||||
|
|
||||||
VideoOutput::VideoOutput(uint8_t *memory) :
|
VideoOutput::VideoOutput(uint8_t *memory) :
|
||||||
ram_(memory),
|
ram_(memory),
|
||||||
crt_(64*6, 1, Outputs::Display::Type::PAL50, Outputs::Display::InputDataType::Red1Green1Blue1),
|
crt_(64*6, 1, Outputs::Display::Type::PAL50, Outputs::Display::InputDataType::PhaseLinkedLuminance8),
|
||||||
v_sync_start_position_(PAL50VSyncStartPosition), v_sync_end_position_(PAL50VSyncEndPosition),
|
v_sync_start_position_(PAL50VSyncStartPosition), v_sync_end_position_(PAL50VSyncEndPosition),
|
||||||
counter_period_(PAL50Period) {
|
counter_period_(PAL50Period) {
|
||||||
// crt_->set_composite_function_type(Outputs::CRT::CRT::CompositeSourceType::DiscreteFourSamplesPerCycle, 0.0f);
|
crt_.set_composite_function_type(Outputs::CRT::CRT::CompositeSourceType::DiscreteFourSamplesPerCycle, 1.0f / 8.0f);
|
||||||
|
|
||||||
set_display_type(Outputs::Display::DisplayType::RGB);
|
set_display_type(Outputs::Display::DisplayType::CompositeColour);
|
||||||
crt_.set_visible_area(crt_.get_rect_for_area(54, 224, 16 * 6, 40 * 6, 4.0f / 3.0f));
|
crt_.set_visible_area(crt_.get_rect_for_area(54, 224, 16 * 6, 40 * 6, 4.0f / 3.0f));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,18 +60,32 @@ void VideoOutput::set_scan_target(Outputs::Display::ScanTarget *scan_target) {
|
|||||||
|
|
||||||
void VideoOutput::set_colour_rom(const std::vector<uint8_t> &rom) {
|
void VideoOutput::set_colour_rom(const std::vector<uint8_t> &rom) {
|
||||||
for(std::size_t c = 0; c < 8; c++) {
|
for(std::size_t c = 0; c < 8; c++) {
|
||||||
std::size_t index = (c << 2);
|
colour_forms_[c] = 0;
|
||||||
uint16_t rom_value = static_cast<uint16_t>((static_cast<uint16_t>(rom[index]) << 8) | static_cast<uint16_t>(rom[index+1]));
|
|
||||||
rom_value = (rom_value & 0xff00) | ((rom_value >> 4)&0x000f) | ((rom_value << 4)&0x00f0);
|
uint8_t *const colour = reinterpret_cast<uint8_t *>(&colour_forms_[c]);
|
||||||
colour_forms_[c] = rom_value;
|
const std::size_t index = (c << 2);
|
||||||
|
|
||||||
|
// Values in the ROM are encoded for indexing by two square waves
|
||||||
|
// in quadrature, which means that they're indexed in the order
|
||||||
|
// 0, 1, 3, 2.
|
||||||
|
colour[1] = uint8_t(rom[index] & 0xf0);
|
||||||
|
colour[0] = uint8_t((rom[index] & 0x0f) << 4);
|
||||||
|
colour[3] = uint8_t((rom[index+1] & 0x0f) << 4);
|
||||||
|
colour[2] = uint8_t(rom[index+1] & 0xf0);
|
||||||
|
|
||||||
|
// Extracting just the visible part of the stored range of values
|
||||||
|
// means etracting the range 0x40 to 0xe0.
|
||||||
|
for(int sub = 0; sub < 4; ++sub) {
|
||||||
|
colour[sub] = ((colour[sub] - 0x40) * 255) / 0xa0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// check for big endianness and byte swap if required
|
// Check for big endianness and byte swap if required.
|
||||||
uint16_t test_value = 0x0001;
|
uint32_t test_value = 0x0001;
|
||||||
if(*reinterpret_cast<uint8_t *>(&test_value) != 0x01) {
|
if(*reinterpret_cast<uint8_t *>(&test_value) != 0x01) {
|
||||||
for(std::size_t c = 0; c < 8; c++) {
|
// for(std::size_t c = 0; c < 8; c++) {
|
||||||
colour_forms_[c] = static_cast<uint16_t>((colour_forms_[c] >> 8) | (colour_forms_[c] << 8));
|
// colour_forms_[c] = static_cast<uint16_t>((colour_forms_[c] >> 8) | (colour_forms_[c] << 8));
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -266,6 +266,13 @@ std::unique_ptr<Shader> ScanTarget::input_shader(InputDataType input_data_type,
|
|||||||
fragment_shader += "fragColour = vec3(texture(textureName, textureCoordinate).r / 255.0);";
|
fragment_shader += "fragColour = vec3(texture(textureName, textureCoordinate).r / 255.0);";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case InputDataType::PhaseLinkedLuminance8:
|
||||||
|
computed_display_type = DisplayType::CompositeMonochrome;
|
||||||
|
fragment_shader +=
|
||||||
|
"uint iPhase = uint(compositeAngle * 2.0 / 3.141592654) & 3u;"
|
||||||
|
"fragColour = vec3(texture(textureName, textureCoordinate)[iPhase] / 255.0);";
|
||||||
|
break;
|
||||||
|
|
||||||
case InputDataType::Luminance8Phase8:
|
case InputDataType::Luminance8Phase8:
|
||||||
computed_display_type = DisplayType::SVideo;
|
computed_display_type = DisplayType::SVideo;
|
||||||
fragment_shader +=
|
fragment_shader +=
|
||||||
|
@ -60,6 +60,12 @@ enum class InputDataType {
|
|||||||
Luminance1, // 1 byte/pixel; any bit set => white; no bits set => black.
|
Luminance1, // 1 byte/pixel; any bit set => white; no bits set => black.
|
||||||
Luminance8, // 1 byte/pixel; linear scale.
|
Luminance8, // 1 byte/pixel; linear scale.
|
||||||
|
|
||||||
|
PhaseLinkedLuminance8, // 4 bytes/pixel; each byte is an individual 8-bit luminance
|
||||||
|
// value and which value is output is a function of
|
||||||
|
// colour subcarrier phase — byte 0 defines the first quarter
|
||||||
|
// of each colour cycle, byte 1 the next quarter, etc. This
|
||||||
|
// format is intended to permit replay of sampled original data.
|
||||||
|
|
||||||
// The luminance plus phase types describe a luminance and the phase offset
|
// The luminance plus phase types describe a luminance and the phase offset
|
||||||
// of a colour subcarrier. So they can be used to generate a luminance signal,
|
// of a colour subcarrier. So they can be used to generate a luminance signal,
|
||||||
// or an s-video pipeline.
|
// or an s-video pipeline.
|
||||||
@ -91,6 +97,7 @@ inline size_t size_for_data_type(InputDataType data_type) {
|
|||||||
return 2;
|
return 2;
|
||||||
|
|
||||||
case InputDataType::Red8Green8Blue8:
|
case InputDataType::Red8Green8Blue8:
|
||||||
|
case InputDataType::PhaseLinkedLuminance8:
|
||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -99,6 +106,7 @@ inline DisplayType natural_display_type_for_data_type(InputDataType data_type) {
|
|||||||
switch(data_type) {
|
switch(data_type) {
|
||||||
case InputDataType::Luminance1:
|
case InputDataType::Luminance1:
|
||||||
case InputDataType::Luminance8:
|
case InputDataType::Luminance8:
|
||||||
|
case InputDataType::PhaseLinkedLuminance8:
|
||||||
return DisplayType::CompositeColour;
|
return DisplayType::CompositeColour;
|
||||||
|
|
||||||
case InputDataType::Red1Green1Blue1:
|
case InputDataType::Red1Green1Blue1:
|
||||||
|
Loading…
Reference in New Issue
Block a user