72 lines
4.2 KiB
C++
72 lines
4.2 KiB
C++
// Integration test: real x86 ASM producer -> x64 editor -> DX11 WARP texture.
|
|
static void RunViewportChecks(EditorApp& app, const char* actualEngine) {
|
|
std::error_code ec;
|
|
const auto testEngine = app.FindEnginePath();
|
|
fs::copy_file(actualEngine,testEngine,fs::copy_options::overwrite_existing,ec);
|
|
Check(!ec,"stage real ASM renderer for editor integration");
|
|
ID3D11Device* device=nullptr;
|
|
HRESULT hr=D3D11CreateDevice(nullptr,D3D_DRIVER_TYPE_WARP,nullptr,0,nullptr,0,D3D11_SDK_VERSION,&device,nullptr,nullptr);
|
|
Check(SUCCEEDED(hr),"DX11 software device supports the embedded viewport");
|
|
if(!device || ec) return;
|
|
app.LoadLevel("../assets/scene.dat"); app.showCutsceneTimeline=true; app.previewAttempted=false;
|
|
app.InitD3D(device);
|
|
auto pump = [&]() {
|
|
int frames=0; ULONGLONG until=GetTickCount64()+5000;
|
|
while(frames<3 && GetTickCount64()<until) {
|
|
if(app.previewPacket && InterlockedCompareExchange(&app.previewPacket->state,0,0)==2) ++frames;
|
|
app.UpdateEnginePreview();
|
|
if(!app.previewError.empty()) break;
|
|
Sleep(2);
|
|
}
|
|
return frames>=3 && app.previewError.empty();
|
|
};
|
|
Check(pump() && app.previewSRV && app.previewHasFrame,"real ASM frames arrive in the editor DX11 viewport");
|
|
auto before=app.previewPixels;
|
|
app.map[3][4]=CELL_METAL;
|
|
Check(pump() && app.previewPixels!=before,"unsaved geometry updates the live game view");
|
|
app.map[3][4]=CELL_EMPTY;
|
|
app.ScrubCutscene(2);
|
|
Check(pump() && app.previewPacket->x==224 && app.previewPacket->angle==0 && app.previewPacket->fade==8,
|
|
"timeline scrub drives the actual ASM viewport camera and fade");
|
|
if(app.previewTexture) {
|
|
D3D11_TEXTURE2D_DESC desc{};app.previewTexture->GetDesc(&desc);
|
|
desc.Usage=D3D11_USAGE_STAGING;desc.BindFlags=0;desc.CPUAccessFlags=D3D11_CPU_ACCESS_READ;
|
|
ID3D11Texture2D* staging=nullptr;
|
|
device->CreateTexture2D(&desc,nullptr,&staging);
|
|
ID3D11DeviceContext* context=nullptr;device->GetImmediateContext(&context);
|
|
bool equal=false;
|
|
if(staging) {
|
|
context->CopyResource(staging,app.previewTexture);
|
|
D3D11_MAPPED_SUBRESOURCE read{};
|
|
if(SUCCEEDED(context->Map(staging,0,D3D11_MAP_READ,0,&read))) {
|
|
equal=true;
|
|
for(int y=0;y<240;++y) if(memcmp(static_cast<const char*>(read.pData)+y*read.RowPitch,
|
|
app.previewPixels.data()+y*320,1280)) equal=false;
|
|
context->Unmap(staging,0);
|
|
}
|
|
staging->Release();
|
|
}
|
|
Check(equal,"DX11 texture pixels match the ASM framebuffer with opaque alpha");
|
|
context->Release();
|
|
}
|
|
app.LoadLevel("../assets/lit.dat");app.showCutsceneTimeline=false;app.lightingMode=1;
|
|
Check(pump(),"saved static lighting arrives in the live viewport");
|
|
auto bakedFrame=app.previewPixels;app.lightingMode=2;
|
|
Check(pump() && app.previewPixels!=bakedFrame && app.previewPacket->lightCount==2,
|
|
"authored dynamic lights visibly affect the embedded game view");
|
|
auto dynamicFrame=app.previewPixels;app.lightSources[1].x+=256;
|
|
Check(pump() && app.previewPixels!=dynamicFrame,"moving a dynamic light updates the image without rebaking");
|
|
app.StopEnginePreview();
|
|
Check(!app.previewProcess.hProcess && !app.previewPacket && !app.previewMapping,"closing viewport releases renderer process and mapping");
|
|
app.ShutdownD3D();device->Release();app.showCutsceneTimeline=false;
|
|
const auto demo=fs::path(actualEngine).parent_path()/"examples/cutscene_demo/assets/map.dat";
|
|
Check(app.LoadLevel(demo.string()),"isolated cutscene demo loads in the editor");
|
|
std::string start,executable;
|
|
Check(app.PreparePlaytest(start,executable),"demo F5 validates both rooms and packages its WAV");
|
|
app.CleanupPlaytest();
|
|
CutscenePreview demoPreview;
|
|
demoPreview.Start(app.playerStartX*64+32,app.playerStartY*64+32,app.playerStartAngle);
|
|
while(demoPreview.active && demoPreview.tick<1000) demoPreview.Step(app.cutscene);
|
|
Check(demoPreview.transition==0 && demoPreview.x==800 && demoPreview.y==544 && demoPreview.angle==0,
|
|
"demo camera reaches final waypoint and dispatches its room transition");
|
|
}
|