aboutsummaryrefslogtreecommitdiff
path: root/libpsn00b/psxgpu/image.c
diff options
context:
space:
mode:
authorspicyjpeg <thatspicyjpeg@gmail.com>2025-01-28 14:42:53 +0100
committerGitHub <noreply@github.com>2025-01-28 14:42:53 +0100
commit5d9aa2d3dfc7d6e51c2eb942ab4cdbae5571a40a (patch)
treece1e647e7a7cc7322b1c4f60497781bc7cf5c4fd /libpsn00b/psxgpu/image.c
parent787db196ad3c4e945792997111d759f82110775a (diff)
parentdeb1b484bcea8885ced69ba2711e5830d9a6e626 (diff)
Merge pull request #89 from yogi313/masterHEADmaster
Fix TIM compatibility and improve TIM validation.
Diffstat (limited to 'libpsn00b/psxgpu/image.c')
-rw-r--r--libpsn00b/psxgpu/image.c54
1 files changed, 35 insertions, 19 deletions
diff --git a/libpsn00b/psxgpu/image.c b/libpsn00b/psxgpu/image.c
index 3a2bb8f..71e554b 100644
--- a/libpsn00b/psxgpu/image.c
+++ b/libpsn00b/psxgpu/image.c
@@ -29,13 +29,27 @@ static int _next_saved_rect = 0;
static void _dma_transfer(const RECT *rect, uint32_t *data, int write) {
size_t length = rect->w * rect->h;
+ size_t dma_chunk_length = DMA_CHUNK_LENGTH;
if (length % 2)
_sdk_log("can't transfer an odd number of pixels\n");
length /= 2;
- if ((length >= DMA_CHUNK_LENGTH) && (length % DMA_CHUNK_LENGTH)) {
- _sdk_log("transfer data length (%d) is not a multiple of %d, rounding\n", length, DMA_CHUNK_LENGTH);
- length += DMA_CHUNK_LENGTH - 1;
+ if (length >= dma_chunk_length) {
+ uint32_t tail = length % dma_chunk_length;
+ if(tail) {
+ // index length w h
+ // 0 80 5 16
+ // 1 34 2 17
+ // 2 36 6 6
+ // 3 38 2 19
+ // 4 40 5 8
+ // 5 42 6 7
+ // 6 44 11 4
+ // 7 46 23 2
+ const uint8_t dma_chunk_length_lookup[8] = {8, 1, 2, 1, 4, 1, 2, 1};
+ dma_chunk_length = dma_chunk_length_lookup[tail % 8];
+ _sdk_log("transfer data length / 2 (%d) is not a multiple of %d, changing dma_chunk_length %d\n", length, DMA_CHUNK_LENGTH, dma_chunk_length);
+ }
}
while (!(GPU_GP1 & (1 << 26)))
@@ -66,11 +80,11 @@ static void _dma_transfer(const RECT *rect, uint32_t *data, int write) {
__asm__ volatile("");
DMA_MADR(DMA_GPU) = (uint32_t) data;
- if (length < DMA_CHUNK_LENGTH)
+ if (length < dma_chunk_length)
DMA_BCR(DMA_GPU) = 0x00010000 | length;
else
- DMA_BCR(DMA_GPU) = DMA_CHUNK_LENGTH |
- ((length / DMA_CHUNK_LENGTH) << 16);
+ DMA_BCR(DMA_GPU) = dma_chunk_length |
+ ((length / dma_chunk_length) << 16);
DMA_CHCR(DMA_GPU) = 0x01000200 | write;
}
@@ -169,6 +183,7 @@ int GsGetTimInfo(const uint32_t *tim, GsIMAGE *info) {
if ((*(tim++) & 0xffff) != 0x0010)
return 1;
+ *info = (GsIMAGE){0};
info->pmode = *(tim++);
if (info->pmode & 8) {
const uint32_t *palette_end = tim;
@@ -179,15 +194,15 @@ int GsGetTimInfo(const uint32_t *tim, GsIMAGE *info) {
info->clut = (uint32_t *) tim;
tim = palette_end;
- } else {
- info->clut = 0;
}
- tim++;
- *((uint32_t *) &(info->px)) = *(tim++);
- *((uint32_t *) &(info->pw)) = *(tim++);
- info->pixel = (uint32_t *) tim;
-
+ uint32_t plength = *(tim++);
+ // bnum(4 bytes) + pos(4 bytes) + size(4 bytes)
+ if (plength > 12) {
+ *((uint32_t *) &(info->px)) = *(tim++);
+ *((uint32_t *) &(info->pw)) = *(tim++);
+ info->pixel = (uint32_t *) tim;
+ }
return 0;
}
@@ -197,6 +212,7 @@ int GetTimInfo(const uint32_t *tim, TIM_IMAGE *info) {
if ((*(tim++) & 0xffff) != 0x0010)
return 1;
+ *info = (TIM_IMAGE){0};
info->mode = *(tim++);
if (info->mode & 8) {
const uint32_t *palette_end = tim;
@@ -206,13 +222,13 @@ int GetTimInfo(const uint32_t *tim, TIM_IMAGE *info) {
info->caddr = (uint32_t *) &tim[2];
tim = palette_end;
- } else {
- info->caddr = 0;
}
- tim++;
- info->prect = (RECT *) tim;
- info->paddr = (uint32_t *) &tim[2];
-
+ uint32_t plength = *(tim++);
+ // bnum(4 bytes) + pos(4 bytes) + size(4 bytes)
+ if (plength > 12) {
+ info->prect = (RECT *) tim;
+ info->paddr = (uint32_t *) &tim[2];
+ }
return 0;
}