Вот модифицированная программа для **PlayStation 1**, которая загружает текстуру напрямую из указанного сектора CD-ROM в RAM, а затем выводит её на экран с эффектом плавного появления. Код адаптирован для работы с "сырыми" секторами диска. --- ### **1. Изменённый код (`MAIN.C`)** ```c #include #include #include #include #include #define SCREEN_WIDTH 320 #define SCREEN_HEIGHT 240 // Параметры текстуры (256x256, 16-бит) #define TEX_WIDTH 256 #define TEX_HEIGHT 256 #define TEX_SIZE (TEX_WIDTH * TEX_HEIGHT * 2) // 131072 байт (16-бит) #define TEX_SECTORS (TEX_SIZE / 2048) // Размер в секторах CD (1 сектор = 2048 байт) // Буфер для текстуры в RAM (выровнен для DMA) uint16_t tex_buffer[TEX_WIDTH * TEX_HEIGHT] __attribute__((aligned(64))); // Структура спрайта typedef struct { RECT img_rect; // Размеры текстуры TIM_IMAGE tim; // Данные TIM-формата (не используется, но нужен для LoadImage) int brightness; // Текущая яркость (0-128) int fade_speed; // Скорость изменения яркости } Sprite; void init() { ResetGraph(0); InitPad(NULL, 0, NULL, 0); CdInit(); SetVideoMode(MODE_NTSC); FntLoad(960, 256); FntOpen(16, 16, 256, 224, 0, 512); } void load_texture_from_sector(int start_sector) { // Чтение текстуры из указанного сектора CD-ROM в RAM через DMA CdRead(start_sector, (uint32_t*)tex_buffer, TEX_SECTORS); CdReadSync(0); // Ожидание завершения DMA } void draw_sprite(Sprite* sprite) { // Настройка полупрозрачности для эффекта яркости float alpha = (float)sprite->brightness / 128.0f; DR_MODE dr_mode; SetDrawMode(&dr_mode, 0, 0, GetTPage(0, 0, 0, 0), 0); SetSprt16(&sprite->img_rect); SetSemiTrans(&sprite->img_rect, 1); setRGB0(&sprite->img_rect, alpha * 255, alpha * 255, alpha * 255); DrawPrim(&sprite->img_rect); } int main() { init(); // Параметры загрузки (пример: текстура начинается с сектора 1000) int texture_start_sector = 1000; // Замените на реальный сектор! load_texture_from_sector(texture_start_sector); // Настройка спрайта Sprite sprite = { .img_rect = {0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0, 0}, .brightness = 0, .fade_speed = 1 }; // Загрузка текстуры в VRAM (адрес в RAM -> VRAM) RECT vram_rect = {0, 0, TEX_WIDTH, TEX_HEIGHT}; // Куда загружать в VRAM LoadImage(&vram_rect, (uint32_t*)tex_buffer); // Главный цикл while (1) { FntPrint("Sector Load Demo\nBrightness: %d\nSector: %d", sprite.brightness, texture_start_sector); // Плавное изменение яркости sprite.brightness += sprite.fade_speed; if (sprite.brightness >= 128 || sprite.brightness <= 0) sprite.fade_speed *= -1; // Отрисовка draw_sprite(&sprite); FntFlush(-1); VSync(0); } return 0; } ``` --- ### **2. Ключевые изменения** 1. **Загрузка из сектора**: - Вместо поиска файла (`CdSearchFile`) используется прямой доступ к сектору: ```c CdRead(start_sector, (uint32_t*)tex_buffer, TEX_SECTORS); ``` - `start_sector` — начальный сектор текстуры на диске (например, `1000`). 2. **Размер текстуры**: - Рассчитывается автоматически: ```c #define TEX_SECTORS (TEX_SIZE / 2048) // 2048 байт = 1 сектор Mode 1 ``` 3. **Выравнивание в RAM**: - Буфер `tex_buffer` выровнен по 64 байта для эффективного DMA: ```c uint16_t tex_buffer[...] __attribute__((aligned(64))); ``` 4. **Загрузка в VRAM**: - `LoadImage` копирует данные из `tex_buffer` (RAM) в VRAM: ```c LoadImage(&vram_rect, (uint32_t*)tex_buffer); ``` --- ### **3. Как подготовить диск** 1. **Конвертируйте текстуру** в RAW 16-бит (например, через Photoshop или `ffmpeg`): ```bash ffmpeg -i texture.png -f rawvideo -pix_fmt rgb565 texture.raw ``` 2. **Запишите RAW-данные** на CD в нужный сектор (например, с помощью `mkpsxiso`): ```bash mkpsxiso -y -o texture.cue -c "CDROM_DATA" texture.raw ``` - Узнайте начальный сектор через `cdrdao` или hex-редактор. --- ### **4. Важные нюансы** - **Режим CD-ROM**: Данные должны быть записаны в **Mode 1** (2048 байт/сектор). - **Размер текстуры**: Должен быть кратен размеру сектора (иначе чтение "сломает" данные). - **Проверка сектора**: Убедитесь, что сектор не занят другими файлами. --- ### **5. Пример для сборки** 1. Скомпилируйте: ```bash ccpsx MAIN.C -o CD_SECTOR_DEMO.EXE ``` 2. Запишите на диск, указав в `SYSTEM.CNF`: ``` BOOT = cdrom:\CD_SECTOR_DEMO.EXE;1 ``` --- ### **6. Дополнительная оптимизация** Для работы с **Mode 2 XA** (формат видео) измените: ```c CdReadMode(CdMode_CD_XA); // Перед CdRead ``` и корректируйте размер сектора (2336 байт). --- Этот код идеален для демо-сцен, где нужно напрямую читать графику с CD без файловой системы! 📀