aboutsummaryrefslogtreecommitdiff
path: root/libpsn00b/psxgpu/image.c
diff options
context:
space:
mode:
authorspicyjpeg <thatspicyjpeg@gmail.com>2022-12-18 14:00:52 +0100
committerspicyjpeg <thatspicyjpeg@gmail.com>2022-12-18 14:00:52 +0100
commit3b7c46ab74548a9a79bfb867551c51dd877c8f4d (patch)
treeb001e9875385df3a917e51399e2d20ee559d65b0 /libpsn00b/psxgpu/image.c
parent70833192a803061008d2221b27e9baada6042c90 (diff)
downloadpsn00bsdk-3b7c46ab74548a9a79bfb867551c51dd877c8f4d.tar.gz
Misc. bugfixes, add support for DRAWENV texture windows
Diffstat (limited to 'libpsn00b/psxgpu/image.c')
-rw-r--r--libpsn00b/psxgpu/image.c36
1 files changed, 29 insertions, 7 deletions
diff --git a/libpsn00b/psxgpu/image.c b/libpsn00b/psxgpu/image.c
index e73505f..fc018a4 100644
--- a/libpsn00b/psxgpu/image.c
+++ b/libpsn00b/psxgpu/image.c
@@ -12,7 +12,17 @@
#include <psxgpu.h>
#include <hwregs_c.h>
-#define DMA_CHUNK_LENGTH 8
+#define QUEUE_LENGTH 16
+#define DMA_CHUNK_LENGTH 8
+
+/* Internal globals */
+
+// LoadImage() and StoreImage() run asynchronously but may be called with a
+// pointer to a RECT struct in the stack, which might no longer be valid by the
+// time the transfer is actually started. This buffer is used to store a copy
+// of all RECTs passed to LoadImage()/StoreImage() as a workaround.
+static RECT _saved_rects[QUEUE_LENGTH];
+static int _next_saved_rect = 0;
/* Private utilities */
@@ -51,21 +61,33 @@ static void _dma_transfer(const RECT *rect, uint32_t *data, int write) {
/* VRAM transfer API */
int LoadImage(const RECT *rect, const uint32_t *data) {
+ int index = _next_saved_rect;
+
+ _saved_rects[index] = *rect;
+ _next_saved_rect = (index + 1) % QUEUE_LENGTH;
+
return EnqueueDrawOp(
- (void *) &_dma_transfer, (uint32_t) rect, (uint32_t) data, 1
+ (void *) &_dma_transfer,
+ (uint32_t) &_saved_rects[index],
+ (uint32_t) data,
+ 1
);
}
int StoreImage(const RECT *rect, uint32_t *data) {
+ int index = _next_saved_rect;
+
+ _saved_rects[index] = *rect;
+ _next_saved_rect = (index + 1) % QUEUE_LENGTH;
+
return EnqueueDrawOp(
- (void *) &_dma_transfer, (uint32_t) rect, (uint32_t) data, 0
+ (void *) &_dma_transfer,
+ (uint32_t) &_saved_rects[index],
+ (uint32_t) data,
+ 0
);
}
-/*int MoveImage(const RECT *rect, int x, int y) {
- return EnqueueDrawOp((void *) &MoveImage2, (uint32_t) rect, x, y);
-}*/
-
void LoadImage2(const RECT *rect, const uint32_t *data) {
_dma_transfer(rect, (uint32_t *) data, 1);
}