mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-25 15:54:31 +01:00
port gfx_fill_rect to IDrawingContext
This commit is contained in:
@@ -26,7 +26,7 @@ interface IDrawingContext
|
||||
|
||||
virtual IDrawingEngine * GetEngine() abstract;
|
||||
|
||||
virtual void Clear(uint32 colour) abstract;
|
||||
virtual void FillRect(uint32 colour, sint32 x, sint32 y, sint32 w, sint32 h) abstract;
|
||||
virtual void DrawSprite(uint32 image, sint32 x, sint32 y) abstract;
|
||||
virtual void Clear(uint32 colour) abstract;
|
||||
virtual void FillRect(uint32 colour, sint32 left, sint32 top, sint32 right, sint32 bottom) abstract;
|
||||
virtual void DrawSprite(uint32 image, sint32 x, sint32 y) abstract;
|
||||
};
|
||||
|
||||
@@ -82,4 +82,23 @@ extern "C"
|
||||
dc->Clear(colour);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x00678AD4
|
||||
* dpi (edi)
|
||||
* left (ax)
|
||||
* top (cx)
|
||||
* right (bx)
|
||||
* bottom (dx)
|
||||
* colour (ebp)
|
||||
*/
|
||||
void gfx_fill_rect(rct_drawpixelinfo *dpi, int left, int top, int right, int bottom, int colour)
|
||||
{
|
||||
if (_drawingEngine != nullptr)
|
||||
{
|
||||
IDrawingContext * dc = _drawingEngine->GetDrawingContext(dpi);
|
||||
dc->FillRect(colour, left, top, right, bottom);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -553,9 +553,200 @@ void SoftwareDrawingContext::Clear(uint32 colour)
|
||||
}
|
||||
}
|
||||
|
||||
void SoftwareDrawingContext::FillRect(uint32 colour, sint32 x, sint32 y, sint32 w, sint32 h)
|
||||
void SoftwareDrawingContext::FillRect(uint32 colour, sint32 left, sint32 top, sint32 right, sint32 bottom)
|
||||
{
|
||||
rct_drawpixelinfo * dpi = _dpi;
|
||||
|
||||
if (left > right) return;
|
||||
if (top > bottom) return;
|
||||
if (dpi->x > right) return;
|
||||
if (left >= dpi->x + dpi->width) return;
|
||||
if (bottom < dpi->y) return;
|
||||
if (top >= dpi->y + dpi->height) return;
|
||||
|
||||
colour |= RCT2_GLOBAL(0x009ABD9C, uint32);
|
||||
|
||||
uint16 crossPattern = 0;
|
||||
|
||||
int startX = left - dpi->x;
|
||||
if (startX < 0)
|
||||
{
|
||||
crossPattern ^= startX;
|
||||
startX = 0;
|
||||
}
|
||||
|
||||
int endX = right - dpi->x + 1;
|
||||
if (endX > dpi->width)
|
||||
{
|
||||
endX = dpi->width;
|
||||
}
|
||||
|
||||
int startY = top - dpi->y;
|
||||
if (startY < 0)
|
||||
{
|
||||
crossPattern ^= startY;
|
||||
startY = 0;
|
||||
}
|
||||
|
||||
int endY = bottom - dpi->y + 1;
|
||||
if (endY > dpi->height)
|
||||
{
|
||||
endY = dpi->height;
|
||||
}
|
||||
|
||||
int width = endX - startX;
|
||||
int height = endY - startY;
|
||||
|
||||
if (colour & 0x1000000)
|
||||
{
|
||||
// Cross hatching
|
||||
uint8 * dst = (startY * (dpi->width + dpi->pitch)) + startX + dpi->bits;
|
||||
for (int i = 0; i < height; i++)
|
||||
{
|
||||
uint8 * nextdst = dst + dpi->width + dpi->pitch;
|
||||
uint32 p = ror32(crossPattern, 1);
|
||||
p = (p & 0xFFFF0000) | width;
|
||||
|
||||
// Fill every other pixel with the colour
|
||||
for (; (p & 0xFFFF) != 0; p--)
|
||||
{
|
||||
p = p ^ 0x80000000;
|
||||
if (p & 0x80000000)
|
||||
{
|
||||
*dst = colour & 0xFF;
|
||||
}
|
||||
dst++;
|
||||
}
|
||||
crossPattern ^= 1;
|
||||
dst = nextdst;
|
||||
}
|
||||
}
|
||||
else if (colour & 0x2000000)
|
||||
{
|
||||
//0x2000000
|
||||
// 00678B7E 00678C83
|
||||
// Location in screen buffer?
|
||||
uint8 * dst = dpi->bits + (uint32)((startY >> (dpi->zoom_level)) * ((dpi->width >> dpi->zoom_level) + dpi->pitch) + (startX >> dpi->zoom_level));
|
||||
|
||||
// Find colour in colour table?
|
||||
uint16 g1Index = palette_to_g1_offset[colour & 0xFF];
|
||||
rct_g1_element * g1Element = &g1Elements[g1Index];
|
||||
uint8 * g1Bits = g1Element->offset;
|
||||
|
||||
// Fill the rectangle with the colours from the colour table
|
||||
for (int i = 0; i < height >> dpi->zoom_level; i++)
|
||||
{
|
||||
uint8 * nextdst = dst + (dpi->width >> dpi->zoom_level) + dpi->pitch;
|
||||
for (int j = 0; j < (width >> dpi->zoom_level); j++)
|
||||
{
|
||||
*dst = g1Bits[*dst];
|
||||
dst++;
|
||||
}
|
||||
dst = nextdst;
|
||||
}
|
||||
}
|
||||
else if (colour & 0x4000000)
|
||||
{
|
||||
uint8 * dst = startY * (dpi->width + dpi->pitch) + startX + dpi->bits;
|
||||
|
||||
// The pattern loops every 15 lines this is which
|
||||
// part the pattern is on.
|
||||
int patternY = (startY + dpi->y) % 16;
|
||||
|
||||
// The pattern loops every 15 pixels this is which
|
||||
// part the pattern is on.
|
||||
int startPatternX = (startX + dpi->x) % 16;
|
||||
int patternX = startPatternX;
|
||||
|
||||
uint16 * patternsrc = RCT2_ADDRESS(0x0097FEFC, uint16*)[colour >> 28]; // or possibly uint8)[esi*4] ?
|
||||
|
||||
for (int numLines = height; numLines > 0; numLines--)
|
||||
{
|
||||
uint8 * nextdst = dst + dpi->width + dpi->pitch;
|
||||
uint16 pattern = patternsrc[patternY];
|
||||
|
||||
for (int numPixels = width; numPixels > 0; numPixels--)
|
||||
{
|
||||
if (pattern & (1 << patternX))
|
||||
{
|
||||
*dst = colour & 0xFF;
|
||||
}
|
||||
patternX = (patternX + 1) % 16;
|
||||
dst++;
|
||||
}
|
||||
patternX = startPatternX;
|
||||
patternY = (patternY + 1) % 16;
|
||||
dst = nextdst;
|
||||
}
|
||||
}
|
||||
else if (colour & 0x8000000)
|
||||
{
|
||||
int esi = left - RCT2_GLOBAL(0x1420070, sint16);
|
||||
RCT2_GLOBAL(0xEDF824, uint32) = esi;
|
||||
esi = top - RCT2_GLOBAL(0x1420072, sint16);
|
||||
RCT2_GLOBAL(0xEDF828, uint32) = esi;
|
||||
left -= dpi->x;
|
||||
if (left < 0)
|
||||
{
|
||||
RCT2_GLOBAL(0xEDF824, sint32) -= left;
|
||||
left = 0;
|
||||
}
|
||||
right -= dpi->x;
|
||||
right++;
|
||||
if (right > dpi->width)
|
||||
{
|
||||
right = dpi->width;
|
||||
}
|
||||
right -= left;
|
||||
top -= dpi->y;
|
||||
if (top < 0)
|
||||
{
|
||||
RCT2_GLOBAL(0xEDF828, sint32) -= top;
|
||||
top = 0;
|
||||
}
|
||||
bottom -= dpi->y;
|
||||
bottom++;
|
||||
if (bottom > dpi->height)
|
||||
{
|
||||
bottom = dpi->height;
|
||||
}
|
||||
bottom -= top;
|
||||
RCT2_GLOBAL(0xEDF824, sint32) &= 0x3F;
|
||||
RCT2_GLOBAL(0xEDF828, sint32) &= 0x3F;
|
||||
esi = dpi->width;
|
||||
esi += dpi->pitch;
|
||||
esi *= top;
|
||||
esi += left;
|
||||
esi += (uint32)dpi->bits;
|
||||
RCT2_GLOBAL(0xEDF82C, sint32) = right;
|
||||
RCT2_GLOBAL(0xEDF830, sint32) = bottom;
|
||||
left = dpi->width;
|
||||
left += dpi->pitch;
|
||||
left -= right;
|
||||
RCT2_GLOBAL(0xEDF834, sint32) = left;
|
||||
colour &= 0xFF;
|
||||
colour--;
|
||||
right = colour;
|
||||
colour <<= 8;
|
||||
right |= colour;
|
||||
RCT2_GLOBAL(0xEDF838, sint32) = right;
|
||||
//right <<= 4;
|
||||
esi = RCT2_GLOBAL(0xEDF828, sint32);
|
||||
esi *= 0x40;
|
||||
left = 0;
|
||||
esi += (uint32)g1Elements[right].offset;//???
|
||||
//Not finished
|
||||
//Start of loop
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8 * dst = startY * (dpi->width + dpi->pitch) + startX + dpi->bits;
|
||||
for (int i = 0; i < height; i++)
|
||||
{
|
||||
Memory::Set(dst, colour & 0xFF, width);
|
||||
dst += dpi->width + dpi->pitch;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SoftwareDrawingContext::DrawSprite(uint32 image, sint32 x, sint32 y)
|
||||
|
||||
@@ -20,203 +20,6 @@
|
||||
#include "../platform/platform.h"
|
||||
#include "drawing.h"
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x00678AD4
|
||||
* dpi (edi)
|
||||
* left (ax)
|
||||
* top (cx)
|
||||
* right (bx)
|
||||
* bottom (dx)
|
||||
* colour (ebp)
|
||||
*/
|
||||
void gfx_fill_rect(rct_drawpixelinfo *dpi, int left, int top, int right, int bottom, int colour)
|
||||
{
|
||||
int left_ = left;
|
||||
int right_ = right;
|
||||
int top_ = top;
|
||||
int bottom_ = bottom;
|
||||
rct_drawpixelinfo *dpi_ = dpi;
|
||||
|
||||
if ((left > right) || (top > bottom) || (dpi->x > right) || (left >= (dpi->x + dpi->width)) ||
|
||||
(bottom < dpi->y) || (top >= (dpi->y + dpi->height)))
|
||||
return;
|
||||
|
||||
colour |= RCT2_GLOBAL(0x009ABD9C, uint32);
|
||||
|
||||
uint16 cross_pattern = 0;
|
||||
|
||||
int start_x = left - dpi->x;
|
||||
if (start_x < 0){
|
||||
cross_pattern ^= start_x;
|
||||
start_x = 0;
|
||||
}
|
||||
|
||||
int end_x = right - dpi->x;
|
||||
end_x++;
|
||||
if (end_x > dpi->width)
|
||||
end_x = dpi->width;
|
||||
|
||||
int width = end_x - start_x;
|
||||
|
||||
int start_y = top - dpi->y;
|
||||
if (start_y < 0){
|
||||
cross_pattern ^= start_y;
|
||||
start_y = 0;
|
||||
}
|
||||
int end_y = bottom - dpi->y;
|
||||
end_y++;
|
||||
|
||||
if (end_y > dpi->height)
|
||||
end_y = dpi->height;
|
||||
|
||||
int height = end_y - start_y;
|
||||
if (colour&0x1000000){
|
||||
// 00678B2E 00678BE5
|
||||
//Cross hatching
|
||||
uint8* dest_pointer = (start_y * (dpi->width + dpi->pitch)) + start_x + dpi->bits;
|
||||
|
||||
uint32 ecx;
|
||||
for (int i = 0; i < height; ++i) {
|
||||
uint8* next_dest_pointer = dest_pointer + dpi->width + dpi->pitch;
|
||||
ecx = cross_pattern;
|
||||
// Rotate right
|
||||
ecx = (ecx >> 1) | (ecx << (sizeof(ecx) * CHAR_BIT - 1));
|
||||
ecx = (ecx & 0xFFFF0000) | width;
|
||||
// Fill every other pixel with the colour
|
||||
for (; (ecx & 0xFFFF) > 0; ecx--) {
|
||||
ecx = ecx ^ 0x80000000;
|
||||
if ((int)ecx < 0) {
|
||||
*dest_pointer = colour & 0xFF;
|
||||
}
|
||||
dest_pointer++;
|
||||
}
|
||||
cross_pattern ^= 1;
|
||||
dest_pointer = next_dest_pointer;
|
||||
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (colour & 0x2000000){
|
||||
//0x2000000
|
||||
// 00678B7E 00678C83
|
||||
// Location in screen buffer?
|
||||
uint8* dest_pointer = dpi->bits + (uint32)((start_y >> (dpi->zoom_level)) * ((dpi->width >> dpi->zoom_level) + dpi->pitch) + (start_x >> dpi->zoom_level));
|
||||
|
||||
// Find colour in colour table?
|
||||
uint16 eax = palette_to_g1_offset[(colour & 0xFF)];
|
||||
rct_g1_element g1_element = g1Elements[eax];
|
||||
|
||||
// Fill the rectangle with the colours from the colour table
|
||||
for (int i = 0; i < height>>dpi->zoom_level; ++i) {
|
||||
uint8* next_dest_pointer = dest_pointer + (dpi->width >> dpi->zoom_level) + dpi->pitch;
|
||||
for (int j = 0; j < width>>dpi->zoom_level; ++j) {
|
||||
*dest_pointer = g1_element.offset[*dest_pointer];
|
||||
dest_pointer++;
|
||||
}
|
||||
dest_pointer = next_dest_pointer;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (colour & 0x4000000){
|
||||
//0x4000000
|
||||
// 00678B8A 00678E38
|
||||
uint8* dest_pointer = start_y * (dpi->width + dpi->pitch) + start_x + dpi->bits;
|
||||
|
||||
//The pattern loops every 15 lines this is which
|
||||
//part the pattern is on.
|
||||
int pattern_y = (start_y + dpi->y) % 16;
|
||||
|
||||
//The pattern loops every 15 pixels this is which
|
||||
//part the pattern is on.
|
||||
int start_pattern_x = (start_x + dpi_->x) % 16;
|
||||
int pattern_x = start_pattern_x;
|
||||
|
||||
uint16* pattern_pointer = RCT2_ADDRESS(0x0097FEFC,uint16*)[colour >> 28]; // or possibly uint8)[esi*4] ?
|
||||
|
||||
for (int no_lines = height; no_lines > 0; no_lines--) {
|
||||
uint8* next_dest_pointer = dest_pointer + dpi->width + dpi->pitch;
|
||||
uint16 pattern = pattern_pointer[pattern_y];
|
||||
|
||||
for (int no_pixels = width; no_pixels > 0; --no_pixels) {
|
||||
if (pattern & (1 << pattern_x))
|
||||
*dest_pointer = colour & 0xFF;
|
||||
|
||||
pattern_x = (pattern_x + 1) % 16;
|
||||
dest_pointer++;
|
||||
}
|
||||
pattern_x = start_pattern_x;
|
||||
pattern_y = (pattern_y + 1) % 16;
|
||||
dest_pointer = next_dest_pointer;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (colour & 0x8000000){
|
||||
//0x8000000
|
||||
// 00678B3A 00678EC9 still to be implemented
|
||||
int esi = left - RCT2_GLOBAL(0x1420070,sint16);
|
||||
RCT2_GLOBAL(0xEDF824,uint32) = esi;
|
||||
esi = top - RCT2_GLOBAL(0x1420072,sint16);
|
||||
RCT2_GLOBAL(0xEDF828,uint32) = esi;
|
||||
left -= dpi->x;//0x4
|
||||
if ( left < 0 ){
|
||||
RCT2_GLOBAL(0xEDF824,sint32) -= left;
|
||||
left = 0;
|
||||
}
|
||||
right -= dpi->x;
|
||||
right++;
|
||||
if ( right > dpi->width ){
|
||||
right = dpi->width;
|
||||
}
|
||||
right -= left;
|
||||
top -= dpi->y;
|
||||
if ( top < 0 ){
|
||||
RCT2_GLOBAL(0xEDF828,sint32) -= top;
|
||||
top = 0;
|
||||
}
|
||||
bottom -= dpi->y;
|
||||
bottom++;
|
||||
if (bottom > dpi->height){
|
||||
bottom = dpi->height;
|
||||
}
|
||||
bottom -= top;
|
||||
RCT2_GLOBAL(0xEDF824,sint32) &= 0x3F;
|
||||
RCT2_GLOBAL(0xEDF828,sint32) &= 0x3F;
|
||||
esi = dpi->width;
|
||||
esi += dpi->pitch;
|
||||
esi *= top;
|
||||
esi += left;
|
||||
esi += (uint32)dpi->bits;
|
||||
RCT2_GLOBAL(0xEDF82C,sint32) = right;
|
||||
RCT2_GLOBAL(0xEDF830,sint32) = bottom;
|
||||
left = dpi->width;
|
||||
left+= dpi->pitch;
|
||||
left-= right;
|
||||
RCT2_GLOBAL(0xEDF834,sint32) = left;
|
||||
colour &= 0xFF;
|
||||
colour--;
|
||||
right = colour;
|
||||
colour <<= 8;
|
||||
right |= colour;
|
||||
RCT2_GLOBAL(0xEDF838,sint32) = right;
|
||||
//right <<= 4;
|
||||
esi = RCT2_GLOBAL(0xEDF828,sint32);
|
||||
esi *= 0x40;
|
||||
left = 0;
|
||||
esi += (uint32)g1Elements[right].offset;//???
|
||||
//Not finished
|
||||
//Start of loop
|
||||
return;
|
||||
}
|
||||
//0x0000000
|
||||
uint8* dest_pointer = start_y * (dpi->width + dpi->pitch) + start_x + dpi->bits;
|
||||
|
||||
for (int i = 0; i < height; ++i) {
|
||||
memset(dest_pointer, (colour & 0xFF), width);
|
||||
dest_pointer += dpi->width + dpi->pitch;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw a rectangle, with optional border or fill
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user