///////////////////////////////////////////////////////////////////////////////// // // 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