1 #include "include/texcache.h"
2 #include "include/ioman.h"
3 #include "include/gui.h"
4 #include "include/util.h"
6 // io call to handle the loading of covers
7 #define IO_CACHE_LOAD_ART 3
13 // only for comparison if the deferred action is still valid
16 } load_image_request_t
;
18 // Io handled action...
19 static void cacheLoadImage(void* data
) {
20 load_image_request_t
* req
= data
;
23 if (!req
|| !req
->entry
|| !req
->cache
)
26 item_list_t
* handler
= req
->list
;
30 // the cache entry was already reused!
31 if (req
->cacheUID
!= req
->entry
->UID
)
34 // seems okay. we can proceed
35 GSTEXTURE
* texture
= &req
->entry
->texture
;
36 if(texture
->Mem
!= NULL
) {
42 texture
->VramClut
= 0;
45 if (handler
->itemGetImage(req
->cache
->prefix
, req
->cache
->isPrefixRelative
, req
->value
, req
->cache
->suffix
, texture
, GS_PSM_CT24
) < 0)
46 req
->entry
->lastUsed
= 0;
48 req
->entry
->lastUsed
= guiFrameId
;
50 req
->entry
->qr
= NULL
;
56 ioRegisterHandler(IO_CACHE_LOAD_ART
, &cacheLoadImage
);
60 // nothing to do... others have to destroy the cache via cacheDestroyCache
63 static void cacheClearItem(cache_entry_t
* item
, int freeTxt
) {
64 if (freeTxt
&& item
->texture
.Mem
)
65 free(item
->texture
.Mem
);
67 memset(item
, 0, sizeof(cache_entry_t
));
68 item
->texture
.Mem
= NULL
;
69 item
->texture
.Vram
= 0;
70 item
->texture
.Clut
= 0;
71 item
->texture
.VramClut
= 0;
77 image_cache_t
* cacheInitCache(int userId
, char* prefix
, int isPrefixRelative
, char* suffix
, int count
) {
78 image_cache_t
* cache
= (image_cache_t
*) malloc(sizeof(image_cache_t
));
79 cache
->userId
= userId
;
81 int length
= strlen(prefix
) + 1;
82 cache
->prefix
= (char*) malloc(length
* sizeof(char));
83 memcpy(cache
->prefix
, prefix
, length
);
84 cache
->isPrefixRelative
= isPrefixRelative
;
85 length
= strlen(suffix
) + 1;
86 cache
->suffix
= (char*) malloc(length
* sizeof(char));
87 memcpy(cache
->suffix
, suffix
, length
);
89 cache
->content
= (cache_entry_t
*) malloc(count
* sizeof(cache_entry_t
));
92 for (i
= 0; i
< count
; ++i
)
93 cacheClearItem(&cache
->content
[i
], 0);
98 void cacheDestroyCache(image_cache_t
* cache
) {
100 for (i
= 0; i
< cache
->count
; ++i
) {
101 cacheClearItem(&cache
->content
[i
], 1);
106 free(cache
->content
);
110 GSTEXTURE
* cacheGetTexture(image_cache_t
* cache
, item_list_t
* list
, int* cacheId
, int* UID
, char* value
) {
111 if (*cacheId
== -2) {
113 } else if (*cacheId
!= -1) {
114 cache_entry_t
* entry
= &cache
->content
[*cacheId
];
115 if (entry
->UID
== *UID
) {
118 else if (entry
->lastUsed
== 0) {
122 entry
->lastUsed
= guiFrameId
;
123 return &entry
->texture
;
130 // under the cache pre-delay (to avoid filling cache while moving around)
131 if (guiInactiveFrames
< list
->delay
)
134 cache_entry_t
*currEntry
, *oldestEntry
= NULL
;
135 int i
, rtime
= guiFrameId
;
137 for (i
= 0; i
< cache
->count
; i
++) {
138 currEntry
= &cache
->content
[i
];
139 if ((!currEntry
->qr
) && (currEntry
->lastUsed
< rtime
)) {
140 oldestEntry
= currEntry
;
141 rtime
= currEntry
->lastUsed
;
147 load_image_request_t
* req
= malloc(sizeof(load_image_request_t
));
149 req
->entry
= oldestEntry
;
152 req
->cacheUID
= cache
->nextUID
;
154 cacheClearItem(oldestEntry
, 1);
155 oldestEntry
->qr
= req
;
156 oldestEntry
->UID
= cache
->nextUID
;
158 *UID
= cache
->nextUID
++;
160 ioPutRequest(IO_CACHE_LOAD_ART
, req
);