2016-02-05 03:28:50 +00:00
|
|
|
//
|
|
|
|
// CRTFrameBuilder.cpp
|
|
|
|
// Clock Signal
|
|
|
|
//
|
|
|
|
// Created by Thomas Harte on 04/02/2016.
|
|
|
|
// Copyright © 2016 Thomas Harte. All rights reserved.
|
|
|
|
//
|
|
|
|
|
|
|
|
#include "CRT.hpp"
|
|
|
|
|
|
|
|
using namespace Outputs;
|
|
|
|
|
|
|
|
CRT::CRTFrameBuilder::CRTFrameBuilder(uint16_t width, uint16_t height, unsigned int number_of_buffers, va_list buffer_sizes)
|
|
|
|
{
|
|
|
|
frame.size.width = width;
|
|
|
|
frame.size.height = height;
|
|
|
|
frame.number_of_buffers = number_of_buffers;
|
|
|
|
frame.buffers = new CRTBuffer[number_of_buffers];
|
|
|
|
frame.size_per_vertex = kCRTSizeOfVertex;
|
|
|
|
frame.geometry_mode = CRTGeometryModeTriangles;
|
|
|
|
|
|
|
|
for(int buffer = 0; buffer < number_of_buffers; buffer++)
|
|
|
|
{
|
|
|
|
frame.buffers[buffer].depth = va_arg(buffer_sizes, unsigned int);
|
|
|
|
frame.buffers[buffer].data = new uint8_t[width * height * frame.buffers[buffer].depth];
|
|
|
|
}
|
|
|
|
|
|
|
|
reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
CRT::CRTFrameBuilder::~CRTFrameBuilder()
|
|
|
|
{
|
|
|
|
for(int buffer = 0; buffer < frame.number_of_buffers; buffer++)
|
|
|
|
delete[] frame.buffers[buffer].data;
|
|
|
|
delete frame.buffers;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CRT::CRTFrameBuilder::reset()
|
|
|
|
{
|
|
|
|
frame.number_of_vertices = 0;
|
|
|
|
_next_write_x_position = _next_write_y_position = 0;
|
|
|
|
frame.dirty_size.width = 0;
|
|
|
|
frame.dirty_size.height = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CRT::CRTFrameBuilder::complete()
|
|
|
|
{
|
|
|
|
frame.vertices = &_all_runs[0];
|
|
|
|
}
|
|
|
|
|
|
|
|
uint8_t *CRT::CRTFrameBuilder::get_next_run()
|
|
|
|
{
|
|
|
|
const size_t vertices_per_run = 6;
|
|
|
|
|
|
|
|
// get a run from the allocated list, allocating more if we're about to overrun
|
|
|
|
if((frame.number_of_vertices + vertices_per_run) * frame.size_per_vertex >= _all_runs.size())
|
|
|
|
{
|
|
|
|
_all_runs.resize(_all_runs.size() + frame.size_per_vertex * vertices_per_run * 100);
|
|
|
|
}
|
|
|
|
|
|
|
|
uint8_t *next_run = &_all_runs[frame.number_of_vertices * frame.size_per_vertex];
|
|
|
|
frame.number_of_vertices += vertices_per_run;
|
|
|
|
|
|
|
|
return next_run;
|
|
|
|
}
|
|
|
|
|
2016-02-08 01:29:32 +00:00
|
|
|
void CRT::CRTFrameBuilder::allocate_write_area(size_t required_length)
|
2016-02-05 03:28:50 +00:00
|
|
|
{
|
2016-02-06 21:07:23 +00:00
|
|
|
_last_allocation_amount = required_length;
|
|
|
|
|
2016-02-08 01:29:32 +00:00
|
|
|
if(_next_write_x_position + required_length + 2 > frame.size.width)
|
2016-02-05 03:28:50 +00:00
|
|
|
{
|
|
|
|
_next_write_x_position = 0;
|
|
|
|
_next_write_y_position = (_next_write_y_position+1)&(frame.size.height-1);
|
|
|
|
frame.dirty_size.height++;
|
|
|
|
}
|
|
|
|
|
2016-02-08 01:29:32 +00:00
|
|
|
_write_x_position = _next_write_x_position + 1;
|
2016-02-05 03:28:50 +00:00
|
|
|
_write_y_position = _next_write_y_position;
|
|
|
|
_write_target_pointer = (_write_y_position * frame.size.width) + _write_x_position;
|
2016-02-08 01:29:32 +00:00
|
|
|
_next_write_x_position += required_length + 2;
|
2016-02-05 03:28:50 +00:00
|
|
|
frame.dirty_size.width = std::max(frame.dirty_size.width, _next_write_x_position);
|
|
|
|
}
|
|
|
|
|
2016-02-08 01:29:32 +00:00
|
|
|
void CRT::CRTFrameBuilder::reduce_previous_allocation_to(size_t actual_length)
|
2016-02-06 21:07:23 +00:00
|
|
|
{
|
2016-02-08 01:29:32 +00:00
|
|
|
for(int c = 0; c < frame.number_of_buffers; c++)
|
|
|
|
{
|
|
|
|
memcpy( &frame.buffers[c].data[(_write_target_pointer - 1) * frame.buffers[c].depth],
|
|
|
|
&frame.buffers[c].data[_write_target_pointer * frame.buffers[c].depth],
|
|
|
|
frame.buffers[c].depth);
|
|
|
|
|
|
|
|
memcpy( &frame.buffers[c].data[(_write_target_pointer + actual_length) * frame.buffers[c].depth],
|
|
|
|
&frame.buffers[c].data[(_write_target_pointer + actual_length - 1) * frame.buffers[c].depth],
|
|
|
|
frame.buffers[c].depth);
|
|
|
|
}
|
|
|
|
|
2016-02-06 21:07:23 +00:00
|
|
|
_next_write_x_position -= (_last_allocation_amount - actual_length);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-02-05 03:28:50 +00:00
|
|
|
uint8_t *CRT::CRTFrameBuilder::get_write_target_for_buffer(int buffer)
|
|
|
|
{
|
|
|
|
return &frame.buffers[buffer].data[_write_target_pointer * frame.buffers[buffer].depth];
|
|
|
|
}
|