121 lines
5.6 KiB
Markdown
121 lines
5.6 KiB
Markdown
Давайте тщательно разберём функцию `fade_calculation` — это ключевая функция управления плавными переходами яркости в игре. Вот полный анализ:
|
||
|
||
---
|
||
|
||
### **Назначение функции**
|
||
Функция вычисляет плавные цветовые переходы для эффектов затемнения/появления, используя:
|
||
1. **Временную синхронизацию** (через VSync)
|
||
2. **Циклическую анимацию** на основе волновой таблицы
|
||
3. **Аппаратный формат цвета PS1** (BGR555)
|
||
|
||
---
|
||
|
||
### **Структура данных (DWORD_8007caa8)**
|
||
Глобальная структура с такими ключевыми полями:
|
||
|
||
| Смещение | Тип | Описание |
|
||
|----------|-----------|-----------------------------------|
|
||
| +0x00 | uint | Флаг активности (param_1 & 1) |
|
||
| +0x04 | int | Предыдущий таймстамп VSync |
|
||
| +0x08 | int | Дельта времени между кадрами |
|
||
| +0x14 | int | Шаг анимации |
|
||
| +0x18 | int | Базовое смещение |
|
||
| +0x1c | uint | Текущее смещение анимации |
|
||
| +0x84 | int | Позиция в волновой таблице (0-63) |
|
||
| +0x88 | short[64] | Волновая таблица (амплитуды) |
|
||
| +0x126 | ushort | Результирующий цвет (BGR555) |
|
||
| +0x128 | byte | Множитель красного (R) |
|
||
| +0x129 | byte | Множитель зелёного (G) |
|
||
| +0x12a | byte | Множитель синего (B) |
|
||
|
||
---
|
||
|
||
### **Пошаговая работа функции**
|
||
|
||
1. **Синхронизация времени**:
|
||
```c
|
||
iVar2 = callVsyncWithParam(0xffffffff); // Получаем текущее время
|
||
*(int *)(DWORD_8007caa8 + 8) = iVar2 - *(int *)(DWORD_8007caa8 + 4); // Дельта времени
|
||
```
|
||
|
||
2. **Обновление позиции анимации**:
|
||
```c
|
||
iVar8 = iVar8 + *(int *)(dVar1 + 8); // Увеличиваем позицию на дельту времени
|
||
iVar8 = iVar8 + (iVar2 >> 6) * -0x40; // Обеспечиваем цикл 0-63 (64 позиции)
|
||
*(int *)(dVar1 + 0x84) = iVar8; // Сохраняем новую позицию
|
||
```
|
||
|
||
3. **Расчёт компонент цвета**:
|
||
Для каждой RGB-компоненты:
|
||
- Берётся значение из волновой таблицы по текущей позиции
|
||
- Умножается на множитель (0x128-0x12a)
|
||
- Нормализуется сдвигом `>> 0xC` (деление на 4096)
|
||
```c
|
||
// Красная компонента (R)
|
||
(uint)*(byte *)(dVar1 + 0x128) * (int)*(short *)(dVar1 + (iVar8 + ...) * 2 + 0x88) >> 0xc;
|
||
|
||
// Зелёная (G) - со смещением +0x20
|
||
(uint)*(byte *)(dVar1 + 0x129) * (int)*(short *)(dVar1 + (iVar6 + ...) * 2 + 0x88) >> 0xc;
|
||
|
||
// Синяя (B)
|
||
(uint)*(byte *)(dVar1 + 0x12a) * (int)*(short *)(dVar1 + (iVar7 + ...) * 2 + 0x88) >> 0xc;
|
||
```
|
||
|
||
4. **Формирование цвета**:
|
||
Компоненты объединяются в формат BGR555 с битом прозрачности:
|
||
```c
|
||
*(ushort *)(dVar1 + 0x126) =
|
||
(R & 0x1F) |
|
||
((G & 0x1F) << 5) |
|
||
((B & 0x1F) << 10) |
|
||
0x8000; // Флаг прозрачности
|
||
```
|
||
|
||
5. **Копирование состояния**:
|
||
```c
|
||
// Копирует 32 байта из +0x108...+0x124 в +0x50...+0x6c
|
||
*(undefined4 *)(dVar1 + 0x50) = *(undefined4 *)(dVar1 + 0x108);
|
||
// ... и так для 8 полей ...
|
||
```
|
||
|
||
---
|
||
|
||
### **Особенности волновой таблицы**
|
||
- Содержит 64 значения (short) по смещению `+0x88`
|
||
- Значения обычно в диапазоне 0-4095 (для >> 0xC)
|
||
- Зелёная компонента использует смещение +32 (+0x20) для фазового сдвига
|
||
|
||
---
|
||
|
||
### **Как управлять эффектом?**
|
||
1. **Скорость анимации**:
|
||
- Измените шаг в `*(int *)(dVar1 + 8)`
|
||
- Или модифицируйте дельту времени в `callVsyncWithParam`
|
||
|
||
2. **Интенсивность**:
|
||
```c
|
||
// Увеличьте множители (по умолчанию 0-255):
|
||
*(byte *)(dVar1 + 0x128) = 0xFF; // Максимальный красный
|
||
```
|
||
|
||
3. **Палитра**:
|
||
Подмените волновую таблицу:
|
||
```c
|
||
*(short *)(dVar1 + 0x88 + i*2) = new_value;
|
||
```
|
||
|
||
---
|
||
|
||
### **Пример работы**
|
||
```mermaid
|
||
sequenceDiagram
|
||
loop Каждый кадр
|
||
VSync->>+fade_calculation: Время
|
||
fade_calculation->>Волновая таблица: Чтение амплитуды
|
||
fade_calculation->>RGB: Расчёт компонент
|
||
fade_calculation->>BGR555: Упаковка цвета
|
||
fade_calculation->>OT: Запись команды
|
||
end
|
||
```
|
||
|
||
Функция — это сердце системы плавных переходов, где все вычисления оптимизированы под PS1. Для модификации эффектов работайте с волновой таблицей и цветовыми множителями. |