30#include <wx/sstream.h>
32#include <wx/translation.h>
56 uint32_t w1 = aStream.
ReadU32();
57 uint32_t w2 = aStream.
ReadU32();
78 const uint32_t a = aStream.
ReadU32();
79 const uint32_t b = aStream.
ReadU32();
82 const uint64_t
combined = (
static_cast<uint64_t
>( a ) << 32 ) + b;
91template <
typename ARRAY>
94 for(
size_t i = 0; i < aArray.size(); i++ )
105 if constexpr( std::is_same_v<T, uint32_t> )
109 else if constexpr( std::is_same_v<T, uint8_t> )
113 else if constexpr( std::is_same_v<T, uint16_t> )
117 else if constexpr( std::is_same_v<T, int16_t> )
121 else if constexpr( std::is_same_v<T, int32_t> )
125 else if constexpr( std::is_same_v<T, FILE_HEADER::LINKED_LIST> )
127 field =
ReadLL( aStream, aFmtVer );
129 else if constexpr(
requires { std::tuple_size<T>::value; } )
131 for(
size_t i = 0; i < std::tuple_size_v<T>; ++i )
147template <
typename COND_T>
150 if( aField.exists( aFmtVer ) )
159 uint32_t masked = aMagic & 0xFFFFFF00;
182 uint32_t majorVer = ( aMagic >> 16 ) & 0xFFFF;
184 if( majorVer <= 0x0012 )
189 THROW_IO_ERROR( wxString::Format(
"Unknown Allegro file version %#010x (rev %d)", aMagic, majorVer - 3 ) );
195 auto header = std::make_unique<ALLEGRO::FILE_HEADER>();
196 const size_t headerStartPos =
m_stream.Position();
198 uint32_t fileMagic =
m_stream.ReadU32();
201 header->m_Magic = fileMagic;
268 wxASSERT(
m_stream.Position() - headerStartPos == 0xF8 );
270 wxASSERT(
m_stream.Position() - headerStartPos == 0x124 );
293 THROW_IO_ERROR( wxString::Format(
"Unknown board units %d", units ) );
318 for(
size_t i = 0; i <
header->m_LayerMap.size(); ++i )
325 header->GetStringsCount() );
335 for( uint32_t i = 0; i < count; ++i )
337 uint32_t
id = stream.
ReadU32();
347 uint8_t classCode = aStream.
ReadU8();
348 uint8_t subclassCode = aStream.
ReadU8();
353 .m_Class = classCode,
354 .m_Subclass = subclassCode,
361 auto block = std::make_unique<BLOCK<BLK_0x01_ARC>>( 0x01, aStream.
Position() );
363 auto& data = block->GetData();
367 data.m_UnknownByte = aStream.
ReadU8();
368 data.m_SubType = aStream.
ReadU8();
369 data.m_Key = aStream.
ReadU32();
370 data.m_Next = aStream.
ReadU32();
371 data.m_Parent = aStream.
ReadU32();
372 data.m_Unknown1 = aStream.
ReadU32();
374 ReadCond( aStream, aVer, data.m_Unknown6 );
376 data.m_Width = aStream.
ReadU32();
378 data.m_StartX = aStream.
ReadS32();
379 data.m_StartY = aStream.
ReadS32();
380 data.m_EndX = aStream.
ReadS32();
381 data.m_EndY = aStream.
ReadS32();
387 for(
size_t i = 0; i < data.m_BoundingBoxCoords.size(); ++i )
389 data.m_BoundingBoxCoords[i] = aStream.
ReadS32();
398 auto block = std::make_unique<BLOCK<BLK_0x03_FIELD>>( 0x03, aStream.
Position() );
400 auto& data = block->GetData();
404 data.m_Hdr1 = aStream.
ReadU16();
405 data.m_Key = aStream.
ReadU32();
406 data.m_Next = aStream.
ReadU32();
408 ReadCond( aStream, aVer, data.m_Unknown1 );
410 data.m_SubType = aStream.
ReadU8();
411 data.m_Hdr2 = aStream.
ReadU8();
412 data.m_Size = aStream.
ReadU16();
414 ReadCond( aStream, aVer, data.m_Unknown2 );
419 switch( data.m_SubType )
429 data.m_Substruct = aStream.
ReadU32();
434 data.m_Substruct = std::array<uint32_t, 2>{
460 "Block 0x03 subtype 0x6C entry count %u exceeds limit at offset %#010zx",
470 data.m_Substruct = std::move( sub );
481 const size_t numEntries = ( sub.
m_X1 + 4 * sub.
m_X0 );
483 for(
size_t i = 0; i < numEntries; ++i )
487 data.m_Substruct = std::move( sub );
493 for(
size_t i = 0; i < sub.
m_Entries.size(); ++i )
497 data.m_Substruct = std::move( sub );
502 if( data.m_Size == 4 )
504 data.m_Substruct = aStream.
ReadU32();
506 else if( data.m_Size == 8 )
508 std::array<uint32_t, 2> sub;
511 data.m_Substruct = std::move( sub );
516 wxString::Format(
"Unknown substruct type %#02x with size %d", data.m_SubType, data.m_Size ) );
528 auto block = std::make_unique<BLOCK<BLK_0x04_NET_ASSIGNMENT>>( 0x04, aStream.
Position() );
530 auto& data = block->GetData();
532 data.m_Type = aStream.
ReadU8();
534 data.m_Key = aStream.
ReadU32();
535 data.m_Next = aStream.
ReadU32();
536 data.m_Net = aStream.
ReadU32();
537 data.m_ConnItem = aStream.
ReadU32();
539 ReadCond( aStream, aVer, data.m_Unknown );
547 auto block = std::make_unique<BLOCK<BLK_0x05_TRACK>>( 0x05, aStream.
Position() );
549 auto& data = block->GetData();
554 data.m_Key = aStream.
ReadU32();
555 data.m_Next = aStream.
ReadU32();
556 data.m_NetAssignment = aStream.
ReadU32();
557 data.m_UnknownPtr1 = aStream.
ReadU32();
558 data.m_Unknown2 = aStream.
ReadU32();
559 data.m_Unknown3 = aStream.
ReadU32();
560 data.m_UnknownPtr2a = aStream.
ReadU32();
561 data.m_UnknownPtr2b = aStream.
ReadU32();
562 data.m_Unknown4 = aStream.
ReadU32();
563 data.m_UnknownPtr3a = aStream.
ReadU32();
564 data.m_UnknownPtr3b = aStream.
ReadU32();
566 ReadCond( aStream, aVer, data.m_Unknown5a );
567 ReadCond( aStream, aVer, data.m_Unknown5b );
569 data.m_FirstSegPtr = aStream.
ReadU32();
570 data.m_UnknownPtr5 = aStream.
ReadU32();
571 data.m_Unknown6 = aStream.
ReadU32();
579 auto block = std::make_unique<BLOCK<BLK_0x06_COMPONENT>>( 0x06, stream.
Position() );
581 auto& data = block->GetData();
586 data.m_Next = stream.
ReadU32();
587 data.m_CompDeviceType = stream.
ReadU32();
588 data.m_SymbolName = stream.
ReadU32();
589 data.m_FirstInstPtr = stream.
ReadU32();
590 data.m_PtrFunctionSlot = stream.
ReadU32();
591 data.m_PtrPinNumber = stream.
ReadU32();
592 data.m_Fields = stream.
ReadU32();
594 ReadCond( stream, aVer, data.m_Unknown1 );
602 auto block = std::make_unique<BLOCK<BLK_0x07_COMPONENT_INST>>( 0x07, stream.
Position() );
604 auto& data = block->GetData();
609 data.m_Next = stream.
ReadU32();
611 ReadCond( stream, aVer, data.m_UnknownPtr1 );
612 ReadCond( stream, aVer, data.m_Unknown2 );
613 ReadCond( stream, aVer, data.m_Unknown3 );
615 data.m_FpInstPtr = stream.
ReadU32();
617 ReadCond( stream, aVer, data.m_Unknown4 );
619 data.m_RefDesStrPtr = stream.
ReadU32();
620 data.m_FunctionInstPtr = stream.
ReadU32();
621 data.m_X03Ptr = stream.
ReadU32();
622 data.m_Unknown5 = stream.
ReadU32();
623 data.m_FirstPadPtr = stream.
ReadU32();
631 auto block = std::make_unique<BLOCK<BLK_0x08_PIN_NUMBER>>( 0x08, aStream.
Position() );
633 auto& data = block->GetData();
635 data.m_Type = aStream.
ReadU8();
637 data.m_Key = aStream.
ReadU32();
639 ReadCond( aStream, aVer, data.m_Previous );
640 ReadCond( aStream, aVer, data.m_StrPtr16x );
642 data.m_Next = aStream.
ReadU32();
644 ReadCond( aStream, aVer, data.m_StrPtr );
646 data.m_PinNamePtr = aStream.
ReadU32();
648 ReadCond( aStream, aVer, data.m_Unknown1 );
650 data.m_Ptr4 = aStream.
ReadU32();
658 auto block = std::make_unique<BLOCK<BLK_0x09_FILL_LINK>>( 0x09, aStream.
Position() );
660 auto& data = block->GetData();
664 data.m_Key = aStream.
ReadU32();
666 for(
size_t i = 0; i < data.m_UnknownArray.size(); ++i )
668 data.m_UnknownArray[i] = aStream.
ReadU32();
671 ReadCond( aStream, aVer, data.m_Unknown1 );
673 data.m_UnknownPtr1 = aStream.
ReadU32();
674 data.m_UnknownPtr2 = aStream.
ReadU32();
675 data.m_Unknown2 = aStream.
ReadU32();
676 data.m_UnknownPtr3 = aStream.
ReadU32();
677 data.m_UnknownPtr4 = aStream.
ReadU32();
679 ReadCond( aStream, aVer, data.m_Unknown3 );
687 auto block = std::make_unique<BLOCK<BLK_0x0A_DRC>>( 0x0A, aStream.
Position() );
689 auto& data = block->GetData();
691 data.m_T = aStream.
ReadU8();
693 data.m_Key = aStream.
ReadU32();
694 data.m_Next = aStream.
ReadU32();
695 data.m_Unknown1 = aStream.
ReadU32();
697 ReadCond( aStream, aVer, data.m_Unknown2 );
699 for(
size_t i = 0; i < data.m_Coords.size(); ++i )
701 data.m_Coords[i] = aStream.
ReadS32();
707 ReadCond( aStream, aVer, data.m_Unknown6 );
715 auto block = std::make_unique<BLOCK<BLK_0x0C_PIN_DEF>>( 0x0C, aStream.
Position() );
717 auto& data = block->GetData();
719 data.m_T = aStream.
ReadU8();
722 data.m_Key = aStream.
ReadU32();
723 data.m_Next = aStream.
ReadU32();
725 data.m_Unknown1 = aStream.
ReadU32();
726 data.m_Unknown2 = aStream.
ReadU32();
729 ReadCond( aStream, aVer, data.m_Shape );
730 ReadCond( aStream, aVer, data.m_DrillChar );
731 ReadCond( aStream, aVer, data.m_UnknownPadding );
734 ReadCond( aStream, aVer, data.m_Shape16x );
735 ReadCond( aStream, aVer, data.m_DrillChars );
736 ReadCond( aStream, aVer, data.m_Unknown_16x );
738 data.m_Unknown4 = aStream.
ReadU32();
739 ReadCond( aStream, aVer, data.m_Unknown5 );
741 for(
size_t i = 0; i < data.m_Coords.size(); ++i )
743 data.m_Coords[i] = aStream.
ReadS32();
746 for(
size_t i = 0; i < data.m_Size.size(); ++i )
748 data.m_Size[i] = aStream.
ReadS32();
751 data.m_GroupPtr = aStream.
ReadU32();
752 data.m_Unknown6 = aStream.
ReadU32();
753 data.m_Unknown7 = aStream.
ReadU32();
755 ReadCond( aStream, aVer, data.m_Unknown8 );
763 auto block = std::make_unique<BLOCK<BLK_0x0D_PAD>>( 0x0D, aStream.
Position() );
765 auto& data = block->GetData();
769 data.m_Key = aStream.
ReadU32();
770 data.m_NameStrId = aStream.
ReadU32();
771 data.m_Next = aStream.
ReadU32();
773 ReadCond( aStream, aVer, data.m_Unknown1 );
775 data.m_CoordsX = aStream.
ReadS32();
776 data.m_CoordsY = aStream.
ReadS32();
778 data.m_PadStack = aStream.
ReadU32();
779 data.m_Unknown2 = aStream.
ReadU32();
781 ReadCond( aStream, aVer, data.m_Unknown3 );
783 data.m_Flags = aStream.
ReadU32();
784 data.m_Rotation = aStream.
ReadU32();
792 auto block = std::make_unique<BLOCK<BLK_0x0E_RECT>>( 0x0E, aStream.
Position() );
794 auto& data = block->GetData();
796 data.m_T = aStream.
ReadU8();
798 data.m_Key = aStream.
ReadU32();
799 data.m_Next = aStream.
ReadU32();
800 data.m_FpPtr = aStream.
ReadU32();
802 data.m_Unknown1 = aStream.
ReadU32();
803 data.m_Unknown2 = aStream.
ReadU32();
804 data.m_Unknown3 = aStream.
ReadU32();
806 ReadCond( aStream, aVer, data.m_Unknown4 );
807 ReadCond( aStream, aVer, data.m_Unknown5 );
809 for(
size_t i = 0; i < data.m_Coords.size(); ++i )
811 data.m_Coords[i] = aStream.
ReadS32();
814 for(
size_t i = 0; i < data.m_UnknownArr.size(); ++i )
816 data.m_UnknownArr[i] = aStream.
ReadU32();
819 data.m_Rotation = aStream.
ReadU32();
827 auto block = std::make_unique<BLOCK<BLK_0x0F_FUNCTION_SLOT>>( 0x0F, stream.
Position() );
829 auto& data = block->GetData();
834 data.m_SlotName = stream.
ReadU32();
836 ReadCond( stream, aVer, data.m_Unknown1 );
838 stream.
ReadBytes( data.m_CompDeviceType.data(), data.m_CompDeviceType.size() );
840 ReadCond( stream, aVer, data.m_Next );
842 data.m_Ptr0x06 = stream.
ReadU32();
843 data.m_Ptr0x11 = stream.
ReadU32();
844 data.m_Unknown2 = stream.
ReadU32();
852 auto block = std::make_unique<BLOCK<BLK_0x10_FUNCTION_INST>>( 0x10, stream.
Position() );
854 auto& data = block->GetData();
860 ReadCond( stream, aVer, data.m_Unknown1 );
861 data.m_ComponentInstPtr = stream.
ReadU32();
862 ReadCond( stream, aVer, data.m_Unknown2 );
863 data.m_PtrX12 = stream.
ReadU32();
864 data.m_Unknown3 = stream.
ReadU32();
865 data.m_FunctionName = stream.
ReadU32();
866 data.m_Slots = stream.
ReadU32();
867 data.m_Fields = stream.
ReadU32();
875 auto block = std::make_unique<BLOCK<BLK_0x11_PIN_NAME>>( 0x11, aStream.
Position() );
877 auto& data = block->GetData();
879 data.m_Type = aStream.
ReadU8();
881 data.m_Key = aStream.
ReadU32();
882 data.m_PinNameStrPtr = aStream.
ReadU32();
883 data.m_Next = aStream.
ReadU32();
884 data.m_PinNumberPtr = aStream.
ReadU32();
885 data.m_Unknown1 = aStream.
ReadU32();
887 ReadCond( aStream, aVer, data.m_Unknown2 );
895 auto block = std::make_unique<BLOCK<BLK_0x12_XREF>>( 0x12, aStream.
Position() );
897 auto& data = block->GetData();
899 data.m_Type = aStream.
ReadU8();
901 data.m_Key = aStream.
ReadU32();
902 data.m_Ptr1 = aStream.
ReadU32();
903 data.m_Ptr2 = aStream.
ReadU32();
904 data.m_Ptr3 = aStream.
ReadU32();
905 data.m_Unknown1 = aStream.
ReadU32();
907 ReadCond( aStream, aVer, data.m_Unknown2 );
908 ReadCond( aStream, aVer, data.m_Unknown3 );
916 auto block = std::make_unique<BLOCK<BLK_0x14_GRAPHIC>>( 0x14, aStream.
Position() );
918 auto& data = block->GetData();
920 data.m_Type = aStream.
ReadU8();
922 data.m_Key = aStream.
ReadU32();
923 data.m_Next = aStream.
ReadU32();
924 data.m_Parent = aStream.
ReadU32();
925 data.m_Flags = aStream.
ReadU32();
927 ReadCond( aStream, aVer, data.m_Unknown2 );
929 data.m_SegmentPtr = aStream.
ReadU32();
930 data.m_Ptr0x03 = aStream.
ReadU32();
931 data.m_Ptr0x26 = aStream.
ReadU32();
939 auto block = std::make_unique<BLOCK<BLK_0x15_16_17_SEGMENT>>( aType, aStream.
Position() );
941 auto& data = block->GetData();
945 data.m_Key = aStream.
ReadU32();
946 data.m_Next = aStream.
ReadU32();
947 data.m_Parent = aStream.
ReadU32();
948 data.m_Flags = aStream.
ReadU32();
950 ReadCond( aStream, aVer, data.m_Unknown2 );
952 data.m_Width = aStream.
ReadU32();
954 data.m_StartX = aStream.
ReadS32();
955 data.m_StartY = aStream.
ReadS32();
956 data.m_EndX = aStream.
ReadS32();
957 data.m_EndY = aStream.
ReadS32();
965 auto block = std::make_unique<BLOCK<BLK_0x1B_NET>>( 0x1B, stream.
Position() );
967 auto& data = block->GetData();
972 data.m_Next = stream.
ReadU32();
973 data.m_NetName = stream.
ReadU32();
974 data.m_Unknown1 = stream.
ReadU32();
976 ReadCond( stream, aVer, data.m_Unknown2 );
978 data.m_Type = stream.
ReadU32();
979 data.m_Assignment = stream.
ReadU32();
980 data.m_Ratline = stream.
ReadU32();
981 data.m_FieldsPtr = stream.
ReadU32();
982 data.m_MatchGroupPtr = stream.
ReadU32();
983 data.m_ModelPtr = stream.
ReadU32();
984 data.m_UnknownPtr4 = stream.
ReadU32();
985 data.m_UnknownPtr5 = stream.
ReadU32();
986 data.m_UnknownPtr6 = stream.
ReadU32();
995 switch( (aVal & 0xF0) )
1012 THROW_IO_ERROR( wxString::Format(
"Unknown padstack type 0x%x", aVal ) );
1020 auto block = std::make_unique<BLOCK<BLK_0x1C_PADSTACK>>( 0x1C, aStream.
Position() );
1022 auto& data = block->GetData();
1024 data.m_UnknownByte1 = aStream.
ReadU8();
1025 data.m_N = aStream.
ReadU8();
1026 data.m_UnknownByte2 = aStream.
ReadU8();
1028 data.m_Key = aStream.
ReadU32();
1029 data.m_Next = aStream.
ReadU32();
1030 data.m_PadStr = aStream.
ReadU32();
1073 uint8_t padTypeAndA = aStream.
ReadU8();
1075 hdr.
m_A = ( padTypeAndA & 0x0F );
1116 data.m_NumFixedCompEntries = 10;
1118 data.m_NumFixedCompEntries = 11;
1120 data.m_NumFixedCompEntries = 21;
1125 const size_t nComps = data.m_NumFixedCompEntries + ( data.GetLayerCount() * data.m_NumCompsPerLayer );
1127 data.m_Components.reserve( nComps );
1128 for(
size_t i = 0; i < nComps; ++i )
1158 const size_t nElems = data.m_N * ( ( aVer <
FMT_VER::V_172 ) ? 8 : 10 );
1160 data.m_UnknownArrN.reserve( nElems );
1161 for(
size_t i = 0; i < nElems; ++i )
1163 data.m_UnknownArrN.push_back( aStream.
ReadU32() );
1173 auto block = std::make_unique<BLOCK<BLK_0x1D_CONSTRAINT_SET>>( 0x1D, aStream.
Position() );
1175 auto& data = block->GetData();
1179 data.m_Key = aStream.
ReadU32();
1180 data.m_Next = aStream.
ReadU32();
1181 data.m_NameStrKey = aStream.
ReadU32();
1182 data.m_FieldPtr = aStream.
ReadU32();
1184 data.m_SizeA = aStream.
ReadU16();
1185 data.m_SizeB = aStream.
ReadU16();
1187 data.m_DataB.resize( data.m_SizeB );
1189 for(
auto& item : data.m_DataB )
1190 aStream.
ReadBytes( item.data(), item.size() );
1192 data.m_DataA.resize( data.m_SizeA );
1194 for(
auto& item : data.m_DataA )
1195 aStream.
ReadBytes( item.data(), item.size() );
1197 ReadCond( aStream, aVer, data.m_Unknown4 );
1205 auto block = std::make_unique<BLOCK<BLK_0x1E_SI_MODEL>>( 0x1E, aStream.
Position() );
1207 auto& data = block->GetData();
1209 data.m_Type = aStream.
ReadU8();
1210 data.m_T2 = aStream.
ReadU16();
1211 data.m_Key = aStream.
ReadU32();
1212 data.m_Next = aStream.
ReadU32();
1214 ReadCond( aStream, aVer, data.m_Unknown2 );
1215 ReadCond( aStream, aVer, data.m_Unknown3 );
1217 data.m_StrPtr = aStream.
ReadU32();
1218 data.m_Size = aStream.
ReadU32();
1222 ReadCond( aStream, aVer, data.m_Unknown4 );
1230 auto block = std::make_unique<BLOCK<BLK_0x1F_PADSTACK_DIM>>( 0x1F, aStream.
Position() );
1232 auto& data = block->GetData();
1236 data.m_Key = aStream.
ReadU32();
1238 data.m_Next = aStream.
ReadU32();
1239 data.m_Unknown2 = aStream.
ReadU32();
1240 data.m_Unknown3 = aStream.
ReadU32();
1241 data.m_Unknown4 = aStream.
ReadU32();
1242 data.m_Unknown5 = aStream.
ReadU16();
1244 data.m_Size = aStream.
ReadU16();
1246 size_t substructSize = 0;
1248 substructSize = data.m_Size * 384 + 8;
1250 substructSize = data.m_Size * 280 + 8;
1252 substructSize = data.m_Size * 280 + 4;
1254 substructSize = data.m_Size * 240 + 4;
1256 data.m_Substruct.resize( substructSize );
1257 aStream.
ReadBytes( data.m_Substruct.data(), substructSize );
1265 auto block = std::make_unique<BLOCK<BLK_0x20_UNKNOWN>>( 0x20, aStream.
Position() );
1267 auto& data = block->GetData();
1269 data.m_Type = aStream.
ReadU8();
1271 data.m_Key = aStream.
ReadU32();
1272 data.m_Next = aStream.
ReadU32();
1275 ReadCond( aStream, aVer, data.m_UnknownArray2 );
1283 auto block = std::make_unique<BLOCK<BLK_0x21_BLOB>>( 0x21, aStream.
Position() );
1285 auto& data = block->GetData();
1287 data.m_Type = aStream.
ReadU8();
1290 data.m_Size = aStream.
ReadU32();
1292 if( data.m_Size < 12 )
1294 THROW_IO_ERROR( wxString::Format(
"Block 0x21 size %u too small (minimum 12) at offset %#010zx",
1295 data.m_Size, aStream.
Position() ) );
1298 data.m_Key = aStream.
ReadU32();
1300 const size_t nBytes = data.m_Size - 12;
1301 data.m_Data.resize( nBytes );
1302 aStream.
ReadBytes( data.m_Data.data(), nBytes );
1310 auto block = std::make_unique<BLOCK<BLK_0x22_UNKNOWN>>( 0x22, aStream.
Position() );
1312 auto& data = block->GetData();
1314 data.m_Type = aStream.
ReadU8();
1315 data.m_T2 = aStream.
ReadU16();
1316 data.m_Key = aStream.
ReadU32();
1318 ReadCond( aStream, aVer, data.m_Unknown1 );
1328 auto block = std::make_unique<BLOCK<BLK_0x23_RATLINE>>( 0x23, aStream.
Position() );
1330 auto& data = block->GetData();
1332 data.m_Type = aStream.
ReadU8();
1334 data.m_Key = aStream.
ReadU32();
1335 data.m_Next = aStream.
ReadU32();
1339 data.m_Ptr1 = aStream.
ReadU32();
1340 data.m_Ptr2 = aStream.
ReadU32();
1341 data.m_Ptr3 = aStream.
ReadU32();
1343 for(
size_t i = 0; i < data.m_Coords.size(); ++i )
1345 data.m_Coords[i] = aStream.
ReadS32();
1350 ReadCond( aStream, aVer, data.m_Unknown2 );
1351 ReadCond( aStream, aVer, data.m_Unknown3 );
1359 auto block = std::make_unique<BLOCK<BLK_0x24_RECT>>( 0x24, aStream.
Position() );
1361 auto& data = block->GetData();
1363 data.m_Type = aStream.
ReadU8();
1365 data.m_Key = aStream.
ReadU32();
1366 data.m_Next = aStream.
ReadU32();
1367 data.m_Parent = aStream.
ReadU32();
1368 data.m_Unknown1 = aStream.
ReadU32();
1370 ReadCond( aStream, aVer, data.m_Unknown2 );
1372 for(
size_t i = 0; i < data.m_Coords.size(); ++i )
1374 data.m_Coords[i] = aStream.
ReadS32();
1377 data.m_Ptr2 = aStream.
ReadU32();
1379 data.m_Unknown3 = aStream.
ReadU32();
1380 data.m_Unknown4 = aStream.
ReadU32();
1381 data.m_Rotation = aStream.
ReadU32();
1389 auto block = std::make_unique<BLOCK<BLK_0x26_MATCH_GROUP>>( 0x26, aStream.
Position() );
1391 auto& data = block->GetData();
1393 data.m_Type = aStream.
ReadU8();
1395 data.m_Key = aStream.
ReadU32();
1396 data.m_MemberPtr = aStream.
ReadU32();
1398 ReadCond( aStream, aVer, data.m_Unknown1 );
1400 data.m_GroupPtr = aStream.
ReadU32();
1401 data.m_ConstPtr = aStream.
ReadU32();
1403 ReadCond( aStream, aVer, data.m_Unknown2 );
1411 auto block = std::make_unique<BLOCK<BLK_0x27_CSTRMGR_XREF>>( 0x27, aStream.
Position() );
1413 auto& data = block->GetData();
1415 const size_t totalBytes = aEndOff - 1 - aStream.
Position();
1418 constexpr size_t kPadding = 3;
1420 if( totalBytes <= kPadding )
1422 aStream.
Skip( totalBytes );
1426 aStream.
Skip( kPadding );
1428 const size_t payloadBytes = totalBytes - kPadding;
1429 const size_t numValues = payloadBytes / 4;
1430 const size_t remainder = payloadBytes % 4;
1432 data.m_Refs.resize( numValues );
1434 for(
size_t i = 0; i < numValues; i++ )
1435 data.m_Refs[i] = aStream.
ReadU32();
1438 aStream.
Skip( remainder );
1446 auto block = std::make_unique<BLOCK<BLK_0x28_SHAPE>>( 0x28, aStream.
Position() );
1448 auto& data = block->GetData();
1450 data.m_Type = aStream.
ReadU8();
1452 data.m_Key = aStream.
ReadU32();
1453 data.m_Next = aStream.
ReadU32();
1454 data.m_Ptr1 = aStream.
ReadU32();
1455 data.m_Unknown1 = aStream.
ReadU32();
1457 ReadCond( aStream, aVer, data.m_Unknown2 );
1458 ReadCond( aStream, aVer, data.m_Unknown3 );
1460 data.m_Ptr2 = aStream.
ReadU32();
1461 data.m_Ptr3 = aStream.
ReadU32();
1462 data.m_FirstKeepoutPtr = aStream.
ReadU32();
1463 data.m_FirstSegmentPtr = aStream.
ReadU32();
1464 data.m_Unknown4 = aStream.
ReadU32();
1465 data.m_Unknown5 = aStream.
ReadU32();
1467 ReadCond( aStream, aVer, data.m_TablePtr );
1469 data.m_Ptr6 = aStream.
ReadU32();
1471 ReadCond( aStream, aVer, data.m_TablePtr_16x );
1473 for(
size_t i = 0; i < data.m_Coords.size(); ++i )
1475 data.m_Coords[i] = aStream.
ReadS32();
1484 auto block = std::make_unique<BLOCK<BLK_0x29_PIN>>( 0x29, aStream.
Position() );
1486 auto& data = block->GetData();
1488 data.m_Type = aStream.
ReadU8();
1490 data.m_Key = aStream.
ReadU32();
1492 data.m_Ptr1 = aStream.
ReadU32();
1493 data.m_Ptr2 = aStream.
ReadU32();
1495 data.m_Null = aStream.
ReadU32();
1497 data.m_Ptr3 = aStream.
ReadU32();
1499 data.m_Coord1 = aStream.
ReadS32();
1500 data.m_Coord2 = aStream.
ReadS32();
1502 data.m_PtrPadstack = aStream.
ReadU32();
1504 data.m_Unknown1 = aStream.
ReadU32();
1506 data.m_PtrX30 = aStream.
ReadU32();
1508 data.m_Unknown2 = aStream.
ReadU32();
1509 data.m_Unknown3 = aStream.
ReadU32();
1510 data.m_Unknown4 = aStream.
ReadU32();
1518 auto block = std::make_unique<BLOCK<BLK_0x2A_LAYER_LIST>>( 0x2A, aStream.
Position() );
1520 auto& data = block->GetData();
1524 data.m_NumEntries = aStream.
ReadU16();
1526 ReadCond( aStream, aVer, data.m_Unknown );
1528 if( data.m_NonRefEntries.exists( aVer ) )
1530 data.m_NonRefEntries = std::vector<BLK_0x2A_LAYER_LIST::NONREF_ENTRY>();
1531 data.m_NonRefEntries->reserve( data.m_NumEntries );
1532 for(
size_t i = 0; i < data.m_NumEntries; ++i )
1541 data.m_RefEntries = std::vector<BLK_0x2A_LAYER_LIST::REF_ENTRY>();
1542 data.m_RefEntries->reserve( data.m_NumEntries );
1543 for(
size_t i = 0; i < data.m_NumEntries; ++i )
1553 data.m_Key = aStream.
ReadU32();
1561 auto block = std::make_unique<BLOCK<BLK_0x2B_FOOTPRINT_DEF>>( 0x2B, stream.
Position() );
1563 auto& data = block->GetData();
1567 data.m_Key = stream.
ReadU32();
1568 data.m_FpStrRef = stream.
ReadU32();
1569 data.m_Unknown1 = stream.
ReadU32();
1571 data.m_Next = stream.
ReadU32();
1572 data.m_FirstInstPtr = stream.
ReadU32();
1573 data.m_UnknownPtr3 = stream.
ReadU32();
1574 data.m_UnknownPtr4 = stream.
ReadU32();
1575 data.m_UnknownPtr5 = stream.
ReadU32();
1576 data.m_SymLibPathPtr = stream.
ReadU32();
1577 data.m_UnknownPtr6 = stream.
ReadU32();
1578 data.m_UnknownPtr7 = stream.
ReadU32();
1579 data.m_UnknownPtr8 = stream.
ReadU32();
1581 ReadCond( stream, aVer, data.m_Unknown2 );
1582 ReadCond( stream, aVer, data.m_Unknown3 );
1590 auto block = std::make_unique<BLOCK<BLK_0x2C_TABLE>>( 0x2C, aStream.
Position() );
1592 auto& data = block->GetData();
1594 data.m_Type = aStream.
ReadU8();
1595 data.m_SubType = aStream.
ReadU16();
1596 data.m_Key = aStream.
ReadU32();
1597 data.m_Next = aStream.
ReadU32();
1599 ReadCond( aStream, aVer, data.m_Unknown1 );
1600 ReadCond( aStream, aVer, data.m_Unknown2 );
1601 ReadCond( aStream, aVer, data.m_Unknown3 );
1603 data.m_StringPtr = aStream.
ReadU32();
1605 ReadCond( aStream, aVer, data.m_Unknown4 );
1607 data.m_Ptr1 = aStream.
ReadU32();
1608 data.m_Ptr2 = aStream.
ReadU32();
1609 data.m_Ptr3 = aStream.
ReadU32();
1611 data.m_Flags = aStream.
ReadU32();
1619 auto block = std::make_unique<BLOCK<BLK_0x2D_FOOTPRINT_INST>>( 0x2D, stream.
Position() );
1621 auto& data = block->GetData();
1623 data.m_UnknownByte1 = stream.
ReadU8();
1624 data.m_Layer = stream.
ReadU8();
1625 data.m_UnknownByte2 = stream.
ReadU8();
1627 data.m_Key = stream.
ReadU32();
1628 data.m_Next = stream.
ReadU32();
1630 ReadCond( stream, aVer, data.m_Unknown1 );
1632 ReadCond( stream, aVer, data.m_InstRef16x );
1634 data.m_Unknown2 = stream.
ReadU16();
1635 data.m_Unknown3 = stream.
ReadU16();
1637 ReadCond( stream, aVer, data.m_Unknown4 );
1639 data.m_Flags = stream.
ReadU32();
1641 data.m_Rotation = stream.
ReadU32();
1642 data.m_CoordX = stream.
ReadS32();
1643 data.m_CoordY = stream.
ReadS32();
1645 ReadCond( stream, aVer, data.m_InstRef );
1647 data.m_GraphicPtr = stream.
ReadU32();
1648 data.m_FirstPadPtr = stream.
ReadU32();
1649 data.m_TextPtr = stream.
ReadU32();
1651 data.m_AssemblyPtr = stream.
ReadU32();
1652 data.m_AreasPtr = stream.
ReadU32();
1653 data.m_UnknownPtr1 = stream.
ReadU32();
1654 data.m_UnknownPtr2 = stream.
ReadU32();
1662 auto block = std::make_unique<BLOCK<BLK_0x2E_CONNECTION>>( 0x2E, aStream.
Position() );
1664 auto& data = block->GetData();
1666 data.m_Type = aStream.
ReadU8();
1667 data.m_T2 = aStream.
ReadU16();
1668 data.m_Key = aStream.
ReadU32();
1669 data.m_Next = aStream.
ReadU32();
1670 data.m_NetAssignment = aStream.
ReadU32();
1671 data.m_Unknown1 = aStream.
ReadU32();
1672 data.m_CoordX = aStream.
ReadU32();
1673 data.m_CoordY = aStream.
ReadU32();
1674 data.m_Connection = aStream.
ReadU32();
1675 data.m_Unknown2 = aStream.
ReadU32();
1677 ReadCond( aStream, aVer, data.m_Unknown3 );
1685 auto block = std::make_unique<BLOCK<BLK_0x2F_UNKNOWN>>( 0x2F, aStream.
Position() );
1687 auto& data = block->GetData();
1689 data.m_Type = aStream.
ReadU8();
1690 data.m_T2 = aStream.
ReadU16();
1691 data.m_Key = aStream.
ReadU32();
1706 uint8_t alignment = aStream.
ReadU8();
1718 uint8_t reversal = aStream.
ReadU8();
1734 auto block = std::make_unique<BLOCK<BLK_0x30_STR_WRAPPER>>( 0x30, aStream.
Position() );
1736 auto& data = block->GetData();
1738 data.m_Type = aStream.
ReadU8();
1740 data.m_Key = aStream.
ReadU32();
1741 data.m_Next = aStream.
ReadU32();
1743 ReadCond( aStream, aVer, data.m_Unknown1 );
1744 ReadCond( aStream, aVer, data.m_Unknown2 );
1746 if( data.m_Font.exists( aVer ) )
1751 ReadCond( aStream, aVer, data.m_Ptr1 );
1752 ReadCond( aStream, aVer, data.m_Unknown3 );
1754 data.m_StrGraphicPtr = aStream.
ReadU32();
1756 ReadCond( aStream, aVer, data.m_PtrGroup_17x );
1757 ReadCond( aStream, aVer, data.m_Unknown4 );
1759 if( data.m_Font16x.exists( aVer ) )
1764 ReadCond( aStream, aVer, data.m_Ptr2 );
1766 data.m_CoordsX = aStream.
ReadU32();
1767 data.m_CoordsY = aStream.
ReadU32();
1769 data.m_Unknown5 = aStream.
ReadU32();
1770 data.m_Rotation = aStream.
ReadU32();
1772 ReadCond( aStream, aVer, data.m_PtrGroup_16x );
1780 auto block = std::make_unique<BLOCK<BLK_0x31_SGRAPHIC>>( 0x31, aStream.
Position() );
1782 auto& data = block->GetData();
1784 data.m_T = aStream.
ReadU8();
1787 const uint16_t layer = aStream.
ReadU16();
1802 data.m_Key = aStream.
ReadU32();
1803 data.m_StrGraphicWrapperPtr = aStream.
ReadU32();
1805 data.m_CoordsX = aStream.
ReadU32();
1806 data.m_CoordsY = aStream.
ReadU32();
1808 data.m_Unknown = aStream.
ReadU16();
1809 data.m_Len = aStream.
ReadU16();
1811 ReadCond( aStream, aVer, data.m_Un2 );
1821 auto block = std::make_unique<BLOCK<BLK_0x32_PLACED_PAD>>( 0x32, aStream.
Position() );
1823 auto& data = block->GetData();
1825 data.m_Type = aStream.
ReadU8();
1827 data.m_Key = aStream.
ReadU32();
1828 data.m_Next = aStream.
ReadU32();
1829 data.m_NetPtr = aStream.
ReadU32();
1830 data.m_Flags = aStream.
ReadU32();
1832 ReadCond( aStream, aVer, data.m_Prev );
1834 data.m_NextInFp = aStream.
ReadU32();
1835 data.m_ParentFp = aStream.
ReadU32();
1836 data.m_Track = aStream.
ReadU32();
1837 data.m_PadPtr = aStream.
ReadU32();
1838 data.m_Ptr6 = aStream.
ReadU32();
1839 data.m_Ratline = aStream.
ReadU32();
1840 data.m_PtrPinNumber = aStream.
ReadU32();
1841 data.m_NextInCompInst = aStream.
ReadU32();
1843 ReadCond( aStream, aVer, data.m_Unknown2 );
1845 data.m_NameText = aStream.
ReadU32();
1846 data.m_Ptr11 = aStream.
ReadU32();
1848 for(
size_t i = 0; i < data.m_Coords.size(); ++i )
1850 data.m_Coords[i] = aStream.
ReadS32();
1859 auto block = std::make_unique<BLOCK<BLK_0x33_VIA>>( 0x33, aStream.
Position() );
1861 auto& data = block->GetData();
1866 data.m_Key = aStream.
ReadU32();
1867 data.m_Next = aStream.
ReadU32();
1868 data.m_NetPtr = aStream.
ReadU32();
1869 data.m_Unknown2 = aStream.
ReadU32();
1871 ReadCond( aStream, aVer, data.m_Unknown3 );
1873 data.m_UnknownPtr1 = aStream.
ReadU32();
1875 ReadCond( aStream, aVer, data.m_UnknownPtr2 );
1877 data.m_CoordsX = aStream.
ReadS32();
1878 data.m_CoordsY = aStream.
ReadS32();
1880 data.m_Connection = aStream.
ReadU32();
1881 data.m_Padstack = aStream.
ReadU32();
1882 data.m_UnknownPtr5 = aStream.
ReadU32();
1883 data.m_UnknownPtr6 = aStream.
ReadU32();
1885 data.m_Unknown4 = aStream.
ReadU32();
1886 data.m_Unknown5 = aStream.
ReadU32();
1888 for(
size_t i = 0; i < data.m_BoundingBoxCoords.size(); ++i )
1890 data.m_BoundingBoxCoords[i] = aStream.
ReadS32();
1899 auto block = std::make_unique<BLOCK<BLK_0x34_KEEPOUT>>( 0x34, aStream.
Position() );
1901 auto& data = block->GetData();
1903 data.m_T = aStream.
ReadU8();
1905 data.m_Key = aStream.
ReadU32();
1906 data.m_Next = aStream.
ReadU32();
1907 data.m_Ptr1 = aStream.
ReadU32();
1909 ReadCond( aStream, aVer, data.m_Unknown1 );
1911 data.m_Flags = aStream.
ReadU32();
1912 data.m_FirstSegmentPtr = aStream.
ReadU32();
1913 data.m_Ptr3 = aStream.
ReadU32();
1914 data.m_Unknown2 = aStream.
ReadU32();
1922 auto block = std::make_unique<BLOCK<BLK_0x35_FILE_REF>>( 0x35, aStream.
Position() );
1924 auto& data = block->GetData();
1926 data.m_T2 = aStream.
ReadU8();
1927 data.m_T3 = aStream.
ReadU16();
1928 aStream.
ReadBytes( data.m_Content.data(), data.m_Content.size() );
1936 auto block = std::make_unique<BLOCK<BLK_0x36_DEF_TABLE>>( 0x36, aStream.
Position() );
1938 auto& data = block->GetData();
1942 data.m_Code = aStream.
ReadU16();
1943 data.m_Key = aStream.
ReadU32();
1944 data.m_Next = aStream.
ReadU32();
1946 ReadCond( aStream, aVer, data.m_Unknown1 );
1948 data.m_NumItems = aStream.
ReadU32();
1949 data.m_Count = aStream.
ReadU32();
1950 data.m_LastIdx = aStream.
ReadU32();
1951 data.m_Unknown2 = aStream.
ReadU32();
1953 ReadCond( aStream, aVer, data.m_Unknown3 );
1955 if( data.m_NumItems > 1000000 )
1958 "Block 0x36 item count %u exceeds limit at offset %#010zx",
1959 data.m_NumItems, aStream.
Position() ) );
1962 if( data.m_Count > data.m_NumItems )
1965 "Block 0x36 filled count %u exceeds capacity %u at offset %#010zx",
1966 data.m_Count, data.m_NumItems, aStream.
Position() ) );
1972 data.m_Items.reserve( data.m_Count );
1973 for( uint32_t i = 0; i < data.m_NumItems; ++i )
1975 const bool keep = i < data.m_Count;
1977 switch( data.m_Code )
1989 data.m_Items.emplace_back( std::move( item ) );
2003 data.m_Items.emplace_back( std::move( item ) );
2014 data.m_Items.emplace_back( std::move( item ) );
2029 data.m_Items.emplace_back( std::move( item ) );
2051 data.m_Items.emplace_back( std::move( item ) );
2059 data.m_Items.emplace_back( std::move( item ) );
2067 data.m_Items.emplace_back( std::move( item ) );
2075 data.m_Items.emplace_back( std::move( item ) );
2085 data.m_Items.emplace_back( std::move( item ) );
2094 data.m_Items.emplace_back( std::move( item ) );
2101 aStream.
Skip( 1052 );
2103 data.m_Items.emplace_back( std::move( item ) );
2106 default:
THROW_IO_ERROR( wxString::Format(
"Unknown substruct type %#02x in block 0x36", data.m_Code ) );
2116 auto block = std::make_unique<BLOCK<BLK_0x37_PTR_ARRAY>>( 0x37, aStream.
Position() );
2118 auto& data = block->GetData();
2120 data.m_T = aStream.
ReadU8();
2121 data.m_T2 = aStream.
ReadU16();
2122 data.m_Key = aStream.
ReadU32();
2123 data.m_GroupPtr = aStream.
ReadU32();
2124 data.m_Next = aStream.
ReadU32();
2125 data.m_Capacity = aStream.
ReadU32();
2126 data.m_Count = aStream.
ReadU32();
2127 data.m_Unknown2 = aStream.
ReadU32();
2129 ReadCond( aStream, aVer, data.m_Unknown3 );
2139 auto block = std::make_unique<BLOCK<BLK_0x38_FILM>>( 0x38, aStream.
Position() );
2141 auto& data = block->GetData();
2145 data.m_Key = aStream.
ReadU32();
2146 data.m_Next = aStream.
ReadU32();
2147 data.m_LayerList = aStream.
ReadU32();
2149 if( data.m_FilmName.exists( aVer ) )
2154 ReadCond( aStream, aVer, data.m_LayerNameStr );
2155 ReadCond( aStream, aVer, data.m_Unknown2 );
2157 for(
size_t i = 0; i < data.m_UnknownArray1.size(); ++i )
2159 data.m_UnknownArray1[i] = aStream.
ReadU32();
2162 ReadCond( aStream, aVer, data.m_Unknown3 );
2170 auto block = std::make_unique<BLOCK<BLK_0x39_FILM_LAYER_LIST>>( 0x39, aStream.
Position() );
2172 auto& data = block->GetData();
2176 data.m_Key = aStream.
ReadU32();
2177 data.m_Parent = aStream.
ReadU32();
2178 data.m_Head = aStream.
ReadU32();
2180 for(
size_t i = 0; i < data.m_X.size(); ++i )
2182 data.m_X[i] = aStream.
ReadU16();
2191 auto block = std::make_unique<BLOCK<BLK_0x3A_FILM_LIST_NODE>>( 0x3A, aStream.
Position() );
2193 auto& data = block->GetData();
2198 data.m_Key = aStream.
ReadU32();
2199 data.m_Next = aStream.
ReadU32();
2200 data.m_Unknown = aStream.
ReadU32();
2202 ReadCond( aStream, aVer, data.m_Unknown1 );
2210 auto block = std::make_unique<BLOCK<BLK_0x3B_PROPERTY>>( 0x3B, aStream.
Position() );
2212 auto& data = block->GetData();
2214 data.m_T = aStream.
ReadU8();
2215 data.m_SubType = aStream.
ReadU16();
2216 data.m_Len = aStream.
ReadU32();
2221 data.m_Unknown1 = aStream.
ReadU32();
2222 data.m_Unknown2 = aStream.
ReadU32();
2224 ReadCond( aStream, aVer, data.m_Unknown3 );
2234 auto block = std::make_unique<BLOCK<BLK_0x3C_KEY_LIST>>( 0x3C, aStream.
Position() );
2236 auto& data = block->GetData();
2238 data.m_T = aStream.
ReadU8();
2239 data.m_T2 = aStream.
ReadU16();
2240 data.m_Key = aStream.
ReadU32();
2242 ReadCond( aStream, aVer, data.m_Unknown );
2244 data.m_NumEntries = aStream.
ReadU32();
2246 if( data.m_NumEntries > 1000000 )
2249 "Block 0x3C entry count %u exceeds limit at offset %#010zx",
2250 data.m_NumEntries, aStream.
Position() ) );
2253 data.m_Entries.reserve( data.m_NumEntries );
2254 for( uint32_t i = 0; i < data.m_NumEntries; ++i )
2256 data.m_Entries.push_back( aStream.
ReadU32() );
2267 uint8_t type = 0x00;
2270 aEndOfObjectsMarker =
true;
2274 std::unique_ptr<BLOCK_BASE> block;
2430 wxString::Format(
"Current offset %#010zx is at or past the expected end of block 0x27 at %#010zx",
2544 aEndOfObjectsMarker =
true;
2568 THROTTLE refreshThrottle( std::chrono::milliseconds( 100 ) );
2572 const size_t offset =
m_stream.Position();
2575 wxASSERT_MSG( offset % 4 == 0,
2576 wxString::Format(
"Allegro object at %#010zx, offset not aligned to 4 bytes", offset ) );
2581 uint8_t blockTypeByte = 0;
2585 bool endOfObjectsMarker =
false;
2586 std::unique_ptr<BLOCK_BASE> block = blockParser.
ParseBlock( endOfObjectsMarker );
2588 if( endOfObjectsMarker )
2594 size_t scanPos =
m_stream.Position();
2595 uint8_t nextByte = 0;
2597 while(
m_stream.GetU8( nextByte ) && nextByte == 0x00 )
2600 if( nextByte > 0x00 && nextByte <= 0x3C )
2602 size_t blockStart = scanPos;
2604 if( blockStart % 4 != 0 )
2605 blockStart -= ( blockStart % 4 );
2610 uint8_t alignedByte = 0;
2615 if( alignedByte == 0x00 || alignedByte > 0x3C )
2619 wxString::Format(
"V18 zero gap from %#010zx to %#010zx, "
2620 "continuing at block type %#04x",
2621 offset, blockStart, nextByte ) );
2629 wxString::Format(
"End of objects marker (0x00) at index %zu, offset %#010zx",
2641 "Do not have parser for block index %zu type %#02x available at offset %#010zx",
2647 wxString::Format(
"Ending at unknown block, index %zu type %#04x at offset %#010zx",
2650 wxFAIL_MSG(
"Failed to create block" );
2657 wxString::Format(
"Added block %zu, type %#04x from %#010zx to %#010zx",
2675template <
typename T>
2678 if constexpr( std::is_same_v<T, FILE_HEADER::LINKED_LIST> )
2682 else if constexpr( std::is_base_of_v<COND_FIELD_BASE<FILE_HEADER::LINKED_LIST>,
T> )
2684 if( aLL.has_value() )
2692 std::unique_ptr<BRD_DB> board = std::make_unique<BRD_DB>();
2707 if( !board->m_Header )
2716 board->m_Header->m_Magic );
2718 dumpLL(
"V18_1", board->m_Header->m_LL_V18_1 );
2719 dumpLL(
"V18_2", board->m_Header->m_LL_V18_2 );
2720 dumpLL(
"V18_3", board->m_Header->m_LL_V18_3 );
2721 dumpLL(
"V18_4", board->m_Header->m_LL_V18_4 );
2722 dumpLL(
"V18_5", board->m_Header->m_LL_V18_5 );
2724 dumpLL(
"0x04", board->m_Header->m_LL_0x04 );
2725 dumpLL(
"0x06", board->m_Header->m_LL_0x06 );
2726 dumpLL(
"0x0C", board->m_Header->m_LL_0x0C );
2727 dumpLL(
"Shapes", board->m_Header->m_LL_Shapes );
2728 dumpLL(
"0x14", board->m_Header->m_LL_0x14 );
2729 dumpLL(
"0x1B_Nets", board->m_Header->m_LL_0x1B_Nets );
2730 dumpLL(
"0x1C", board->m_Header->m_LL_0x1C );
2731 dumpLL(
"0x24_0x28", board->m_Header->m_LL_0x24_0x28 );
2732 dumpLL(
"Unknown1", board->m_Header->m_LL_Unknown1 );
2733 dumpLL(
"0x2B", board->m_Header->m_LL_0x2B );
2734 dumpLL(
"0x03_0x30", board->m_Header->m_LL_0x03_0x30 );
2735 dumpLL(
"0x0A", board->m_Header->m_LL_0x0A );
2736 dumpLL(
"0x1D_0x1E_0x1F", board->m_Header->m_LL_0x1D_0x1E_0x1F );
2737 dumpLL(
"Unknown2", board->m_Header->m_LL_Unknown2 );
2738 dumpLL(
"0x38", board->m_Header->m_LL_0x38 );
2739 dumpLL(
"0x2C", board->m_Header->m_LL_0x2C );
2740 dumpLL(
"0x0C_2", board->m_Header->m_LL_0x0C_2 );
2741 dumpLL(
"Unknown3", board->m_Header->m_LL_Unknown3 );
2742 dumpLL(
"Unknown5", board->m_Header->m_LL_Unknown5_preV18 );
2743 dumpLL(
"Unknown5", board->m_Header->m_LL_Unknown5_V18 );
2744 dumpLL(
"0x36", board->m_Header->m_LL_0x36 );
2745 dumpLL(
"Unknown6", board->m_Header->m_LL_Unknown6 );
2746 dumpLL(
"0x0A_2", board->m_Header->m_LL_0x0A_2 );
2748 dumpLL(
"V18_6", board->m_Header->m_LL_V18_6 );
2754 s += wxString::Format(
"Error parsing Allegro file: %s\n", e.
What() );
2755 s += wxString::Format(
"Stream position: %#010lx\n",
m_stream.Position() );
2757 if( board->m_Header )
2758 s += wxString::Format(
"File magic: %#010x\n", board->m_Header->m_Magic );
2760 s += wxString::Format(
"File magic: Unknown\n" );
2769 wxString verStr( board->m_Header->m_AllegroVersion.data(), 60 );
2773 _(
"This file was created with %s, which uses a binary format that "
2774 "predates Allegro 16.0 and is not supported by this importer.\n\n"
2775 "To import this design, open it in Cadence Allegro PCB Editor "
2776 "version 16.0 or later and re-save, then import the resulting file." ),
2780 const uint32_t stringsCount = board->m_Header->GetStringsCount();
2781 board->ReserveCapacity( board->m_Header->m_ObjectCount, stringsCount );
2785 board->SetLeanMode(
true );
2791 wxLogTrace(
traceAllegroPerf, wxT(
" ReadStringMap (%u strings): %.3f ms" ),
2792 stringsCount, parseTimer.
msecs(
true ) );
2796 wxLogTrace(
traceAllegroPerf, wxT(
" readObjects (%zu objects): %.3f ms" ),
2797 board->GetObjectCount(), parseTimer.
msecs(
true ) );
2802 s += wxString::Format(
"Error parsing Allegro file: %s\n", e.
What() );
2803 s += wxString::Format(
"Stream position: %#010lx\n",
m_stream.Position() );
2805 if( board->m_Header )
2806 s += wxString::Format(
"File magic: %#010x\n", board->m_Header->m_Magic );
2808 s += wxString::Format(
"File magic: Unknown\n" );
2814 board->ResolveAndValidate();
static std::unique_ptr< BLOCK_BASE > ParseBlock_0x35(FILE_STREAM &aStream, FMT_VER aVer)
static std::unique_ptr< BLOCK_BASE > ParseBlock_0x36(FILE_STREAM &aStream, FMT_VER aVer)
void dumpLL(const char *name, const T &aLL)
static FILE_HEADER::LINKED_LIST ReadLL(FILE_STREAM &aStream, FMT_VER aVer)
static PAD_TYPE decodePadType(uint8_t aVal)
static std::unique_ptr< BLOCK_BASE > ParseBlock_0x04_NET_ASSIGNMENT(FILE_STREAM &aStream, FMT_VER aVer)
static std::unique_ptr< BLOCK_BASE > ParseBlock_0x2C_TABLE(FILE_STREAM &aStream, FMT_VER aVer)
static std::unique_ptr< BLOCK_BASE > ParseBlock_0x1F(FILE_STREAM &aStream, FMT_VER aVer)
static std::unique_ptr< BLOCK_BASE > ParseBlock_0x3A_FILM_LIST_NODE(FILE_STREAM &aStream, FMT_VER aVer)
static std::unique_ptr< BLOCK_BASE > ParseBlock_0x3C(FILE_STREAM &aStream, FMT_VER aVer)
static std::unique_ptr< BLOCK_BASE > ParseBlock_0x14(FILE_STREAM &aStream, FMT_VER aVer)
static std::unique_ptr< BLOCK_BASE > ParseBlock_0x08(FILE_STREAM &aStream, FMT_VER aVer)
static std::unique_ptr< BLOCK_BASE > ParseBlock_0x10(FILE_STREAM &stream, FMT_VER aVer)
static std::unique_ptr< BLOCK_BASE > ParseBlock_0x1B_NET(FILE_STREAM &stream, FMT_VER aVer)
static const wxChar *const traceAllegroParserBlocks
static std::unique_ptr< BLOCK_BASE > ParseBlock_0x0F(FILE_STREAM &stream, FMT_VER aVer)
static std::unique_ptr< BLOCK_BASE > ParseBlock_0x05_TRACK(FILE_STREAM &aStream, FMT_VER aVer)
static std::unique_ptr< BLOCK_BASE > ParseBlock_0x1D(FILE_STREAM &aStream, FMT_VER aVer)
static std::unique_ptr< BLOCK_BASE > ParseBlock_0x1C_PADSTACK(FILE_STREAM &aStream, FMT_VER aVer)
static std::unique_ptr< BLOCK_BASE > ParseBlock_0x34_KEEPOUT(FILE_STREAM &aStream, FMT_VER aVer)
static std::unique_ptr< BLOCK_BASE > ParseBlock_0x01_ARC(FILE_STREAM &aStream, FMT_VER aVer)
static BLK_0x30_STR_WRAPPER::TEXT_PROPERTIES ParseTextProps(FILE_STREAM &aStream)
static std::unique_ptr< BLOCK_BASE > ParseBlock_0x0D_PAD(FILE_STREAM &aStream, FMT_VER aVer)
static std::unique_ptr< BLOCK_BASE > ParseBlock_0x1E(FILE_STREAM &aStream, FMT_VER aVer)
static std::unique_ptr< BLOCK_BASE > ParseBlock_0x20(FILE_STREAM &aStream, FMT_VER aVer)
static std::unique_ptr< BLOCK_BASE > ParseBlock_0x0A_DRC(FILE_STREAM &aStream, FMT_VER aVer)
static std::unique_ptr< BLOCK_BASE > ParseBlock_0x06(FILE_STREAM &stream, FMT_VER aVer)
static void ReadStringMap(FILE_STREAM &stream, DB &aDb, uint32_t count)
static std::unique_ptr< BLOCK_BASE > ParseBlock_0x0E(FILE_STREAM &aStream, FMT_VER aVer)
static void ReadArrayU32(FILE_STREAM &aStream, ARRAY &aArray)
static std::unique_ptr< BLOCK_BASE > ParseBlock_0x39_FILM_LAYER_LIST(FILE_STREAM &aStream, FMT_VER aVer)
static void ReadCond(FILE_STREAM &aStream, FMT_VER aFmtVer, COND_T &aField)
Read a single conditional field from the stream, if it exists at the current version.
static std::unique_ptr< BLOCK_BASE > ParseBlock_0x09(FILE_STREAM &aStream, FMT_VER aVer)
static std::unique_ptr< BLOCK_BASE > ParseBlock_0x38_FILM(FILE_STREAM &aStream, FMT_VER aVer)
static double ReadAllegroFloat(FILE_STREAM &aStream)
static std::unique_ptr< BLOCK_BASE > ParseBlock_0x24_RECT(FILE_STREAM &aStream, FMT_VER aVer)
static std::unique_ptr< BLOCK_BASE > ParseBlock_0x2E(FILE_STREAM &aStream, FMT_VER aVer)
static std::unique_ptr< BLOCK_BASE > ParseBlock_0x03(FILE_STREAM &aStream, FMT_VER aVer)
static std::unique_ptr< BLOCK_BASE > ParseBlock_0x12(FILE_STREAM &aStream, FMT_VER aVer)
static std::unique_ptr< BLOCK_BASE > ParseBlock_0x15_16_17_SEGMENT(FILE_STREAM &aStream, FMT_VER aVer, uint8_t aType)
static std::unique_ptr< BLOCK_BASE > ParseBlock_0x31_SGRAPHIC(FILE_STREAM &aStream, FMT_VER aVer)
static std::unique_ptr< BLOCK_BASE > ParseBlock_0x22(FILE_STREAM &aStream, FMT_VER aVer)
static std::unique_ptr< BLOCK_BASE > ParseBlock_0x27(FILE_STREAM &aStream, FMT_VER aVer, size_t aEndOff)
static std::unique_ptr< BLOCK_BASE > ParseBlock_0x2A(FILE_STREAM &aStream, FMT_VER aVer)
static std::unique_ptr< BLOCK_BASE > ParseBlock_0x2F(FILE_STREAM &aStream, FMT_VER aVer)
static LAYER_INFO ParseLayerInfo(FILE_STREAM &aStream)
static std::unique_ptr< BLOCK_BASE > ParseBlock_0x07(FILE_STREAM &stream, FMT_VER aVer)
static std::unique_ptr< BLOCK_BASE > ParseBlock_0x33_VIA(FILE_STREAM &aStream, FMT_VER aVer)
static std::unique_ptr< BLOCK_BASE > ParseBlock_0x32_PLACED_PAD(FILE_STREAM &aStream, FMT_VER aVer)
static std::unique_ptr< BLOCK_BASE > ParseBlock_0x37(FILE_STREAM &aStream, FMT_VER aVer)
static std::unique_ptr< BLOCK_BASE > ParseBlock_0x2B(FILE_STREAM &stream, FMT_VER aVer)
static std::unique_ptr< BLOCK_BASE > ParseBlock_0x2D(FILE_STREAM &stream, FMT_VER aVer)
static std::unique_ptr< BLOCK_BASE > ParseBlock_0x21(FILE_STREAM &aStream, FMT_VER aVer)
static std::unique_ptr< BLOCK_BASE > ParseBlock_0x23_RATLINE(FILE_STREAM &aStream, FMT_VER aVer)
static std::unique_ptr< BLOCK_BASE > ParseBlock_0x28_SHAPE(FILE_STREAM &aStream, FMT_VER aVer)
static std::unique_ptr< BLOCK_BASE > ParseBlock_0x11(FILE_STREAM &aStream, FMT_VER aVer)
static std::unique_ptr< BLOCK_BASE > ParseBlock_0x26(FILE_STREAM &aStream, FMT_VER aVer)
static std::unique_ptr< BLOCK_BASE > ParseBlock_0x3B(FILE_STREAM &aStream, FMT_VER aVer)
static std::unique_ptr< BLOCK_BASE > ParseBlock_0x0C(FILE_STREAM &aStream, FMT_VER aVer)
static std::unique_ptr< BLOCK_BASE > ParseBlock_0x29_PIN(FILE_STREAM &aStream, FMT_VER aVer)
static T ReadField(FILE_STREAM &aStream, FMT_VER aFmtVer)
static std::unique_ptr< BLOCK_BASE > ParseBlock_0x30_STR_WRAPPER(FILE_STREAM &aStream, FMT_VER aVer)
The block parser is responsible for parsing individual blocks of data from the file stream.
std::unique_ptr< BLOCK_BASE > ParseBlock(bool &aEndOfObjectsMarker)
Parse one block from the stream, returning a BLOCK_BASE representing the raw data of the block.
const size_t m_x27_end
To parse an 0x27 block, we need to know where the end of the block is in the stream.
An Allegro database that represents a .brd file (amd presumably .dra)
std::unique_ptr< FILE_HEADER > m_Header
void InsertBlock(std::unique_ptr< BLOCK_BASE > aBlock) override
An ALLEGRO::DB is the represention of the actual data stored within an Allegro file,...
void AddString(uint32_t aKey, wxString &&aStr)
size_t GetObjectCount() const
Stream that reads primitive types from a memory buffer containing Allegro .brd (or ....
void ReadBytes(void *aDest, size_t aSize)
Read a number of bytes from the stream into the destination buffer.
std::string ReadString(bool aRoundToNextU32)
std::string ReadStringFixed(size_t aLen, bool aRoundToNextU32)
PROGRESS_REPORTER * m_progressReporter
void readObjects(BRD_DB &aDb)
std::unique_ptr< BRD_DB > Parse()
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
virtual const wxString What() const
A composite of Problem() and Where()
A small class to help profiling.
double msecs(bool aSinceLast=false)
Rate-limiter that fires at most once per interval.
static const wxChar *const traceAllegroParser
Flag to enable debug output of Allegro parsing.
#define THROW_IO_ERROR(msg)
macro which captures the "call site" values of FILE_, __FUNCTION & LINE
PAD_TYPE
The type of the padstack.
FMT_VER
The format of an Allego file.
static const wxChar *const traceAllegroPerf
std::vector< uint32_t > m_Entries
std::vector< uint32_t > m_Entries
std::array< uint32_t, 20 > m_Entries
TEXT_ALIGNMENT m_Alignment
COND_GE< FMT_VER::V_172, std::array< uint32_t, 8 > > m_Ys
uint32_t m_CharacterSpace
COND_GE< FMT_VER::V_174, uint32_t > m_Unknown2
std::array< uint32_t, 14 > m_Xs
COND_GE< FMT_VER::V_172, std::array< uint32_t, 2 > > m_Zs
COND_GE< FMT_VER::V_164, std::array< uint32_t, 3 > > m_Ys
COND_GE< FMT_VER::V_172, std::string > m_Str
COND_GE< FMT_VER::V_174, uint32_t > m_Unknown1
COND_LT< FMT_VER::V_172, std::string > m_Str16x
std::array< uint8_t, 28 > m_Unknown
COND_GE< FMT_VER::V_174, uint32_t > m_Unknown2
COND_LT< FMT_VER::V_172, std::array< uint32_t, 50 > > m_Unknown2
std::array< uint8_t, 1016 > m_Unknown
std::array< uint8_t, 232 > m_Unknown
std::array< uint8_t, 200 > m_Unknown
std::array< uint32_t, 3 > m_Ptrs
std::array< uint8_t, 108 > m_Unknown
COND_GE< FMT_VER::V_180, uint32_t > m_Unknown2
Substruct in a padstack object.
static const size_t STRING_TABLE_OFFSET
FMT_VER m_FmtVer
What version is this file?
A type that is always false.
std::vector< std::string > header
wxString result
Test unit parsing edge cases and error handling.