1
0
Fork 0
mirror of https://github.com/k4zmu2a/SpaceCadetPinball.git synced 2024-11-22 17:00:18 +01:00

render v2, ready

This commit is contained in:
oz 2020-11-15 17:39:00 +03:00
parent 79bb0adab8
commit a4c64cc4c8
14 changed files with 630 additions and 117 deletions

Binary file not shown.

View file

@ -61,7 +61,7 @@ int main()
visualKickerStruct kicker1{}; visualKickerStruct kicker1{};
loader::kicker(509, &kicker1); loader::kicker(509, &kicker1);
auto score1 = score::create("score1", 117); auto score1 = score::create("score1", nullptr);
auto pinballTable = new TPinballTable(); auto pinballTable = new TPinballTable();
//pinballTable->find_component(1); //pinballTable->find_component(1);

View file

@ -47,7 +47,7 @@ TPinballComponent::TPinballComponent(TPinballTable* table, int groupIndex, bool
zMap = static_cast<zmap_header_type*>(ListZMap->Get(0)); zMap = static_cast<zmap_header_type*>(ListZMap->Get(0));
if (ListBitmap) if (ListBitmap)
{ {
visual_rect bmp1Rect{}, tmpRect{}; rectangle_type bmp1Rect{}, tmpRect{};
auto rootBmp = static_cast<gdrv_bitmap8*>(ListBitmap->Get(0)); auto rootBmp = static_cast<gdrv_bitmap8*>(ListBitmap->Get(0));
bmp1Rect.XPosition = rootBmp->XPosition - table->XOffset; bmp1Rect.XPosition = rootBmp->XPosition - table->XOffset;
bmp1Rect.YPosition = rootBmp->YPosition - table->YOffset; bmp1Rect.YPosition = rootBmp->YPosition - table->YOffset;

View file

@ -58,7 +58,7 @@ TPinballTable::TPinballTable(): TPinballComponent(nullptr, -1, false)
TLightGroup* lightGroupObj = new TLightGroup(this, 0); TLightGroup* lightGroupObj = new TLightGroup(this, 0);
this->LightGroup = lightGroupObj; this->LightGroup = lightGroupObj;
auto score1 = score::create("score1", pinball::render_background_bitmap); auto score1 = score::create("score1", render::background_bitmap);
this->Score1 = score1; this->Score1 = score1;
this->Score2 = score1; this->Score2 = score1;
int scoreIndex = 1; int scoreIndex = 1;
@ -71,8 +71,8 @@ TPinballTable::TPinballTable(): TPinballComponent(nullptr, -1, false)
while (scoreIndex < 4); while (scoreIndex < 4);
this->UnknownP45 = 0; this->UnknownP45 = 0;
this->UnknownP73 = 3; this->UnknownP73 = 3;
this->ScoreBallcount = (int*)score::create("ballcount1", pinball::render_background_bitmap); this->ScoreBallcount = (int*)score::create("ballcount1", render::background_bitmap);
this->ScorePlayerNumber1 = (int*)score::create("player_number1", pinball::render_background_bitmap); this->ScorePlayerNumber1 = (int*)score::create("player_number1", render::background_bitmap);
int groupIndexObjects = loader::query_handle("table_objects"); int groupIndexObjects = loader::query_handle("table_objects");
short* shortArr = loader::query_iattribute(groupIndexObjects, 1025, &shortArrLength); short* shortArr = loader::query_iattribute(groupIndexObjects, 1025, &shortArrLength);

View file

@ -2,35 +2,117 @@
#include "maths.h" #include "maths.h"
void maths::enclosing_box(visual_rect* rect1, visual_rect* rect2, visual_rect* dstRect) void maths::enclosing_box(rectangle_type* rect1, rectangle_type* rect2, rectangle_type* dstRect)
{ {
int xPos1 = rect1->XPosition; int xPos1 = rect1->XPosition;
int yPos1 = rect1->YPosition; int yPos1 = rect1->YPosition;
int width1 = rect1->Width; int width1 = rect1->Width;
int height1 = rect1->Height; int height1 = rect1->Height;
int xPos2 = rect2->XPosition; int xPos2 = rect2->XPosition;
bool rect2XPosLessRect1 = rect2->XPosition < rect1->XPosition; bool rect2XPosLessRect1 = rect2->XPosition < rect1->XPosition;
int yPos2 = rect2->YPosition; int yPos2 = rect2->YPosition;
int width2 = rect2->Width; int width2 = rect2->Width;
int height2 = rect2->Height; int height2 = rect2->Height;
int xPos2_2 = rect2->XPosition; int xPos2_2 = rect2->XPosition;
if (rect2XPosLessRect1) if (rect2XPosLessRect1)
{ {
width1 += xPos1 - xPos2; width1 += xPos1 - xPos2;
xPos1 = xPos2; xPos1 = xPos2;
} }
if (yPos2 < yPos1) if (yPos2 < yPos1)
{ {
height1 += yPos1 - yPos2; height1 += yPos1 - yPos2;
yPos1 = yPos2; yPos1 = yPos2;
} }
if (width2 + xPos2 > xPos1 + width1) if (width2 + xPos2 > xPos1 + width1)
width1 = xPos2_2 + width2 - xPos1; width1 = xPos2_2 + width2 - xPos1;
int height1_2 = height1; int height1_2 = height1;
if (height2 + yPos2 > height1 + yPos1) if (height2 + yPos2 > height1 + yPos1)
height1_2 = yPos2 + height2 - yPos1; height1_2 = yPos2 + height2 - yPos1;
dstRect->YPosition = yPos1; dstRect->YPosition = yPos1;
dstRect->Height = height1_2; dstRect->Height = height1_2;
dstRect->XPosition = xPos1; dstRect->XPosition = xPos1;
dstRect->Width = width1; dstRect->Width = width1;
} }
int maths::rectangle_clip(rectangle_type* rect1, rectangle_type* rect2, rectangle_type* dstRect)
{
int xPos1 = rect1->XPosition;
int yPos1 = rect1->YPosition;
int height1 = rect1->Height;
int xRight2 = rect2->XPosition + rect2->Width;
int width1 = rect1->Width;
int yRight2 = rect2->YPosition + rect2->Height;
if (xPos1 + width1 < rect2->XPosition)
return 0;
if (xPos1 >= xRight2)
return 0;
int yPos2 = yPos1;
if (yPos1 + height1 < rect2->YPosition || yPos1 >= yRight2)
return 0;
if (xPos1 < rect2->XPosition)
{
width1 += xPos1 - rect2->XPosition;
xPos1 = rect2->XPosition;
}
if (xPos1 + width1 > xRight2)
width1 = xRight2 - xPos1;
int height2 = height1;
if (yPos1 < rect2->YPosition)
{
height2 = yPos1 - rect2->YPosition + height1;
yPos2 = rect2->YPosition;
}
if (height2 + yPos2 > yRight2)
height2 = yRight2 - yPos2;
if (!width1 || !height2)
return 0;
if (dstRect)
{
dstRect->XPosition = xPos1;
dstRect->YPosition = yPos2;
dstRect->Width = width1;
dstRect->Height = height2;
}
return 1;
}
int maths::overlapping_box(rectangle_type* rect1, rectangle_type* rect2, rectangle_type* dstRect)
{
int v3; // esi
int v4; // edi
int v5; // esi
int v6; // esi
int v7; // edi
if (rect1->XPosition >= rect2->XPosition)
{
dstRect->XPosition = rect2->XPosition;
v3 = rect1->Width - rect2->XPosition;
v4 = rect1->XPosition;
}
else
{
dstRect->XPosition = rect1->XPosition;
v3 = rect2->Width - rect1->XPosition;
v4 = rect2->XPosition;
}
dstRect->Width = v3 + v4 + 1;
v5 = rect1->YPosition;
if (v5 >= rect2->YPosition)
{
dstRect->YPosition = rect2->YPosition;
v6 = rect1->Height - rect2->YPosition;
v7 = rect1->YPosition;
}
else
{
dstRect->YPosition = v5;
v6 = rect2->Height - rect1->YPosition;
v7 = rect2->YPosition;
}
dstRect->Height = v6 + v7 + 1;
return dstRect->Width <= rect2->Width + rect1->Width && dstRect->Height <= rect2->Height + rect1->Height;
}

View file

@ -1,7 +1,7 @@
#pragma once #pragma once
struct __declspec(align(4)) visual_rect struct __declspec(align(4)) rectangle_type
{ {
int XPosition; int XPosition;
int YPosition; int YPosition;
@ -12,7 +12,7 @@ struct __declspec(align(4)) visual_rect
class maths class maths
{ {
public: public:
static void enclosing_box(visual_rect* rect1, visual_rect* rect2, visual_rect* dstRect); static void enclosing_box(rectangle_type* rect1, rectangle_type* rect2, rectangle_type* dstRect);
static int rectangle_clip(rectangle_type* rect1, rectangle_type* rect2, rectangle_type* dstRect);
static int overlapping_box(rectangle_type* rect1, rectangle_type* rect2, rectangle_type* dstRect);
}; };

View file

@ -4,7 +4,6 @@
int pinball::quickFlag = 0; int pinball::quickFlag = 0;
int pinball::render_background_bitmap = 0;
TTextBox* pinball::InfoTextBox; TTextBox* pinball::InfoTextBox;
TTextBox* pinball::MissTextBox; TTextBox* pinball::MissTextBox;
char pinball::getRcBuffer[6 * 256]; char pinball::getRcBuffer[6 * 256];

View file

@ -5,7 +5,6 @@ class pinball
{ {
public: public:
static int quickFlag; static int quickFlag;
static int render_background_bitmap;
static TTextBox* InfoTextBox; static TTextBox* InfoTextBox;
static TTextBox* MissTextBox; static TTextBox* MissTextBox;
static HINSTANCE hinst; static HINSTANCE hinst;

View file

@ -1,75 +1,256 @@
#include "pch.h" #include "pch.h"
#include "render.h" #include "render.h"
#include "memory.h" #include "memory.h"
int render::blit = 0; int render::blit = 0;
int render::many_dirty, render::many_sprites, render::many_balls; int render::many_dirty, render::many_sprites, render::many_balls;
render_sprite_type_struct **render::dirty_list = new render_sprite_type_struct*[1000], **render::sprite_list = new render_sprite_type_struct **render::dirty_list, **render::sprite_list, **render::ball_list;
render_sprite_type_struct* [1000], **render::ball_list = new render_sprite_type_struct* [
1000];
zmap_header_type* render::background_zmap; zmap_header_type* render::background_zmap;
int render::zmap_offset, render::zmap_offsetY; int render::zmap_offset, render::zmap_offsetY, render::offset_x, render::offset_y;
float render::zscaler, render::zmin, render::zmax;
rectangle_type render::vscreen_rect;
gdrv_bitmap8 render::vscreen, *render::background_bitmap, render::ball_bitmap[20];
zmap_header_type render::zscreen;
void render::init(gdrv_bitmap8* bmp, float zMin, float zScaler, int width, int height)
{
++memory::critical_allocation;
zscaler = zScaler;
zmin = zMin;
zmax = 4294967300.0f / zScaler + zMin;
sprite_list = (render_sprite_type_struct**)memory::allocate(0xFA0u);
dirty_list = (render_sprite_type_struct**)memory::allocate(0xFA0u);
ball_list = (render_sprite_type_struct**)memory::allocate(0x50u);
gdrv::create_bitmap(&vscreen, width, height);
zdrv::create_zmap(&zscreen, width, height);
zdrv::fill(&zscreen, zscreen.Width, zscreen.Height, 0, 0, 0xFFFF);
vscreen_rect.YPosition = 0;
vscreen_rect.XPosition = 0;
vscreen_rect.Width = width;
vscreen_rect.Height = height;
vscreen.YPosition = 0;
vscreen.XPosition = 0;
gdrv_bitmap8* ballBmp = ball_bitmap;
while (ballBmp <= &ball_bitmap[20])
{
gdrv::create_raw_bitmap(ballBmp, 64, 64, 1);
++ballBmp;
}
background_bitmap = bmp;
if (bmp)
gdrv::copy_bitmap(&vscreen, width, height, 0, 0, bmp, 0, 0);
else
gdrv::fill_bitmap(&vscreen, vscreen.Width, vscreen.Height, 0, 0, 0);
--memory::critical_allocation;
}
void render::uninit()
{
gdrv::destroy_bitmap(&vscreen);
zdrv::destroy_zmap(&zscreen);
for (int i = 0; i < many_sprites; ++i)
remove_sprite(sprite_list[i]);
for (int j = 0; j < many_balls; ++j)
remove_ball(ball_list[j]);
memory::free(ball_list);
memory::free(dirty_list);
memory::free(sprite_list);
many_sprites = 0;
many_dirty = 0;
many_balls = 0;
}
void render::update() void render::update()
{ {
rectangle_type overlapRect{};
auto dirtyPtr = dirty_list;
for (int index = 0; index < many_dirty; ++dirtyPtr, ++index)
{
auto curSprite = *dirtyPtr;
if ((*dirtyPtr)->VisualType != VisualType::None)
{
if ((*dirtyPtr)->VisualType == VisualType::Sprite)
{
if (curSprite->BmpRectCopy.Width > 0)
maths::enclosing_box(&curSprite->BmpRectCopy, &curSprite->BmpRect, &curSprite->DirtyRect);
if (!maths::rectangle_clip(&curSprite->DirtyRect, &vscreen_rect, &curSprite->DirtyRect))
{
curSprite->DirtyRect.Width = -1;
continue;
}
auto yPos = curSprite->DirtyRect.YPosition;
auto width = curSprite->DirtyRect.Width;
auto xPos = curSprite->DirtyRect.XPosition;
auto height = curSprite->DirtyRect.Height;
zdrv::fill(&zscreen, width, height, xPos, yPos, 0xFFFF);
if (background_bitmap)
gdrv::copy_bitmap(&vscreen, width, height, xPos, yPos, background_bitmap, xPos, yPos);
else
gdrv::fill_bitmap(&vscreen, width, height, xPos, yPos, 0);
}
}
else
{
if (!maths::rectangle_clip(&curSprite->BmpRect, &vscreen_rect, &curSprite->DirtyRect))
{
curSprite->DirtyRect.Width = -1;
continue;
}
if (!curSprite->Bmp)
{
auto yPos = curSprite->DirtyRect.YPosition;
auto width = curSprite->DirtyRect.Width;
auto xPos = curSprite->DirtyRect.XPosition;
auto height = curSprite->DirtyRect.Height;
zdrv::fill(&zscreen, width, height, xPos, yPos, 0xFFFF);
if (background_bitmap)
gdrv::copy_bitmap(&vscreen, width, height, xPos, yPos, background_bitmap, xPos, yPos);
else
gdrv::fill_bitmap(&vscreen, width, height, xPos, yPos, 0);
}
}
}
dirtyPtr = dirty_list;
for (int index = 0; index < many_dirty; ++index)
{
auto sprite = *dirtyPtr;
if ((*dirtyPtr)->DirtyRect.Width > 0 && (sprite->VisualType == VisualType::None || sprite->VisualType ==
VisualType::Sprite))
repaint(*dirtyPtr);
++dirtyPtr;
}
paint_balls();
if (blit)
{
gdrv::start_blit_sequence();
auto xPos = vscreen.XPosition + offset_x;
auto yPos = vscreen.YPosition + offset_y;
dirtyPtr = dirty_list;
for (int index = 0; index < many_dirty; ++dirtyPtr, ++index)
{
auto sprite = *dirtyPtr;
auto dirtyRect = &(*dirtyPtr)->DirtyRect;
auto width2 = (*dirtyPtr)->DirtyRect.Width;
if (width2 > 0)
gdrv::blit_sequence(
&vscreen,
dirtyRect->XPosition,
dirtyRect->YPosition,
dirtyRect->XPosition + xPos,
dirtyRect->YPosition + yPos,
width2,
dirtyRect->Height);
auto rect = &sprite->BmpRectCopy;
rect->XPosition = dirtyRect->XPosition;
rect->YPosition = dirtyRect->YPosition;
rect->Width = dirtyRect->Width;
rect->Height = dirtyRect->Height;
if (sprite->Unknown6_0 != 0)
remove_sprite(sprite);
}
dirtyPtr = ball_list;
for (int index = 0; index < many_balls; ++dirtyPtr, ++index)
{
auto rectCopy = &(*dirtyPtr)->BmpRectCopy;
auto dirtyRect = &(*dirtyPtr)->DirtyRect;
if (maths::overlapping_box(dirtyRect, rectCopy, &overlapRect) && dirtyRect->Width > 0)
{
if (overlapRect.Width > 0)
gdrv::blit_sequence(
&vscreen,
overlapRect.XPosition,
overlapRect.YPosition,
overlapRect.XPosition + xPos,
overlapRect.YPosition + yPos,
overlapRect.Width,
overlapRect.Height);
}
else
{
if (dirtyRect->Width > 0)
gdrv::blit_sequence(
&vscreen,
dirtyRect->XPosition,
dirtyRect->YPosition,
dirtyRect->XPosition + xPos,
dirtyRect->YPosition + yPos,
dirtyRect->Width,
dirtyRect->Height);
if (rectCopy->Width > 0)
gdrv::blit_sequence(
&vscreen,
rectCopy->XPosition,
rectCopy->YPosition,
rectCopy->XPosition + xPos,
rectCopy->YPosition + yPos,
rectCopy->Width,
rectCopy->Height);
}
}
gdrv::end_blit_sequence();
}
many_dirty = 0;
unpaint_balls();
} }
void render::paint() void render::paint()
{ {
/*render_paint_balls(); paint_balls();
gdrv_blat((int)&vscreen, xDest, yDest); gdrv::blat(&vscreen, vscreen.XPosition, vscreen.YPosition);
render_unpaint_balls();*/ unpaint_balls();
} }
void render::sprite_modified(render_sprite_type_struct* sprite)
int render::sprite_modified(render_sprite_type_struct* sprite)
{ {
int result = 0; // eax if (sprite->VisualType != VisualType::Ball && many_dirty < 999)
if (sprite->VisualType == VisualType::Ball)
return result;
result = many_dirty;
if (many_dirty < 999)
dirty_list[many_dirty++] = sprite; dirty_list[many_dirty++] = sprite;
return result;
} }
render_sprite_type_struct* render::create_sprite(VisualType visualType, gdrv_bitmap8* rootBmp8, zmap_header_type* zMap, render_sprite_type_struct* render::create_sprite(VisualType visualType, gdrv_bitmap8* bmp, zmap_header_type* zMap,
int xPosition, int yPosition, visual_rect* rect) int xPosition, int yPosition, rectangle_type* rect)
{ {
render_sprite_type_struct* sprite = (render_sprite_type_struct*)memory::allocate(0x5Cu); auto sprite = (render_sprite_type_struct*)memory::allocate(sizeof(render_sprite_type_struct));
render_sprite_type_struct* result = nullptr;
if (!sprite) if (!sprite)
return result; return nullptr;
sprite->YPosition = yPosition; sprite->BmpRect.YPosition = yPosition;
sprite->RootBmp8 = rootBmp8; sprite->BmpRect.XPosition = xPosition;
sprite->XPosition = xPosition; sprite->Bmp = bmp;
sprite->VisualType = visualType; sprite->VisualType = visualType;
sprite->Unknown6_0 = 0; sprite->Unknown6_0 = 0;
sprite->Unknown17 = 0; sprite->SpriteArray = nullptr;
sprite->Unknown18 = 0; sprite->SpriteCount = 0;
if (rect) if (rect)
{ {
sprite->Rect = *rect; sprite->BoundingRect = *rect;
} }
else else
{ {
sprite->Rect.Width = -1; sprite->BoundingRect.Width = -1;
sprite->Rect.Height = -1; sprite->BoundingRect.Height = -1;
sprite->Rect.XPosition = 0; sprite->BoundingRect.XPosition = 0;
sprite->Rect.YPosition = 0; sprite->BoundingRect.YPosition = 0;
} }
if (rootBmp8) if (bmp)
{ {
sprite->Bmp8Width = rootBmp8->Width; sprite->BmpRect.Width = bmp->Width;
sprite->Bmp8Height = rootBmp8->Height; sprite->BmpRect.Height = bmp->Height;
} }
else else
{ {
sprite->Bmp8Width = 0; sprite->BmpRect.Width = 0;
sprite->Bmp8Height = 0; sprite->BmpRect.Height = 0;
} }
sprite->ZMap = zMap; sprite->ZMap = zMap;
sprite->ZMapOffestX = 0; sprite->ZMapOffestX = 0;
@ -80,10 +261,7 @@ render_sprite_type_struct* render::create_sprite(VisualType visualType, gdrv_bit
sprite->ZMapOffestY = xPosition - zmap_offset; sprite->ZMapOffestY = xPosition - zmap_offset;
sprite->ZMapOffestX = yPosition - zmap_offsetY; sprite->ZMapOffestX = yPosition - zmap_offsetY;
} }
sprite->XPosition2 = sprite->XPosition; sprite->BmpRectCopy = sprite->BmpRect;
sprite->YPosition2 = sprite->YPosition;
sprite->Bmp8Width2 = sprite->Bmp8Width;
sprite->Bmp8Height2 = sprite->Bmp8Height;
if (visualType == VisualType::Ball) if (visualType == VisualType::Ball)
{ {
ball_list[many_balls++] = sprite; ball_list[many_balls++] = sprite;
@ -93,6 +271,255 @@ render_sprite_type_struct* render::create_sprite(VisualType visualType, gdrv_bit
sprite_list[many_sprites++] = sprite; sprite_list[many_sprites++] = sprite;
sprite_modified(sprite); sprite_modified(sprite);
} }
result = sprite; return sprite;
return result; }
void render::remove_sprite(render_sprite_type_struct* sprite)
{
int spriteCount = many_sprites;
int index = 0;
if (many_sprites > 0)
{
while (sprite_list[index] != sprite)
{
if (++index >= many_sprites)
return;
}
while (index < spriteCount)
{
sprite_list[index] = sprite_list[index + 1];
spriteCount = many_sprites;
++index;
}
many_sprites = spriteCount - 1;
if (sprite->SpriteArray)
memory::free(sprite->SpriteArray);
memory::free(sprite);
}
}
void render::remove_ball(struct render_sprite_type_struct* ball)
{
int ballCount = many_balls;
int index = 0;
if (many_balls > 0)
{
while (ball_list[index] != ball)
{
if (++index >= many_balls)
return;
}
while (index < ballCount)
{
ball_list[index] = ball_list[index + 1];
ballCount = many_balls;
++index;
}
many_balls = ballCount - 1;
memory::free(ball);
}
}
void render::sprite_set(render_sprite_type_struct* sprite, gdrv_bitmap8* bmp, zmap_header_type* zMap, int xPos,
int yPos)
{
if (sprite)
{
sprite->BmpRect.XPosition = xPos;
sprite->BmpRect.YPosition = yPos;
sprite->Bmp = bmp;
if (bmp)
{
sprite->BmpRect.Width = bmp->Width;
sprite->BmpRect.Height = bmp->Height;
}
sprite->ZMap = zMap;
sprite_modified(sprite);
}
}
void render::sprite_set_bitmap(render_sprite_type_struct* sprite, gdrv_bitmap8* bmp)
{
if (sprite && sprite->Bmp != bmp)
{
sprite->Bmp = bmp;
if (bmp)
{
sprite->BmpRect.Width = bmp->Width;
sprite->BmpRect.Height = bmp->Height;
}
sprite_modified(sprite);
}
}
void render::set_background_zmap(struct zmap_header_type* zMap, int offsetX, int offsetY)
{
background_zmap = zMap;
zmap_offset = offsetX;
zmap_offsetY = offsetY;
}
void render::ball_set(render_sprite_type_struct* sprite, gdrv_bitmap8* bmp, float depth, int xPos, int yPos)
{
if (sprite)
{
sprite->Bmp = bmp;
if (bmp)
{
sprite->BmpRect.XPosition = xPos;
sprite->BmpRect.YPosition = yPos;
sprite->BmpRect.Width = bmp->Width;
sprite->BmpRect.Height = bmp->Height;
}
if (depth >= zmin)
{
float depth2 = (depth - zmin) * zscaler;
if (depth2 <= zmax)
sprite->Depth = static_cast<short>(depth2);
else
sprite->Depth = -1;
}
else
{
sprite->Depth = 0;
}
}
}
void render::repaint(struct render_sprite_type_struct* sprite)
{
rectangle_type clipRect{};
if (!sprite->SpriteArray)
return;
for (int index = 0; index < sprite->SpriteCount; index++)
{
render_sprite_type_struct* curSprite = sprite->SpriteArray[index];
if (!curSprite->Unknown6_0 && curSprite->Bmp)
{
if (maths::rectangle_clip(&curSprite->BmpRect, &sprite->DirtyRect, &clipRect))
zdrv::paint(
clipRect.Width,
clipRect.Height,
&vscreen,
clipRect.XPosition,
clipRect.YPosition,
&zscreen,
clipRect.XPosition,
clipRect.YPosition,
curSprite->Bmp,
clipRect.XPosition - curSprite->BmpRect.XPosition,
clipRect.YPosition - curSprite->BmpRect.YPosition,
curSprite->ZMap,
clipRect.XPosition + curSprite->ZMapOffestY - curSprite->BmpRect.XPosition,
clipRect.YPosition + curSprite->ZMapOffestX - curSprite->BmpRect.YPosition);
}
}
}
void render::paint_balls()
{
int ballCount = many_balls;
if (many_balls > 1)
{
for (int index = 0; index < ballCount; index++)
{
for (int i = index; i < ballCount / 2; ++i)
{
auto curBall = ball_list[i];
auto firstBallPtr = &ball_list[index];
if ((*firstBallPtr)->Depth > curBall->Depth)
{
auto firstBall = *firstBallPtr;
*firstBallPtr = curBall;
ball_list[i] = firstBall;
}
}
}
}
auto ballPtr = ball_list;
auto ballBmpPtr = ball_bitmap;
for (int index2 = 0; index2 < many_balls; ++index2)
{
struct render_sprite_type_struct* sprite = *ballPtr;
rectangle_type* rect2 = &(*ballPtr)->DirtyRect;
if ((*ballPtr)->Bmp && maths::rectangle_clip(&sprite->BmpRect, &vscreen_rect, &(*ballPtr)->DirtyRect))
{
int xPos = rect2->XPosition;
int yPos = rect2->YPosition;
gdrv::copy_bitmap(ballBmpPtr, rect2->Width, rect2->Height, 0, 0, &vscreen, xPos, yPos);
zdrv::paint_flat(
rect2->Width,
rect2->Height,
&vscreen,
xPos,
yPos,
&zscreen,
xPos,
yPos,
sprite->Bmp,
xPos - sprite->BmpRect.XPosition,
yPos - sprite->BmpRect.YPosition,
sprite->Depth);
}
else
{
rect2->Width = -1;
}
++ballBmpPtr;
++ballPtr;
}
}
void render::unpaint_balls()
{
auto ballPtr = &ball_list[many_balls - 1];
if (many_balls - 1 >= 0)
{
gdrv_bitmap8* bitmapPtr = &ball_bitmap[many_balls - 1];
for (int index = many_balls; index > 0; index--)
{
struct render_sprite_type_struct* curBall = *ballPtr;
rectangle_type* rect2 = &(*ballPtr)->DirtyRect;
int width = (*ballPtr)->DirtyRect.Width;
if (width > 0)
gdrv::copy_bitmap(
&vscreen,
width,
(*ballPtr)->DirtyRect.Height,
(*ballPtr)->DirtyRect.XPosition,
(*ballPtr)->DirtyRect.YPosition,
bitmapPtr,
0,
0);
rectangle_type* rectCopy = &curBall->BmpRectCopy;
rectCopy->XPosition = rect2->XPosition;
rectCopy->YPosition = rect2->YPosition;
rectCopy->Width = rect2->Width;
rectCopy->Height = rect2->Height;
--ballPtr;
--bitmapPtr;
}
}
}
void render::shift(int offsetX, int offsetY, int xSrc, int ySrc, int DestWidth, int DestHeight)
{
offset_x += offsetX;
offset_y += offsetY;
paint_balls();
gdrv::blit(
&vscreen,
xSrc,
ySrc,
xSrc + offset_x + vscreen.XPosition,
ySrc + offset_y + vscreen.YPosition,
DestWidth,
DestHeight);
unpaint_balls();
} }

View file

@ -12,30 +12,22 @@ enum class VisualType : char
struct __declspec(align(4)) render_sprite_type_struct struct __declspec(align(4)) render_sprite_type_struct
{ {
int XPosition; rectangle_type BmpRect;
int YPosition; gdrv_bitmap8* Bmp;
int Bmp8Width;
int Bmp8Height;
gdrv_bitmap8* RootBmp8;
zmap_header_type* ZMap; zmap_header_type* ZMap;
char Unknown6_0; char Unknown6_0;
VisualType VisualType; VisualType VisualType;
short Depth; __int16 Depth;
int XPosition2; rectangle_type BmpRectCopy;
int YPosition2;
int Bmp8Width2;
int Bmp8Height2;
int ZMapOffestY; int ZMapOffestY;
int ZMapOffestX; int ZMapOffestX;
int Unknown13; rectangle_type DirtyRect;
int Unknown14; render_sprite_type_struct** SpriteArray;
int Unknown15; int SpriteCount;
int Unknown16; rectangle_type BoundingRect;
int Unknown17;
int Unknown18;
visual_rect Rect;
}; };
static_assert(sizeof(render_sprite_type_struct) == 0x5c, "Wrong size render_sprite_type_struct"); static_assert(sizeof(render_sprite_type_struct) == 0x5c, "Wrong size render_sprite_type_struct");
class render class render
@ -45,12 +37,29 @@ public:
static int many_dirty, many_sprites, many_balls; static int many_dirty, many_sprites, many_balls;
static render_sprite_type_struct **dirty_list, **sprite_list, **ball_list; static render_sprite_type_struct **dirty_list, **sprite_list, **ball_list;
static zmap_header_type* background_zmap; static zmap_header_type* background_zmap;
static int zmap_offset, zmap_offsetY; static int zmap_offset, zmap_offsetY, offset_x, offset_y;
static float zscaler, zmin, zmax;
static rectangle_type vscreen_rect;
static gdrv_bitmap8 vscreen, *background_bitmap, ball_bitmap[20];
static zmap_header_type zscreen;
static void init(gdrv_bitmap8* bmp, float zMin, float zScaler, int width, int height);
static void uninit();
static void update(); static void update();
static void paint(); static void paint();
static int sprite_modified(render_sprite_type_struct* sprite); static void sprite_modified(render_sprite_type_struct* sprite);
static render_sprite_type_struct* create_sprite(VisualType visualType, gdrv_bitmap8* rootBmp8, static render_sprite_type_struct* create_sprite(VisualType visualType, gdrv_bitmap8* bmp,
zmap_header_type* zMap, zmap_header_type* zMap,
int xPosition, int yPosition, visual_rect* rect); int xPosition, int yPosition, rectangle_type* rect);
static void remove_sprite(render_sprite_type_struct* sprite);
static void remove_ball(struct render_sprite_type_struct* ball);
static void sprite_set(render_sprite_type_struct* sprite, gdrv_bitmap8* bmp, zmap_header_type* zMap, int xPos,
int yPos);
static void sprite_set_bitmap(render_sprite_type_struct* sprite, gdrv_bitmap8* bmp);
static void set_background_zmap(struct zmap_header_type* zMap, int offsetX, int offsetY);
static void ball_set(render_sprite_type_struct* sprite, gdrv_bitmap8* bmp, float depth, int xPos, int yPos);
static void repaint(struct render_sprite_type_struct* sprite);
static void paint_balls();
static void unpaint_balls();
static void shift(int offsetX, int offsetY, int xSrc, int ySrc, int DestWidth, int DestHeight);
}; };

View file

@ -10,13 +10,13 @@ int score::init()
return 1; return 1;
} }
scoreStruct* score::create(LPCSTR fieldName, int renderBgBmp) scoreStruct* score::create(LPCSTR fieldName, gdrv_bitmap8* renderBgBmp)
{ {
scoreStruct* score = (scoreStruct*)memory::allocate(sizeof(scoreStruct)); scoreStruct* score = (scoreStruct*)memory::allocate(sizeof(scoreStruct));
if (!score) if (!score)
return nullptr; return nullptr;
score->Unknown1 = -9999; score->Unknown1 = -9999;
score->RenderBgBmp = renderBgBmp; score->BackgroundBmp = renderBgBmp;
__int16* shortArr = (__int16*)partman::field_labeled(loader::loader_table, fieldName, datFieldTypes::ShortArray); __int16* shortArr = (__int16*)partman::field_labeled(loader::loader_table, fieldName, datFieldTypes::ShortArray);
if (!shortArr) if (!shortArr)
{ {

View file

@ -1,10 +1,11 @@
#pragma once #pragma once
#include "gdrv.h"
struct scoreStruct struct scoreStruct
{ {
int Unknown1; int Unknown1;
int Unknown2; int Unknown2;
int RenderBgBmp; gdrv_bitmap8* BackgroundBmp;
int Short1; int Short1;
int Short2; int Short2;
int Short3; int Short3;
@ -25,6 +26,6 @@ class score
{ {
public: public:
static int init(); static int init();
static scoreStruct* create(LPCSTR fieldName, int renderBgBmp); static scoreStruct* create(LPCSTR fieldName, gdrv_bitmap8* renderBgBmp);
static scoreStruct* dup(scoreStruct* score, int scoreIndex); static scoreStruct* dup(scoreStruct* score, int scoreIndex);
}; };

View file

@ -31,15 +31,11 @@ int zdrv::destroy_zmap(zmap_header_type* zmap)
return -1; return -1;
if (zmap->ZPtr1) if (zmap->ZPtr1)
memory::free(zmap->ZPtr1); memory::free(zmap->ZPtr1);
zmap->Width = 0; memset(zmap, 0, sizeof(zmap_header_type));
zmap->Height = 0;
zmap->Stride = 0;
zmap->ZPtr1 = nullptr;
zmap->ZPtr2 = nullptr;
return 0; return 0;
} }
void zdrv::fill(zmap_header_type* zmap, int width, int height, int xOff, int yOff, __int16 fillChar) void zdrv::fill(zmap_header_type* zmap, int width, int height, int xOff, int yOff, unsigned __int16 fillChar)
{ {
int fillCharInt = fillChar | (fillChar << 16); int fillCharInt = fillChar | (fillChar << 16);
auto zmapPtr = &zmap->ZPtr1[2 * (xOff + zmap->Stride * (zmap->Height - height - yOff))]; auto zmapPtr = &zmap->ZPtr1[2 * (xOff + zmap->Stride * (zmap->Height - height - yOff))];
@ -50,7 +46,7 @@ void zdrv::fill(zmap_header_type* zmap, int width, int height, int xOff, int yOf
unsigned int widthDiv2 = static_cast<unsigned int>(width) >> 1; unsigned int widthDiv2 = static_cast<unsigned int>(width) >> 1;
memset32(zmapPtr, fillCharInt, widthDiv2); memset32(zmapPtr, fillCharInt, widthDiv2);
__int16* lastShort = (__int16*)&zmapPtr[2 * widthDiv2]; auto lastShort = &zmapPtr[2 * widthDiv2];
for (int i = widthMod2; i; --i) for (int i = widthMod2; i; --i)
*lastShort++ = fillChar; *lastShort++ = fillChar;

View file

@ -22,7 +22,7 @@ public:
static int pad(int width); static int pad(int width);
static int create_zmap(zmap_header_type* zmap, int width, int height); static int create_zmap(zmap_header_type* zmap, int width, int height);
static int destroy_zmap(zmap_header_type* zmap); static int destroy_zmap(zmap_header_type* zmap);
static void fill(zmap_header_type* zmap, int width, int height, int xOff, int yOff, __int16 fillChar); static void fill(zmap_header_type* zmap, int width, int height, int xOff, int yOff, unsigned __int16 fillChar);
static void paint(int width, int height, gdrv_bitmap8* dstBmp, int dstBmpXOff, int dstBmpYOff, static void paint(int width, int height, gdrv_bitmap8* dstBmp, int dstBmpXOff, int dstBmpYOff,
zmap_header_type* dstZMap, int dstZMapXOff, int dstZMapYOff, gdrv_bitmap8* srcBmp, int srcBmpXOff, zmap_header_type* dstZMap, int dstZMapXOff, int dstZMapYOff, gdrv_bitmap8* srcBmp, int srcBmpXOff,
int srcBmpYOff, zmap_header_type* srcZMap, int srcZMapXOff, int srcZMapYOff); int srcBmpYOff, zmap_header_type* srcZMap, int srcZMapXOff, int srcZMapYOff);