123 lines
6.1 KiB
NASM
123 lines
6.1 KiB
NASM
/////////////////////////////////////////////////////////////////////////////////
|
||
//
|
||
// Persona 2 Eternal Punishment (PSX) JAP / Custom Name Render In Battle VRAM
|
||
// Author: Sergey Shemet 24/01/2026
|
||
//
|
||
|
||
customNameRender:
|
||
// _4bit_conversion_table2:
|
||
// lui t8, 0x1f80
|
||
// ori t8, t8, 0x390
|
||
// lui t7, 0x8001
|
||
// ori t7, t7, 0x5fc
|
||
// lw t5, 0x0(t7)
|
||
// lw t6, 0x4(t7)
|
||
// sw t5, 0x0(t8)
|
||
// sw t6, 0x4(t8)
|
||
// lw t5, 0x8(t7)
|
||
// lw t6, 0xC(t7)
|
||
// sw t5, 0x8(t8)
|
||
// sw t6, 0xC(t8)
|
||
// lw t5, 0x10(t7)
|
||
// lw t6, 0x14(t7) //Удалим этот код, потому что эта таблица в 99.999999% есть в scratchpad
|
||
// sw t5, 0x10(t8)
|
||
// sw t6, 0x14(t8)
|
||
// lw t5, 0x18(t7)
|
||
// lw t6, 0x1C(t7)
|
||
// sw t5, 0x18(t8)
|
||
// sw t6, 0x1C(t8)
|
||
|
||
// make_sprite_size_table2:
|
||
// lui s3, 0x1f80
|
||
// ori s3, 0x03f0
|
||
// lui v0, 0x0403
|
||
// ori v0, 0x0201 //И эта моя кастомная таблица тоже
|
||
// sw v0, 0x0(s3)
|
||
// lui v1, 0x0706
|
||
// ori v1, 0x0504
|
||
// sw v1, 0x4(s3)
|
||
|
||
|
||
|
||
// Занятые регистры после перехода из процедуры рендеринга
|
||
// ИХ НЕ ТРОГАТЬ (Если трогать, то сохранять в стеке, либо в вызове make_char_line_in_scratch)
|
||
// s3 - входящий a0 функции (используется позже в коде)
|
||
// s4 - адрес параметров перса (смещение 0x54)
|
||
// s5 - счётчик персов
|
||
// s6 - глобальный RECT.x VRAM
|
||
|
||
//адрес имени в a0
|
||
|
||
// заполняем буфер и активируем счётчик в зависимости от типа хранения имени
|
||
clear a1
|
||
clear a2
|
||
|
||
|
||
lui v1, MyAddr
|
||
lh v0, 0x0(a0)
|
||
nop
|
||
srl v0, v0, 0xD // Проверяем 13-й бит (имя в моём формате)
|
||
bne v0, zero, read_chars_rus // Если установлен, читаем текст по-другому
|
||
nop
|
||
|
||
read_chars_jap: //читаем японское имя ГГ из IS
|
||
lbu v0, 0x0(a0)
|
||
nop
|
||
|
||
sb v0, -0x0c(v1) // Запись символа в буфер
|
||
beq v0, zero, end_of_name_read
|
||
nop
|
||
addiu v1, 0x1 //Увеличиваем адрес записи в буфер
|
||
addiu a2, 0x1 //Счётчик +1
|
||
sltiu v0, a2, 0x7
|
||
bne v0, zero, read_chars_jap //Продолжаем 6 символов... TODO: Считывать до управляющего кода! Хотя он и так остановится на 0x00 в следующей функции.
|
||
addiu a0, 0x2 //адрес чтения + 2
|
||
|
||
j end_of_name_read //Пропускаем чтение русского имени
|
||
nop
|
||
|
||
|
||
read_chars_rus: //Читаем русское имя из EP
|
||
lh v0, 0x0(a0)
|
||
nop
|
||
andi a2, v0, 0xFF //чистим количество символов и превращаем в счётчик
|
||
addiu a0, 2 //Смещаем адрес чтения текста (пропускаем управляющий код)
|
||
read_rus_char:
|
||
lbu v0, 0x0(a0) //грузим символ...
|
||
nop
|
||
sb v0, -0x0c(v1)
|
||
addiu v1, 0x1 //Увеличиваем адрес записи в буфер
|
||
addiu a1, 0x1 //Счётчик +1
|
||
bne a1, a2, read_rus_char //Продолжаем, пока не достигнем счётчика символов
|
||
addiu a0, 0x1 //адрес чтения + 1
|
||
|
||
end_of_name_read:
|
||
|
||
lui v0, 0x1f80 //Адрес хранения таблицы количества спрайтов на количество символов
|
||
ori v0, 0x03f0
|
||
|
||
move a0, a2 // Перебрасываем cчётчик символов в a0
|
||
addu v0, v0, a0 // получаем адрес количества спрайтов из таблицы
|
||
addiu v0, -0x1 // index -1
|
||
lbu a1, 0x0(v0) // Читаем количество ширину спрайтов в a1
|
||
nop
|
||
|
||
sll a1, 1 //*2 = Ширина в 16 битах
|
||
|
||
sh a1, 0x5c(sp) //Сохраняем rect.w в стек
|
||
sra a1, 1 //Возвращаем ширину блоков спрайта и передаём в функцию
|
||
|
||
lui t3, 0x8009
|
||
ori t3, t3, 0x1500 // Начало данных спрайта в RAM (LoadImage не работает со scratch!)
|
||
|
||
jal make_char_line_in_scratch //Формируем символы в RAM
|
||
nop
|
||
|
||
addiu a0, sp, 0x58 //RECT хранится в стеке...
|
||
jal 0x80054894 //Вызов LoadImage
|
||
move a1, v0 //Адрес данных символов, которые вернулись из процедуры формирования пикулей
|
||
jal 0x800545e8 //Тут же вызов DrawSync
|
||
clear a0 //Обязательно обнуляем аргумент 0
|
||
|
||
j 0x800d2268 //Возврат в оригинальную процедуру на команду смещения глобального X
|
||
nop |