Files
SergObsidian/PERSONAL PROJECTS/PS1 DOCS/PSX code - Texture show from file.md
2025-04-18 23:10:56 +05:00

5.9 KiB
Raw Blame History

Вот готовая программа для 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)

#include <sys/types.h>
#include <libetc.h>
#include <libgte.h>
#include <libgpu.h>
#include <libcd.h>

#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:
    ccpsx MAIN.C -o TEXTURE_DEMO.EXE
    
  2. Запишите на диск вместе с TEXTURE.BIN и SYSTEM.CNF.

6. Демонстрация эффекта

  • Текстура плавно "проявляется" (от чёрного к нормальной яркости) и затем исчезает.
  • Скорость регулируется fade_speed.

7. Оптимизации

  • Для плавности используется VSync(0).
  • DMA ускоряет загрузку текстуры.
  • Полупрозрачность GPU имитирует изменение яркости.

Этот код можно расширить для загрузки анимаций или сложных эффектов! 🎮