EBLAN_ENGINE/tests/lighting_editor_checks.inl

65 lines
4.9 KiB
C++

static void RunLightingChecks(EditorApp& app) {
app.InitDefaultLevel();app.sprites.clear();app.transitions.clear();app.lightSources.clear();
memset(app.map,0,sizeof(app.map));
for(int i=0;i<32;++i){app.map[0][i]=app.map[31][i]=app.map[i][0]=app.map[i][31]=1;app.map[i][10]=1;}
app.playerStartX=2;app.playerStartY=5;app.playerStartAngle=0;
app.lightingMode=2;app.ambientLightLevel=10;app.isFlashlightOn=false;
EditorLightSource fixed;fixed.x=352;fixed.y=352;fixed.radius=900;fixed.intensity=220;fixed.curIntensity=220;
fixed.lightType=LIGHT_TYPE_STATIC;fixed.flags=LIGHT_FLAG_ACTIVE|LIGHT_FLAG_SHADOWS;fixed.color=0xFF0000;
app.lightSources.push_back(fixed);app.BakeLighting();
auto red=app.bakedLightRGB[5*32+5];
Check(((red>>16)&255)>100 && (red&0xFFFF)==0x0A0A,"static bake preserves RGB light color");
Check(app.bakedLightRGB[5*32+14]==0x0A0A0A,"baked light cannot cross a wall or smooth through it");
auto before=app.bakedLightRGB;
EditorLightSource moving=fixed;moving.x=480;moving.lightType=LIGHT_TYPE_POINT;moving.color=0x0000FF;
app.lightSources.push_back(moving);app.BakeLighting();
Check(app.bakedLightRGB==before,"dynamic lights never enter the static bake");
app.map[5][7]=CELL_DOOR;
Check(!app.CastLightRay(352,352,608,352),"closed door blocks editor light rays");
app.map[5][7]=CELL_DOOR_OPEN;
Check(app.CastLightRay(352,352,608,352),"open door transmits editor light rays");
app.map[5][7]=0;app.map[5][6]=1;
Check(!app.CastLightRay(352,352,416,416),"diagonal light cannot leak through a blocked corner");
app.map[5][6]=0;
app.lightSources[0].flags=LIGHT_FLAG_ACTIVE;app.BakeLighting();
Check(((app.bakedLightRGB[5*32+14]>>16)&255)>10,"disabling shadows permits light across walls");
app.lightSources[0].flags|=LIGHT_FLAG_SHADOWS;app.BakeLighting();
app.PushUndo();app.lightSources[0].color=0x00FF00;app.ambientLightLevel=25;app.lightingMode=1;app.BakeLighting();
app.Undo();
Check(app.lightSources[0].color==0xFF0000 && app.ambientLightLevel==10 && app.lightingMode==2 && app.bakedLightRGB==before,
"undo restores sources, settings and the exact baked RGB data");
app.Redo();Check(app.lightSources[0].color==0x00FF00 && app.ambientLightLevel==25,"redo restores authored lighting");
app.Undo();
app.lightSources[0].x+=1;
Check(app.LightingNeedsBake(),"editing static lights marks the bake out of date");
app.lightSources[0].x-=1;app.lightSources[1].x+=64;
Check(!app.LightingNeedsBake(),"moving a realtime source does not invalidate static lighting");
app.lightSources[1].x-=64;
Check(app.SaveLevel("../assets/lit.dat"),"save v5 authored lights and persistent RGB bake");
std::ofstream reference("../assets/lighting_reference.bin",std::ios::binary);
reference.write(reinterpret_cast<const char*>(app.bakedLightRGB.data()),4096);reference.close();
auto valid=Bytes("../assets/lit.dat");
BinaryLevel loaded;std::string error;
Check(ReadLevelFile("../assets/lit.dat",loaded,error) && loaded.header.version==5 && loaded.lighting.lights.size()==2 &&
loaded.lighting.settings.flashlight==0 && loaded.lighting.rgb==app.bakedLightRGB,"v5 lighting round trip is lossless");
app.lightSources[0].radius=0;
Check(!app.SaveLevel("../assets/lit.dat") && Bytes("../assets/lit.dat")==valid,"invalid light cannot overwrite an existing level");
app.lightSources[0].radius=900;
app.lightSources[0].lightType=LIGHT_TYPE_BURST;
Check(!app.SaveLevel("../assets/lit.dat") && Bytes("../assets/lit.dat")==valid,"internal burst slots cannot be serialized as authored lights");
app.lightSources[0].lightType=LIGHT_TYPE_STATIC;
auto bad=valid;bad[34]=14;
{std::ofstream out("../assets/lit_badcount.dat",std::ios::binary);out.write(reinterpret_cast<const char*>(bad.data()),bad.size());}
bad=valid;uint32_t invalidRadius=0; // settings start after header and grid; no sprites, transitions or script
memcpy(bad.data()+38+1024+32+8,&invalidRadius,4);
{std::ofstream out("../assets/lit_badradius.dat",std::ios::binary);out.write(reinterpret_cast<const char*>(bad.data()),bad.size());}
bad=valid;bad.back()=255;
{std::ofstream out("../assets/lit_badrgb.dat",std::ios::binary);out.write(reinterpret_cast<const char*>(bad.data()),bad.size());}
Check(!app.LoadLevel("../assets/lit_badcount.dat") && app.lightSources.size()==2,"malformed lighting count preserves the editor scene");
Check(!app.LoadLevel("../assets/lit_badradius.dat"),"malformed light radius rejected before scene replacement");
Check(!app.LoadLevel("../assets/lit_badrgb.dat"),"invalid baked RGB padding rejected before scene replacement");
std::string start,engine;
Check(app.PreparePlaytest(start,engine),"F5 packages v5 lighting with the current unsaved map");app.CleanupPlaytest();
app.LoadLevel("../assets/map.dat");
Check(app.lightSources.empty() && app.lightingMode==0,"legacy maps clear old lights and retain classic rendering");
}