Skip to content

Commit

Permalink
ags4-auto-test: sync engine render test with ags3
Browse files Browse the repository at this point in the history
  • Loading branch information
ivan-mogilko committed Apr 6, 2024
1 parent 497dac2 commit f337ae6
Show file tree
Hide file tree
Showing 6 changed files with 248 additions and 0 deletions.
35 changes: 35 additions & 0 deletions ags4/auto-test/Game.agf
Original file line number Diff line number Diff line change
Expand Up @@ -1194,6 +1194,41 @@
</Sprite>
</Sprites>
</SpriteFolder>
<SpriteFolder Name="EngineRenderTests">
<SubFolders />
<Sprites>
<Sprite Slot="5" Width="32" Height="32" ColorDepth="32" Resolution="Real" AlphaChannel="True">
<Source>
<FileName>Sprites/EngineRenderTests/32x32-red.png</FileName>
<OffsetX>0</OffsetX>
<OffsetY>0</OffsetY>
<ImportHeight>32</ImportHeight>
<ImportWidth>32</ImportWidth>
<ImportAsTile>False</ImportAsTile>
<Frame>0</Frame>
<RemapToGamePalette>False</RemapToGamePalette>
<RemapToRoomPalette>False</RemapToRoomPalette>
<ImportMethod>LeaveAsIs</ImportMethod>
<ImportAlphaChannel>True</ImportAlphaChannel>
</Source>
</Sprite>
<Sprite Slot="6" Width="32" Height="32" ColorDepth="32" Resolution="Real" AlphaChannel="True">
<Source>
<FileName>Sprites/EngineRenderTests/32x32-yellow.png</FileName>
<OffsetX>0</OffsetX>
<OffsetY>0</OffsetY>
<ImportHeight>32</ImportHeight>
<ImportWidth>32</ImportWidth>
<ImportAsTile>False</ImportAsTile>
<Frame>0</Frame>
<RemapToGamePalette>False</RemapToGamePalette>
<RemapToRoomPalette>False</RemapToRoomPalette>
<ImportMethod>LeaveAsIs</ImportMethod>
<ImportAlphaChannel>True</ImportAlphaChannel>
</Source>
</Sprite>
</Sprites>
</SpriteFolder>
</SubFolders>
<Sprites>
<Sprite Slot="0" Width="1" Height="1" ColorDepth="8" Resolution="Real" AlphaChannel="False">
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified ags4/auto-test/acsprset.spr
Binary file not shown.
Binary file modified ags4/auto-test/sprindex.dat
Binary file not shown.
213 changes: 213 additions & 0 deletions ags4/auto-test/test-enginerender.asc
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,20 @@ void _HideControls(GUI *parent)
}
}

bool _MatchSurfaceRects(DrawingSurface *test_ds, DrawingSurface *match_ds,
int rx, int ry, int rw, int rh)
{
for (int y = 0; y < rh; y++) {
for (int x = 0; x < rw; x++) {
if (test_ds.GetPixel(x + rx, y + ry) != match_ds.GetPixel(x, y)) {
return false;
}
}
}

return true;
}

