Вот готовая программа для **PlayStation 1**, которая загружает текстуру с CD-ROM, передаёт её в VRAM и плавно выводит на экран с анимацией яркости (от 0 до 128). Код использует **PsyQ SDK** и разбит на логические блоки. --- ### **1. Структура проекта** ``` texture_demo/ ├── MAIN.C # Основной код ├── TEXTURE.BIN # RAW-текстура 256x256 (16-бит RGB) └── SYSTEM.CNF # Конфигурационный файл ``` --- ### **2. Код программы (`MAIN.C`)** ```c #include #include #include #include #include #define SCREEN_WIDTH 320 #define SCREEN_HEIGHT 240 // Буфер для текстуры (256x256, 16-бит) #define TEX_SIZE (256 * 256 * 2) // 131072 байт uint16_t tex_buffer[256 * 256] __attribute__((aligned(64))); // Выравнивание для DMA // Параметры спрайта typedef struct { RECT img_rect; // Размеры текстуры TIM_IMAGE tim; // Данные TIM-файла int brightness; // Текущая яркость (0-128) int fade_speed; // Скорость изменения яркости } Sprite; void init() { // Инициализация системных библиотек ResetGraph(0); InitPad(NULL, 0, NULL, 0); CdInit(); // Настройка видеорежима (NTSC) SetVideoMode(MODE_NTSC); FntLoad(960, 256); FntOpen(16, 16, 256, 224, 0, 512); } void load_texture(const char* filename) { CdlFILE file; uint8_t sector_buffer[2048]; // Буфер для сектора CD // Поиск файла на диске if (CdSearchFile(&file, filename) == 0) { FntPrint("Error: File not found!\n"); return; } // Чтение текстуры в буфер через DMA CdRead(file.pos, (uint32_t*)tex_buffer, TEX_SIZE / 2048); CdReadSync(0); // Ожидание завершения } void draw_sprite(Sprite* sprite) { // Установка яркости (0-128 → 0.0-1.0) float alpha = (float)sprite->brightness / 128.0f; // Рисуем полноэкранный спрайт с альфа-смешением DR_MODE dr_mode; SetDrawMode(&dr_mode, 0, 0, GetTPage(0, 0, sprite->tim.prect->x, sprite->tim.prect->y), 0); SetSprt16(&sprite->img_rect); // 16-битный спрайт // Применяем яркость через полупрозрачность SetSemiTrans(&sprite->img_rect, 1); setRGB0(&sprite->img_rect, alpha * 255, alpha * 255, alpha * 255); // Вывод спрайта DrawPrim(&sprite->img_rect); } int main() { init(); // Инициализация // Загрузка текстуры load_texture("\\TEXTURE.BIN"); // Путь на CD // Настройка спрайта Sprite sprite = { .img_rect = {0, 0, SCREEN_WIDTH, SCREEN_HEIGHT}, .brightness = 0, .fade_speed = 1 }; // Загрузка текстуры в VRAM sprite.tim.mode = 0; sprite.tim.prect = (RECT*)tex_buffer; LoadImage(&sprite.tim.prect[0], &sprite.tim.pdata[0]); // Главный цикл while (1) { FntPrint("Fade Demo: Brightness = %d\n", sprite.brightness); // Плавное увеличение яркости sprite.brightness += sprite.fade_speed; if (sprite.brightness >= 128 || sprite.brightness <= 0) sprite.fade_speed *= -1; // Меняем направление // Отрисовка draw_sprite(&sprite); FntFlush(-1); // Синхронизация с VBlank VSync(0); } return 0; } ``` --- ### **3. Как это работает?** 1. **Инициализация**: - Настраивается видеорежим (NTSC 320x240). - Инициализируются CD-ROM и геймпад. 2. **Загрузка текстуры**: - Файл `TEXTURE.BIN` (RAW 256x256, 16-бит) читается с диска через DMA. - Данные копируются в буфер `tex_buffer`. 3. **Передача в VRAM**: - `LoadImage()` загружает текстуру в VRAM (адрес автоматически выбирается GPU). 4. **Плавное затемнение**: - В главном цикле меняется параметр `brightness` (0 → 128 → 0). - Яркость применяется через **полупрозрачность** (`SetSemiTrans`). 5. **Вывод**: - Спрайт рисуется на весь экран с текущей яркостью. --- ### **4. Требования к текстуре** - Формат: **RAW 16-бит RGB** (без заголовков). - Размер: **256x256** (можно изменить в коде). - Размещение: корень CD (`TEXTURE.BIN`). --- ### **5. Сборка** 1. Скомпилируйте через **PsyQ SDK**: ```bash ccpsx MAIN.C -o TEXTURE_DEMO.EXE ``` 2. Запишите на диск вместе с `TEXTURE.BIN` и `SYSTEM.CNF`. --- ### **6. Демонстрация эффекта** - Текстура плавно "проявляется" (от чёрного к нормальной яркости) и затем исчезает. - Скорость регулируется `fade_speed`. --- ### **7. Оптимизации** - Для плавности используется **VSync(0)**. - DMA ускоряет загрузку текстуры. - Полупрозрачность GPU имитирует изменение яркости. Этот код можно расширить для загрузки анимаций или сложных эффектов! 🎮