2016-02-14 01:52:23 +00:00
|
|
|
//
|
2016-03-09 01:59:16 +00:00
|
|
|
// CRTInputBufferBuilder.cpp
|
2016-02-14 01:52:23 +00:00
|
|
|
// Clock Signal
|
|
|
|
//
|
2016-03-09 01:59:16 +00:00
|
|
|
// Created by Thomas Harte on 08/03/2016.
|
2016-02-14 01:52:23 +00:00
|
|
|
// Copyright © 2016 Thomas Harte. All rights reserved.
|
|
|
|
//
|
|
|
|
|
2016-03-09 01:59:16 +00:00
|
|
|
#include "CRTInputBufferBuilder.hpp"
|
2016-02-14 01:52:23 +00:00
|
|
|
#include "CRTOpenGL.hpp"
|
2016-03-09 01:59:16 +00:00
|
|
|
#include <string.h>
|
2016-02-14 01:52:23 +00:00
|
|
|
|
2016-03-09 01:59:16 +00:00
|
|
|
using namespace Outputs::CRT;
|
2016-02-14 01:52:23 +00:00
|
|
|
|
2016-03-20 02:46:17 +00:00
|
|
|
CRTInputBufferBuilder::CRTInputBufferBuilder(size_t bytes_per_pixel) :
|
2016-05-04 11:39:45 +00:00
|
|
|
_bytes_per_pixel(bytes_per_pixel),
|
2016-03-20 02:46:17 +00:00
|
|
|
_next_write_x_position(0),
|
|
|
|
_next_write_y_position(0),
|
2016-05-04 11:39:45 +00:00
|
|
|
_last_uploaded_line(0),
|
2016-05-05 01:27:10 +00:00
|
|
|
_is_full(false),
|
|
|
|
_image(new uint8_t[bytes_per_pixel * InputBufferBuilderWidth * InputBufferBuilderHeight])
|
2016-03-20 02:46:17 +00:00
|
|
|
{}
|
|
|
|
|
2016-05-05 01:27:10 +00:00
|
|
|
CRTInputBufferBuilder::~CRTInputBufferBuilder()
|
|
|
|
{
|
|
|
|
delete[] _image;
|
|
|
|
}
|
|
|
|
|
2016-03-09 01:59:16 +00:00
|
|
|
void CRTInputBufferBuilder::allocate_write_area(size_t required_length)
|
2016-02-14 01:52:23 +00:00
|
|
|
{
|
2016-05-05 01:08:38 +00:00
|
|
|
if(!_is_full)
|
2016-02-14 01:52:23 +00:00
|
|
|
{
|
2016-05-04 11:39:45 +00:00
|
|
|
_last_allocation_amount = required_length;
|
2016-02-14 01:52:23 +00:00
|
|
|
|
2016-05-04 11:39:45 +00:00
|
|
|
if(_next_write_x_position + required_length + 2 > InputBufferBuilderWidth)
|
|
|
|
{
|
|
|
|
_next_write_x_position = 0;
|
|
|
|
_next_write_y_position++;
|
|
|
|
|
|
|
|
_is_full = (_next_write_y_position == _last_uploaded_line + InputBufferBuilderHeight);
|
2016-05-05 01:08:38 +00:00
|
|
|
if(_is_full)
|
|
|
|
return;
|
2016-05-04 11:39:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
_write_x_position = _next_write_x_position + 1;
|
|
|
|
_write_y_position = _next_write_y_position;
|
2016-05-05 01:27:10 +00:00
|
|
|
_write_target_pointer = (_write_y_position * InputBufferBuilderWidth) + _write_x_position;
|
2016-05-04 11:39:45 +00:00
|
|
|
_next_write_x_position += required_length + 2;
|
|
|
|
}
|
2016-02-14 01:52:23 +00:00
|
|
|
}
|
|
|
|
|
2016-05-05 01:27:10 +00:00
|
|
|
bool CRTInputBufferBuilder::reduce_previous_allocation_to(size_t actual_length)
|
2016-02-14 01:52:23 +00:00
|
|
|
{
|
2016-05-04 11:39:45 +00:00
|
|
|
if(_is_full) return false;
|
|
|
|
|
2016-03-19 21:07:05 +00:00
|
|
|
// book end the allocation with duplicates of the first and last pixel, to protect
|
|
|
|
// against rounding errors when this run is drawn
|
2016-05-05 01:27:10 +00:00
|
|
|
memcpy( &_image[(_write_target_pointer - 1) * _bytes_per_pixel],
|
|
|
|
&_image[_write_target_pointer * _bytes_per_pixel],
|
2016-05-04 11:39:45 +00:00
|
|
|
_bytes_per_pixel);
|
2016-02-14 01:52:23 +00:00
|
|
|
|
2016-05-05 01:27:10 +00:00
|
|
|
memcpy( &_image[(_write_target_pointer + actual_length) * _bytes_per_pixel],
|
|
|
|
&_image[(_write_target_pointer + actual_length - 1) * _bytes_per_pixel],
|
2016-05-04 11:39:45 +00:00
|
|
|
_bytes_per_pixel);
|
2016-02-14 01:52:23 +00:00
|
|
|
|
2016-03-19 21:07:05 +00:00
|
|
|
// return any allocated length that wasn't actually used to the available pool
|
2016-02-14 01:52:23 +00:00
|
|
|
_next_write_x_position -= (_last_allocation_amount - actual_length);
|
2016-05-04 11:39:45 +00:00
|
|
|
|
|
|
|
return true;
|
2016-02-14 01:52:23 +00:00
|
|
|
}
|
2016-05-05 01:27:10 +00:00
|
|
|
|
|
|
|
uint8_t *CRTInputBufferBuilder::get_image_pointer()
|
|
|
|
{
|
|
|
|
return _image;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint16_t CRTInputBufferBuilder::get_and_finalise_current_line()
|
|
|
|
{
|
|
|
|
uint16_t result = _write_y_position;
|
|
|
|
_next_write_x_position = _next_write_y_position = 0;
|
|
|
|
_is_full = false;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint8_t *CRTInputBufferBuilder::get_write_target()
|
|
|
|
{
|
|
|
|
return _is_full ? nullptr : &_image[_write_target_pointer * _bytes_per_pixel];
|
|
|
|
}
|
|
|
|
|
|
|
|
uint16_t CRTInputBufferBuilder::get_last_write_x_position()
|
|
|
|
{
|
|
|
|
return _write_x_position;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint16_t CRTInputBufferBuilder::get_last_write_y_position()
|
|
|
|
{
|
|
|
|
return _write_y_position % InputBufferBuilderHeight;
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t CRTInputBufferBuilder::get_bytes_per_pixel()
|
|
|
|
{
|
|
|
|
return _bytes_per_pixel;
|
|
|
|
}
|