// Takes screenshot 1:1 and compares a part of the image with the given sprite
bool _TakeScreenshotAndCompareRect(int rx, int ry, int rw, int rh, DynamicSprite *match_with)
{
Expand All @@ -36,6 +50,112 @@ bool _TakeScreenshotAndCompareRect(int rx, int ry, int rw, int rh, DynamicSprite
return true;
}

bool _TakeScreenshotAndCompareRect2(int r1x, int r1y, int r1w, int r1h, DynamicSprite *match_with1,
int r2x, int r2y, int r2w, int r2h, DynamicSprite *match_with2)
{
DynamicSprite *shot = DynamicSprite.CreateFromScreenShot(Screen.Width, Screen.Height);
DrawingSurface *test_ds = shot.GetDrawingSurface();
DrawingSurface *match_ds1 = match_with1.GetDrawingSurface();
DrawingSurface *match_ds2 = match_with2.GetDrawingSurface();

if (!_MatchSurfaceRects(test_ds, match_ds1, r1x, r1y, r1w, r1h)) {
return false;
}
if (!_MatchSurfaceRects(test_ds, match_ds2, r2x, r2y, r2w, r2h)) {
return false;
}
return true;
}

void _SetSpriteAndTest(Object *obj, int sprnum, DynamicSprite *dynspr, const string test_name)
{
obj.Graphic = sprnum;
if (dynspr == null) {
dynspr = DynamicSprite.CreateFromExistingSprite(sprnum, true);
}
Wait(1); // let them redraw
tap.ok(
_TakeScreenshotAndCompareRect(obj.X, obj.Y - dynspr.Height, dynspr.Width, dynspr.Height, dynspr),
test_name);
}

void _SetSpriteAndTest2(Object *obj1, Object *obj2, int sprnum1, DynamicSprite *spr1, int sprnum2, DynamicSprite *spr2, const string test_name)
{
obj1.Graphic = sprnum1;
obj2.Graphic = sprnum2;
if (spr1 == null) {
spr1 = DynamicSprite.CreateFromExistingSprite(sprnum1, true);
}
if (spr2 == null) {
spr2 = DynamicSprite.CreateFromExistingSprite(sprnum2, true);
}
Wait(1); // let them redraw
tap.ok(
_TakeScreenshotAndCompareRect2(obj1.X, obj1.Y - spr1.Height, spr1.Width, spr1.Height, spr1,
obj2.X, obj2.Y - spr2.Height, spr2.Width, spr2.Height, spr2),
test_name);
}

void _TestObjectMatchSprite2(Object *obj1, Object *obj2, DynamicSprite *dynspr, const string test_name)
{
Wait(1); // let them redraw
tap.ok(
_TakeScreenshotAndCompareRect2(obj1.X, obj1.Y - dynspr.Height, dynspr.Width, dynspr.Height, dynspr,
obj2.X, obj2.Y - dynspr.Height, dynspr.Width, dynspr.Height, dynspr),
test_name);
}

void _UpdateSpriteAndTest(Object *obj, DynamicSprite *dynspr, int color, const string test_name)
{
_FillSprite(dynspr, color);
Wait(1);
tap.ok(
_TakeScreenshotAndCompareRect(obj.X, obj.Y - dynspr.Height, dynspr.Width, dynspr.Height, dynspr),
test_name);
}

void _UpdateSpriteAndTest2(Object *obj1, Object *obj2, DynamicSprite *dynspr, int color, const string test_name)
{
_FillSprite(dynspr, color);
Wait(1); // let them redraw
tap.ok(
_TakeScreenshotAndCompareRect2(obj1.X, obj1.Y - dynspr.Height, dynspr.Width, dynspr.Height, dynspr,
obj2.X, obj2.Y - dynspr.Height, dynspr.Width, dynspr.Height, dynspr),
test_name);
}

DynamicSprite *_RecreateSpriteAndTest(Object *obj, DynamicSprite *dynspr, int color, const string test_name)
{
int width = dynspr.Width;
int height = dynspr.Height;
dynspr.Delete(); // recreate the sprite
dynspr = DynamicSprite.Create(width, height);
_FillSprite(dynspr, color);
obj.Graphic = dynspr.Graphic;
Wait(1); // let them redraw
tap.ok(
_TakeScreenshotAndCompareRect(obj.X, obj.Y - dynspr.Height, dynspr.Width, dynspr.Height, dynspr),
test_name);
return dynspr;
}

DynamicSprite *_RecreateSpriteAndTest2(Object *obj1, Object *obj2, DynamicSprite *dynspr, int color, const string test_name)
{
int width = dynspr.Width;
int height = dynspr.Height;
dynspr.Delete(); // recreate the sprite
dynspr = DynamicSprite.Create(width, height);
_FillSprite(dynspr, color);
obj1.Graphic = dynspr.Graphic;
obj2.Graphic = dynspr.Graphic;
Wait(1); // let them redraw
tap.ok(
_TakeScreenshotAndCompareRect2(obj1.X, obj1.Y - dynspr.Height, dynspr.Width, dynspr.Height, dynspr,
obj2.X, obj2.Y - dynspr.Height, dynspr.Width, dynspr.Height, dynspr),
test_name);
return dynspr;
}

void TestEngineRender()
{
tap.Comment("start EngineRender tests");
Expand Down Expand Up @@ -360,5 +480,98 @@ void TestEngineRender()
dynspr.Delete();
}

//
// Object switching from static to dynamic sprite and back:
// should keep updating itself after any change or if dynamic sprite changed
// while it was assigned to object. This test is for sprite update
// notification mechanism keeping working seamlessly while switching between
// sprites of two kinds.
//
{
int static_spr1 = 5;
int static_spr2 = 6;
int spr_width = Game.SpriteWidth[static_spr1];
int spr_height = Game.SpriteHeight[static_spr1];
int color1 = 10;
int color2 = 11;
int color3 = 12;
DynamicSprite* dynspr1 = DynamicSprite.Create(spr_width, spr_height);
_FillSprite(dynspr1, color1);
DynamicSprite* dynspr2 = DynamicSprite.Create(spr_width, spr_height);
_FillSprite(dynspr2, color2);

Object* oDynamicObject = object[0];
oDynamicObject.X = 100;
oDynamicObject.Y = 100;
oDynamicObject.Visible = true;

_SetSpriteAndTest(oDynamicObject, static_spr1, null, "Object graphic sequence 1");
_SetSpriteAndTest(oDynamicObject, dynspr1.Graphic, dynspr1, "Object graphic sequence 2");
_SetSpriteAndTest(oDynamicObject, static_spr1, null, "Object graphic sequence 3");
_SetSpriteAndTest(oDynamicObject, static_spr2, null, "Object graphic sequence 4");
_SetSpriteAndTest(oDynamicObject, dynspr1.Graphic, dynspr1, "Object graphic sequence 5");
_SetSpriteAndTest(oDynamicObject, dynspr2.Graphic, dynspr2, "Object graphic sequence 6");
_SetSpriteAndTest(oDynamicObject, static_spr1, null, "Object graphic sequence 7");
_SetSpriteAndTest(oDynamicObject, dynspr1.Graphic, dynspr1, "Object graphic sequence 8");
_UpdateSpriteAndTest(oDynamicObject, dynspr1, color2, "Object graphic sequence 9");
_UpdateSpriteAndTest(oDynamicObject, dynspr1, color3, "Object graphic sequence 10");
_SetSpriteAndTest(oDynamicObject, static_spr1, null, "Object graphic sequence 11");
_SetSpriteAndTest(oDynamicObject, dynspr1.Graphic, dynspr1, "Object graphic sequence 12");
dynspr1 = _RecreateSpriteAndTest(oDynamicObject, dynspr1, color1, "Object graphic sequence 13");
dynspr1 = _RecreateSpriteAndTest(oDynamicObject, dynspr1, color2, "Object graphic sequence 14");
_SetSpriteAndTest(oDynamicObject, static_spr1, null, "Object graphic sequence 15");

oDynamicObject.Visible = false;
}

//
// Two objects updated in parallel.
// Test multiple objects sharing same static or dynamic sprites
// and being able to update in sync.
//
{
int static_spr1 = 5;
int static_spr2 = 6;
int spr_width = Game.SpriteWidth[static_spr1];
int spr_height = Game.SpriteHeight[static_spr1];
int color1 = 10;
int color2 = 11;
int color3 = 12;
int color4 = 13;
DynamicSprite* dynspr1 = DynamicSprite.Create(spr_width, spr_height);
_FillSprite(dynspr1, color1);
DynamicSprite* dynspr2 = DynamicSprite.Create(spr_width, spr_height);
_FillSprite(dynspr2, color2);

Object* oDynamicObject1 = object[0];
Object* oDynamicObject2 = object[1];
oDynamicObject1.X = 100;
oDynamicObject1.Y = 100;
oDynamicObject1.Visible = true;
oDynamicObject2.X = 200;
oDynamicObject2.Y = 100;
oDynamicObject2.Visible = true;

_SetSpriteAndTest2(oDynamicObject1, oDynamicObject2, static_spr1, null, static_spr1, null, "Two objects graphic sequence 1");
_SetSpriteAndTest2(oDynamicObject1, oDynamicObject2, dynspr1.Graphic, dynspr1, dynspr1.Graphic, dynspr1, "Two objects graphic sequence 2");
_UpdateSpriteAndTest2(oDynamicObject1, oDynamicObject2, dynspr1, color2, "Two objects graphic sequence 3");
oDynamicObject2.Visible = false; // do one pass with 1 object disabled
_UpdateSpriteAndTest(oDynamicObject1, dynspr1, color3, "Two objects graphic sequence 4");
oDynamicObject2.Visible = true; // enable and make a pass, make sure it syncs again
_TestObjectMatchSprite2(oDynamicObject1, oDynamicObject2, dynspr1, "Two objects graphic sequence 5");
dynspr1 = _RecreateSpriteAndTest2(oDynamicObject1, oDynamicObject2, dynspr1, color1, "Two objects graphic sequence 6");
oDynamicObject2.Visible = false; // do one pass with 1 object disabled
dynspr1 = _RecreateSpriteAndTest(oDynamicObject1, dynspr1, color2, "Two objects graphic sequence 7");
oDynamicObject2.Visible = true; // enable and make a pass, make sure it syncs again
_TestObjectMatchSprite2(oDynamicObject1, oDynamicObject2, dynspr1, "Two objects graphic sequence 8");
// Now test some quick sequence where they change to different sprites
_SetSpriteAndTest2(oDynamicObject1, oDynamicObject2, static_spr1, null, static_spr2, null, "Two objects graphic sequence 9");
_SetSpriteAndTest2(oDynamicObject1, oDynamicObject2, dynspr1.Graphic, dynspr1, static_spr2, null, "Two objects graphic sequence 10");
_SetSpriteAndTest2(oDynamicObject1, oDynamicObject2, dynspr1.Graphic, dynspr1, dynspr1.Graphic, dynspr1, "Two objects graphic sequence 11");
_SetSpriteAndTest2(oDynamicObject1, oDynamicObject2, dynspr2.Graphic, dynspr2, dynspr1.Graphic, dynspr1, "Two objects graphic sequence 12");
_SetSpriteAndTest2(oDynamicObject1, oDynamicObject2, dynspr2.Graphic, dynspr2, dynspr2.Graphic, dynspr2, "Two objects graphic sequence 13");
_SetSpriteAndTest2(oDynamicObject1, oDynamicObject2, static_spr1, null, static_spr2, null, "Two objects graphic sequence 14");
}

tap.Comment("end EngineRender tests");
}

0 comments on commit f337ae6

Please sign in to comment.