diff --git a/IS_charload_grouped.asm b/IS_charload_grouped.asm index 51d0557..b1508c6 100644 --- a/IS_charload_grouped.asm +++ b/IS_charload_grouped.asm @@ -142,7 +142,7 @@ sprite_end: lui a0, 0x1f80 ori a0, a0, 0x1c0 -make_shadow: //s3 - line width in bytes +make_shadow: //s3 - line width in bytes, a0 - data start move a1, s3 // a1 = ширина sll a1, 0x1 //a1 = смещение на 3 строку (ширина * 2) sll v0, s3, 3 //v0 = ширина строки * 8 @@ -170,25 +170,37 @@ shadow_row_loop: // Внутренний цикл по пикселям в строке shadow_pixel_loop: - sll v0, a2, 0x2 // v0 = смещение битов для исходного пикселя (X * 4) - sllv v0, t2, v0 // v0 = маска для исходного пикселя (0xF << (X*4)) - and v0, t0, v0 // v0 = проверяем есть ли исходный пиксель - beq v0, zero, no_s // если пикселя нет, пропускаем - sllv v0, t2, a1 // v0 = маска для пикселя тени (0xF << позиция_тени) - addu t8, t7, s3 //этот же байт в следующей строке = наш адрес + ширина строки - lw v1, 0x0(t8) // v1 = следующая строка (где будет тень) // смещение на ВСЮ ШИРИНУ СТРОКИ - - nop - and v0, v1, v0 // проверяем занято ли место для тени - bne v0, zero, no_s // если место занято, пропускаем - sllv v0, t1, a1 // v0 = цвет тени в нужной позиции + sll v0, a2, 0x2 // v0 = смещение битов (X * 4) + sllv v0, t2, v0 // v0 = маска исходного пикселя + and v0, t0, v0 // проверяем есть ли исходный пиксель + beq v0, zero, no_s // если нет, пропускаем - or v0, v1, v0 // добавляем тень к следующей строке - sw v0, 0x0(t8) // сохраняем строку с тенью + // ВЫЧИСЛЯЕМ АДРЕС ТЕНИ С УЧЕТОМ ГРАНИЦ + 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) // загружаем целевой спрайт для тени + 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) // сохраняем no_s: addiu a2, a2, 0x1 // следующий пиксель (X+1) - sltiu v0, a2, 0x7 // проверяем X < 7 (только 7 из 8 пикселей) + sltiu v0, a2, 0x8 // проверяем X < 8 (ВСЕ 8 пикселей!) bne v0, zero, shadow_pixel_loop // продолжаем цикл по пикселям addiu a1, a1, 0x4 // следующая позиция тени (+4 бита = +1 пиксель)