M2/Loading

From wowdev
Revision as of 05:52, 22 October 2017 by Fallenoak (talk | contribs) (Add initial reversal of CM2Shared::SubstituteSimpleShaders)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Shader Substitution

CM2Shared::SubstituteSimpleShaders

3.3.5a:

void __fastcall CM2Shared::SubstituteSimpleShaders(CM2Shared *this) {
  uint32_t batchCount = this->skinProfile->batches.count;

  if (batchCount == 0) {
    return;
  }

  uint32_t batchIndex;

  for (batchIndex = 0; batchIndex < batchCount; ++batchIndex) {
    M2Batch batch = this->skinProfile->batches.data[batchIndex];

    if (batch->shader & 0x8000) {
      continue;
    }

    M2Material material = &this->data->materials.data[batch->materialIndex];

    if (this->data->flags & 0x8) {
      uint32_t textureCombinerComboIndex = batch->shader;
      uint32_t textureCoordComboIndex = batch->textureCoordComboIndex;

      batch->shader = 0;

      // Single texture
      if (batch->textureCount == 0) {
        uint16_t shader = 0;

        uint16_t textureCombiner = 0;

        // If the material blend mode is opaque, force the combiner to opaque; otherwise,
        // default combiner to mod
        if (material->blendMode == 0) {
          textureCombiner = 0;
        } else {
          textureCombiner = 1;
        }

        shader = textureCombiner;

        uint16_t textureCoord = this->data->textureCoordCombos.data[textureCoordComboIndex];

        // If the texture coord is env, set env bit for texture
        if (textureCoord > 2u) {
          shader |= 8u;
        }

        // If the texture coord is T2, enable bit 15
        if (textureCoord == 1) {
          batch->shader |= 0x4000;
        }

        batch->shader |= shader << 4;
      // Multi texture
      } else {
        uint16_t shader[2];

        uint32_t textureIndex = 0;

        while (textureIndex < batch->textureCount) {
          bool isFirstTexture = textureIndex == 0;
          bool isLastTexture = textureIndex == batch->textureCount - 1;

          uint16_t textureCombiner = 0;

          // If this is the first texture and the batch material's blending mode is opaque,
          // override the combiner mode to opaque; otherwise, use the combiner mode from the
          // combiner combos
          if (isFirstTexture && material->blendMode == 0) {
            textureCombiner = 0;
          } else {
            textureCombiner = this->data->textureCombinerCombos.data[textureCombinerComboIndex + textureIndex];
          }

          shader[textureIndex] = textureCombiner;

          uint16_t textureCoord = this->data->textureCoordCombos.data[textureCoordComboIndex + textureIndex];

          // If the texture coord is env, set env bit for texture
          if (textureCoord > 2u) {
             shader[textureIndex] |= 8u;
          }

          // If this is the last texture and the texture coord is T2, enable bit 15
          if (isLastTexture && textureCoord == 1) {
            batch->shader |= 0x4000u;
          }

          ++textureIndex;
        }

        batch->shader |= shader[0] << 4 | shader[1];
      }
    }

    batchIndex++;
  }
}