Files
SergObsidian/PERSONAL PROJECTS/PS1 DOCS/fade calculation.md
2025-04-19 03:02:43 +05:00

121 lines
5.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

Давайте тщательно разберём функцию `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. Для модификации эффектов работайте с волновой таблицей и цветовыми множителями.