almost works

This commit is contained in:
sShemet
2025-10-05 16:30:50 +05:00
parent f44ef257ae
commit 9a82929c8b
6 changed files with 101 additions and 76 deletions

View File

@@ -168,41 +168,53 @@ shadow_row_loop:
clear a2 // a2 = счётчик пикселей в строке (X координата)
li a1, 0x4 // a1 = сдвиг 1 пиксель вправо (4 бита)
// Внутренний цикл по пикселям в строке
shadow_pixel_loop:
sll v0, a2, 0x2 // v0 = смещение битов (X * 4)
sllv v0, t2, v0 // v0 = маска исходного пикселя
// Внутренний цикл по пикселям в строке
shadow_pixel_loop:
move a1, a2 // a1 = текущий X пиксель
addiu a1, a1, 0x1 // +1 пиксель вправо
sll a1, a1, 0x2 // ×4 (перевод в биты)
sll v0, a2, 0x2 // v0 = смещение исходного пикселя (X * 4)
sllv v0, t2, v0 // v0 = маска для исходного пикселя
and v0, t0, v0 // проверяем есть ли исходный пиксель
beq v0, zero, no_s // если нет, пропускаем
// ВЫЧИСЛЯЕМ АДРЕС ТЕНИ С УЧЕТОМ ГРАНИЦ
move t8, t7 // по умолчанию тот же спрайт
move v1, a1 // позиция тени в том же спрайте
// Если это пиксель 7 (последний), тень в следующем спрайте
sltiu v0, a2, 7 // проверяем X < 7
bne v0, zero, same_sprite // если не граничный, остаемся в том же спрайте
// Граничный случай: пиксель 7 -> тень в следующем спрайте, позиция 0
addiu t8, t7, 4 // следующий спрайт
li v1, 0x0 // позиция тени = 0 (младшие 4 бита)
same_sprite:
lw v0, 0x0(t8) // загружаем целевой спрайт для тени
beq v0, zero, no_s // если пикселя нет, пропускаем
nop
sllv a3, t2, v1 // маска для позиции тени
and v1, v0, a3 // проверяем занято ли место
bne v1, zero, no_s // если занято, пропускаем
sllv v1, t1, v1 // цвет тени в нужной позиции
or v0, v0, v1 // добавляем тень
sw v0, 0x0(t8) // сохраняем
// Проверяем граничный случай (8-й пиксель)
li v0, 0x7 // последний пиксель (X = 7)
bne a2, v0, normal_case // если не 8-й пиксель - обычная обработка
nop
// Граничный случай: 8-й пиксель исходного спрайта
// Тень будет в позиции a1 = 32 (8 × 4) - это следующий word!
addu t8, t7, s3 // адрес следующей строки
addiu t8, t8, 0x4 // переходим к следующему word
lw v1, 0x0(t8) // загружаем следующий word
li v0, 0xF // маска для ПЕРВОГО пикселя в новом word
and v0, v1, v0 // проверяем занятость (биты 0-3 нового word)
bne v0, zero, no_s // если занято - пропускаем
nop
move v0, t1 // цвет тени (в биты 0-3 нового word)
or v0, v1, v0 // добавляем тень
sw v0, 0x0(t8) // сохраняем
b no_s
nop
normal_case:
addu t8, t7, s3 // этот же word в следующей строке
lw v1, 0x0(t8) // следующая строка
sllv v0, t2, a1 // маска для пикселя тени
and v0, v1, v0 // проверяем занятость
bne v0, zero, no_s // если занято - пропускаем
nop
sllv v0, t1, a1 // цвет тени
or v0, v1, v0 // добавляем тень
sw v0, 0x0(t8) // сохраняем
no_s:
addiu a2, a2, 0x1 // следующий пиксель (X+1)
sltiu v0, a2, 0x8 // проверяем X < 8 (ВСЕ 8 пикселей!)
bne v0, zero, shadow_pixel_loop // продолжаем цикл по пикселям
addiu a1, a1, 0x4 // следующая позиция тени (+4 бита = +1 пиксель)
addiu a2, a2, 0x1 // следующий пиксель
sltiu v0, a2, 0x8 // X < 8 (все 8 пикселей!)
bne v0, zero, shadow_pixel_loop
nop
addiu t5, t5, 0x04
bne t5, s3, shadow_sprites_loop