vault backup: 2025-04-20 00:15:46
This commit is contained in:
121
PERSONAL PROJECTS/P2EP/pseudoCode/MakeSmallChar.md
Normal file
121
PERSONAL PROJECTS/P2EP/pseudoCode/MakeSmallChar.md
Normal file
@@ -0,0 +1,121 @@
|
||||
``` c
|
||||
#include <libgte.h>
|
||||
#include <libgpu.h>
|
||||
#include <libgs.h>
|
||||
|
||||
/* Структуры данных */
|
||||
typedef struct {
|
||||
uint* next_block; // Следующий блок DMA (младшие 24 бита)
|
||||
uint control; // Контрольные биты DMA
|
||||
uint data_addr; // Адрес данных
|
||||
uint tpage_params; // Параметры текстуры (TPage)
|
||||
} DMAControlBlock;
|
||||
|
||||
typedef struct {
|
||||
short x, y; // Позиция символа
|
||||
short char_width; // Ширина символа
|
||||
ushort flags; // Флаги рендеринга
|
||||
uint* dma_head; // Голова DMA-цепочки
|
||||
uint* dma_tail; // Хвост DMA-цепочки
|
||||
} TextRenderState;
|
||||
|
||||
/* Константы */
|
||||
#define SCRAM_BASE 0x1F800000 // Быстрая память PS1
|
||||
#define DMA_MAGIC 0x80000000 // Флаг DMA-блока
|
||||
#define CHAR_OFFSET 0x20 // Смещение ASCII-кодов
|
||||
|
||||
/* Глобальные переменные (аналоги оригинальных) */
|
||||
static uint* gDmaNextFree = (uint*)0x8007CE68;
|
||||
static uint* gDmaCounter = (uint*)0x8007CE6C;
|
||||
static uint gActiveTpage = 0x8007CA0C;
|
||||
|
||||
/* Основная функция рендеринга текста */
|
||||
DMAControlBlock* RenderTextSystem(
|
||||
const char* text,
|
||||
short base_x,
|
||||
short base_y,
|
||||
uint color_flags,
|
||||
uint tpage_config
|
||||
) {
|
||||
/* Инициализация состояния */
|
||||
TextRenderState state;
|
||||
state.x = base_x;
|
||||
state.y = base_y;
|
||||
state.flags = color_flags;
|
||||
|
||||
/* Получаем начальный DMA-блок из SCRAM */
|
||||
DMAControlBlock* dma_blocks = (DMAControlBlock*)(*gDmaNextFree | DMA_MAGIC);
|
||||
state.dma_head = state.dma_tail = (uint*)dma_blocks;
|
||||
|
||||
/* Настройка параметров рендеринга */
|
||||
StoreColorToAddr(color_flags, tpage_config);
|
||||
InitDMAtextChain(dma_blocks, base_x, base_y);
|
||||
|
||||
/* Основной цикл обработки текста */
|
||||
while (*text) {
|
||||
char current_char = *text++;
|
||||
ushort char_code = current_char - CHAR_OFFSET;
|
||||
|
||||
/* Особые обработки для специфичных символов */
|
||||
switch (current_char) {
|
||||
case 'g': case 'j': case 'p': case 'q': case 'y':
|
||||
base_y += 2; // Смещение для символов с хвостами
|
||||
break;
|
||||
}
|
||||
|
||||
/* Позиционирование символа */
|
||||
short render_x, render_y;
|
||||
if (state.flags & 0x10) {
|
||||
/* Альтернативный режим позиционирования */
|
||||
render_x = base_x - GetCharLeftOffset(char_code);
|
||||
render_y = base_y + GetCharBaseline(char_code);
|
||||
} else {
|
||||
/* Стандартный режим */
|
||||
render_x = base_x + dma_blocks->char_width * 8;
|
||||
render_y = base_y;
|
||||
}
|
||||
|
||||
/* Генерация DMA-команд для символа */
|
||||
DMAControlBlock* new_block = AllocDMABlock();
|
||||
SetupCharRender(new_block, char_code, render_x, render_y);
|
||||
|
||||
/* Добавление в цепочку */
|
||||
state.dma_tail->next_block = (uint)new_block & 0xFFFFFF;
|
||||
state.dma_tail = new_block;
|
||||
|
||||
/* Обновление позиции */
|
||||
if (dma_blocks->char_width == 0) {
|
||||
state.dma_head = new_block;
|
||||
dma_blocks->char_width = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Финализация текстурных страниц */
|
||||
for (int i = 0; i < 2; i++) {
|
||||
DMAControlBlock* tpage_block = AllocDMABlock();
|
||||
SetDrawTPage(tpage_block, 0, 1, gActiveTpage);
|
||||
state.dma_tail->next_block = (uint)tpage_block & 0xFFFFFF;
|
||||
state.dma_tail = tpage_block;
|
||||
}
|
||||
|
||||
return dma_blocks;
|
||||
}
|
||||
|
||||
/* Вспомогательные функции */
|
||||
static DMAControlBlock* AllocDMABlock() {
|
||||
DMAControlBlock* block = (DMAControlBlock*)(*gDmaNextFree | DMA_MAGIC);
|
||||
(*gDmaCounter)--;
|
||||
*gDmaNextFree = (*gDmaNextFree & 0xFF000000) | (*block & 0xFFFFFF);
|
||||
return block;
|
||||
}
|
||||
|
||||
static void SetupCharRender(DMAControlBlock* block, ushort char_code, short x, short y) {
|
||||
/* Настройка параметров символа */
|
||||
block->control = 0x1000000; // Базовые флаги DMA
|
||||
block->data_addr = GetCharDataAddr(char_code);
|
||||
block->tpage_params = (y << 16) | x; // Позиция
|
||||
|
||||
/* Дополнительные настройки из оригинального кода */
|
||||
block->control |= 0x64808080; // Специфичные флаги PS1
|
||||
}
|
||||
```
|
||||
Reference in New Issue
Block a user