• Content count

  • Joined

  • Last visited

  • Days Won


Krycztij last won the day on September 20 2015

Krycztij had the most liked content!

Community Reputation

2 Neutral

About Krycztij

  • Rank
  • Birthday 09/05/1981
  1. RA is Huffman, and as such it has very high CPU demand (lots of ALU and cache pressure). I have not seen anything like that in early 1990ies systems (even sliding windows were rare), so I stand by my opinion – it is very likely RLE compression
  2. Oh, this is even more interesting when you consider that ILBMs are already compressed! In order to not make the resulting file smaller at all, the ILBM needs to be stored in an uncompressed format before JR’ing it. I’ve seen some RLE compressions on Atari and PlayStation, and I can only recommend: pick a human-readable file like TXT or INI to begin with find consecutive chunks (e.g. the 12 B of “FORM----ILBM”, then 2B of “HD”) list them with the leading codes (in this case “02 00 F2 BA 00 00 63 B8” and “01”) unless you are very gifted at cracking codes, translate the leading codes to binary (these algorithms are always bit-packed and it’s very hard to find patterns in the hex numbers) try finding patterns, of course sort the consecutive chunks by length or by frequency of occurancy, maybe this reveals identical bits consider that these algorithms may be using words instead of bytes I guess it’s something RLE-related, because “01” just before the two “HD” bytes seems too much of a coincidence. Maybe you get a clue from PackBits, the ILBM RLE compression: auto n = next_byte(); if(n <= 127) { // copy the following n + 1 bytes literally } else if(n > 128) { // replicate the following byte 257 - n times (the numbers make much more sense if you consider the byte signed, but I didn’t for performance, sorry!) } else { // reserved; ignore } … or the PCX RLE compression: auto n = next_byte(); if(0xC0 <= n) { auto const count = 0x3F & n; // replicate the following byte this many times } else { // copy the byte } … or something from PlayStation: auto n = next_byte_signed(); if(n < 0) { // repeat the following byte 2 + |n| times } else { // copy the following 1 + n bytes } The pattern is always the same, just the magic numbers differ a lot (they’re often hand-tuned for good results with the game).
  3. Sunny saturday, had a walk with my family. A glider crashed just a few meters away from us into the trees – I rushed to help, but the pilot had lots of luck and could just walk away with no injuries. I did something very stupid: I didn’t call the fire department, because it was really just a bent plane and the pilot reassured me it wouldn’t be necessary. However, I learned later that people farther away heard the crash, called 911, and they searched the area with a helicopter to find the crash site. I could have avoided that. Well, flight simulators didn’t prepare me for this
  4. Could this be the reason it’s unused? Considering what has been said about EF2000 (“project from hell”, “a million lines of pants-down code”), occurance of such opcodes doesn’t surprise me at all.
  5. Sounds like an optimized version of the triangle jump to me. Like „hey we can save two bytes and 20 CPU cycles if we use two points instead of three“; Art department saying „this is really hard to understand for our artists when they make the models“; everyone going back to the triangle version …
  6. Two points don’t define a plane … how does 0011 decide to jump, then? Maybe distance related (point 1 closer to the viewer than point 2)?
  7. Could this be a multi-GPU issue? E.g. the main GPU offloading to the integrated GPU for power saving or due to a driver error?
  8. No time either. I was holding my breath in hope for some simple patterns to emerge … now I guess this will require disassembly
  9. Is there a way to find out all values without flying to these points in the game? If I had a table with all 400×400 actual indices, I could compare that to the raw indices and pattern matching could be as easy as looking at the diff image.
  10. Happy New Year everybody!
  11. While you’re editing: In TFXplorer.cpp (1807), replace if(supershapesToRasterize) { with if(supershapesToRasterize) { // Draw one quad per tile in ground color (160 in TFX 3 palette). This is a quick-and-dirty solution to transparent ground // in TFX 1 levels. auto const y000 = floatx4Zero() - x000From(yInTFXUnits(eyePoint)); auto toNextJob = supershapesToRasterize.toBeginning; auto index = 0; do { // From XZ and Y, interleave XYZ: Geo::XYZ_float_reg eyeSpaceOffset = { interleavedXY(load(toNextJob->offsetFromEye).xy__, y000) }; auto const objectToEye = preTranslated(eyeSpaceOffset, worldToEye); auto const a = Geo::transformed(Geo::xyzFrom(-1024.0f, 32.0f, -1024.0f), objectToEye); auto const b = Geo::transformed(Geo::xyzFrom(-1024.0f, 32.0f, 1024.0f), objectToEye); auto const c = Geo::transformed(Geo::xyzFrom( 1024.0f, 32.0f, 1024.0f), objectToEye); auto const d = Geo::transformed(Geo::xyzFrom( 1024.0f, 32.0f, -1024.0f), objectToEye); rasterizeFlatShadedTriangle(myRasterizer.tfx, a, b, c, 160); nextVertex(myRasterizer.tfx, d, 160); if(0 == index % 512) { myRasterizer.tfx.flushCommandList(); // prevent overruns } } while(++index, ++toNextJob < supershapesToRasterize.toEnd); myRasterizer.tfx.flushCommandList(); Which really is a big waste of CPU time with TFX 2 and TFX 3, but it looks so incredibly good with TFX 1 …
  12. The cloud files should load with the above fixes. At least they shouldn’t crash TFXplorer any more. Thanks a lot for sorting out the whole stuff. I just checked out Libya in-game, and you did a fantastic job with it! Regarding the missing run-way numbers … I found them: Look a kilometer away! (Probably a transformation opcode has different meanings in TFX 1 & 3, or variables are initialized differently.)
  13. Investigating a different crash. Mike, how many LODs does 3\CLOUD2.3 have? In TFX Shape.cpp (691), please replace UCount const numberOfLODs = 1; while(0x0000 != *toWord && 0x7FFF != *toWord && Shape::maximalNumberOfLODs > numberOfLODs) { with while(0x0000 != *toWord && 0x7FFF != *toWord && toEndOfLODs < toCapacityEndOf(lods)) { Because I hard-coded a limit of 4 LODs (TFX 2 and TFX 3 never use more) and the buffer runs over with said file. Furthermore, in TFX Supershape.cpp (451), replace case 0x0014: case 0x001A: case 0x001B: case 0x004A: { with case 0x004A: { if(6 > sizeOf(block)) { return "file too short"; } struct OffsetObject { UInt2B shapeIndex; UInt2B positionIndex; UInt2B twentyOne; }; auto const & information = read<OffsetObject>(block); if(header.numberOfShapes <= information.shapeIndex) { return "block 4 pointer 1 opcode 004a: bad shape index"; } if(header.numberOfPositions <= information.positionIndex) { return "block 4 pointer 1 opcode 004a: bad position index"; } auto & shape = block6.shapes[information.shapeIndex]; auto & newObject = *shapes.toEnd++; newObject.indexInShapeList = shape.indexInShapeList; newObject.scale = shape.scale; newObject.yaw = shape.yaw; newObject.pitch = shape.pitch; newObject.roll = shape.roll; = block3[information.positionIndex]; } goto readNext; case 0x0014: case 0x001A: case 0x001B: { which is an ugly copy-paste solution from the block above, but it should work for now
  14. Yes, I meant the origin, not the center. ThreeView SupershapeSession.cpp (83): Replace with auto const worldToEye = computeWorldToEye(); Replace the call in line 91 with: supershape.prepareEntireRasterization( shapeRasterizeJobs.toEnd, timeOfDay, zeroParameters, rotationOf(worldToEye), 1.0f, transformed(offsetOf(worldToEye), transposed(rotationOf(worldToEye))) );
  15. Oh, that’s a mean one. We ran out of stack space (it doesn’t grow infinitely). Right-click 3View -> Properties -> Linker -> System -> Stack Reserve Size -> enter 2000000 I think that fix is already done in the 32-bit versions, but since I never distributed a 64-bit version of 3View, I missed that one. There are other issues as well; I’m checking them now. Update: Two more crashes: Go to TFX Supershape.cpp (1456) and change the initial value of “greatestDistance” from 0.0f to -1.0f. Do the same in line 1553. Otherwise, while sorting the shapes by distance for rendering, no closest shape would ever be chosen if the viewer is exactly at the center. And that’s the next issue: For some reason, you’re always placed in the center. I’m at it.