* Evaluates the register modifiers and integrates them into the preprocessed sprite layout. * @param object ResolverObject owning the temporary storage. * @param resolved_var10 The value of var10 the action-1-2-3 chain was evaluated for. * @param resolved_sprite Result sprite of the action-1-2-3 chain. */
| 663 | * @param resolved_sprite Result sprite of the action-1-2-3 chain. |
| 664 | */ |
| 665 | void SpriteLayoutProcessor::ProcessRegisters(const ResolverObject &object, uint8_t resolved_var10, uint32_t resolved_sprite) |
| 666 | { |
| 667 | assert(this->raw_layout != nullptr); |
| 668 | const TileLayoutRegisters *regs = this->raw_layout->registers.empty() ? nullptr : this->raw_layout->registers.data(); |
| 669 | bool ground = true; |
| 670 | for (DrawTileSeqStruct &result : this->result_seq) { |
| 671 | TileLayoutFlags flags = TLF_NOTHING; |
| 672 | if (regs != nullptr) flags = regs->flags; |
| 673 | |
| 674 | /* Is the sprite or bounding box affected by an action-1-2-3 chain? */ |
| 675 | if (HasBit(result.image.sprite, SPRITE_MODIFIER_CUSTOM_SPRITE) || (flags & TLF_SPRITE_REG_FLAGS)) { |
| 676 | /* Does the var10 value apply to this sprite? */ |
| 677 | uint8_t var10 = (flags & TLF_SPRITE_VAR10) ? regs->sprite_var10 : (ground && this->separate_ground ? 1 : 0); |
| 678 | if (var10 == resolved_var10) { |
| 679 | /* Apply registers */ |
| 680 | if ((flags & TLF_DODRAW) && object.GetRegister(regs->dodraw) == 0) { |
| 681 | result.image.sprite = 0; |
| 682 | } else { |
| 683 | if (HasBit(result.image.sprite, SPRITE_MODIFIER_CUSTOM_SPRITE)) result.image.sprite += resolved_sprite; |
| 684 | if (flags & TLF_SPRITE) { |
| 685 | int16_t offset = static_cast<int16_t>(object.GetRegister(regs->sprite)); // mask to 16 bits to avoid trouble |
| 686 | if (!HasBit(result.image.sprite, SPRITE_MODIFIER_CUSTOM_SPRITE) || (offset >= 0 && offset < regs->max_sprite_offset)) { |
| 687 | result.image.sprite += offset; |
| 688 | } else { |
| 689 | result.image.sprite = SPR_IMG_QUERY; |
| 690 | } |
| 691 | } |
| 692 | |
| 693 | if (result.IsParentSprite()) { |
| 694 | if (flags & TLF_BB_XY_OFFSET) { |
| 695 | result.origin.x += object.GetRegister(regs->delta.parent[0]); |
| 696 | result.origin.y += object.GetRegister(regs->delta.parent[1]); |
| 697 | } |
| 698 | if (flags & TLF_BB_Z_OFFSET) result.origin.z += object.GetRegister(regs->delta.parent[2]); |
| 699 | } else { |
| 700 | if (flags & TLF_CHILD_X_OFFSET) result.origin.x += object.GetRegister(regs->delta.child[0]); |
| 701 | if (flags & TLF_CHILD_Y_OFFSET) result.origin.y += object.GetRegister(regs->delta.child[1]); |
| 702 | } |
| 703 | } |
| 704 | } |
| 705 | } |
| 706 | |
| 707 | /* Is the palette affected by an action-1-2-3 chain? */ |
| 708 | if (result.image.sprite != 0 && (HasBit(result.image.pal, SPRITE_MODIFIER_CUSTOM_SPRITE) || (flags & TLF_PALETTE_REG_FLAGS))) { |
| 709 | /* Does the var10 value apply to this sprite? */ |
| 710 | uint8_t var10 = (flags & TLF_PALETTE_VAR10) ? regs->palette_var10 : (ground && this->separate_ground ? 1 : 0); |
| 711 | if (var10 == resolved_var10) { |
| 712 | /* Apply registers */ |
| 713 | if (HasBit(result.image.pal, SPRITE_MODIFIER_CUSTOM_SPRITE)) result.image.pal += resolved_sprite; |
| 714 | if (flags & TLF_PALETTE) { |
| 715 | int16_t offset = static_cast<int16_t>(object.GetRegister(regs->palette)); // mask to 16 bits to avoid trouble |
| 716 | if (!HasBit(result.image.pal, SPRITE_MODIFIER_CUSTOM_SPRITE) || (offset >= 0 && offset < regs->max_palette_offset)) { |
| 717 | result.image.pal += offset; |
| 718 | } else { |
| 719 | result.image.sprite = SPR_IMG_QUERY; |
| 720 | result.image.pal = PAL_NONE; |
| 721 | } |
| 722 | } |
no test coverage detected