Files
SergObsidian/PERSONAL PROJECTS/PSX code - Load texture from SECTOR!.md
2025-04-18 22:10:50 +05:00

169 lines
6.2 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.

Вот модифицированная программа для **PlayStation 1**, которая загружает текстуру напрямую из указанного сектора CD-ROM в RAM, а затем выводит её на экран с эффектом плавного появления. Код адаптирован для работы с "сырыми" секторами диска.
---
### **1. Изменённый код (`MAIN.C`)**
```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_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 без файловой системы! 📀