From ca6f507d0a1d288595ebc6ebf0be11024d236845 Mon Sep 17 00:00:00 2001 From: "wagic.the.homebrew@gmail.com" Date: Sun, 6 Dec 2009 12:38:23 +0000 Subject: [PATCH] Erwan - putting valloc.c back in the project as some persons have problem using/finding the valloc library --- JGE/Makefile | 2 +- JGE/include/valloc.h | 33 +++++ JGE/src/JGfx.cpp | 3 +- JGE/src/valloc.c | 284 ++++++++++++++++++++++++++++++++++++++++++ projects/mtg/Makefile | 2 +- 5 files changed, 320 insertions(+), 4 deletions(-) create mode 100644 JGE/include/valloc.h create mode 100644 JGE/src/valloc.c diff --git a/JGE/Makefile b/JGE/Makefile index f2a1c8aa7..f22568070 100644 --- a/JGE/Makefile +++ b/JGE/Makefile @@ -16,7 +16,7 @@ GENERIC_OBJS = src/JApp.o src/JGBKFont.o \ src/tinyxml/tinyxmlparser.o src/tinyxml/tinyxmlerror.o \ src/Encoding.o src/JTTFont.o \ src/JMD2Model.o src/JOBJModel.o -PSP_OBJS = src/JSocket.o src/JGfx.o src/JSfx.o src/JAudio.o src/JMP3.o src/decoder_prx.o src/main.o +PSP_OBJS = src/JSocket.o src/JGfx.o src/JSfx.o src/JAudio.o src/JMP3.o src/decoder_prx.o src/main.o src/valloc.o LINUX_OBJS = src/linux/JGfx.o src/linux/JSfx.o src/Xmain.o diff --git a/JGE/include/valloc.h b/JGE/include/valloc.h new file mode 100644 index 000000000..3a7158ec3 --- /dev/null +++ b/JGE/include/valloc.h @@ -0,0 +1,33 @@ +#ifndef _VALLOC_H +#define _VALLOC_H + +#include + + +#ifdef __cplusplus +extern "C" { +#endif + +#define vrelptr vGuPointer +#define vabsptr vCPUPointer + +size_t vgetMemorySize(unsigned int width, unsigned int height, unsigned int psm); + +// Return a pointer relative to VRAM Base address useable by GU +void* vGuPointer( void* ptr ); +// Return an absolute pointer useable by CPU +void* vCPUPointer( void* ptr ); + +// Returns an absolute pointer useable by CPU +void* valloc( size_t size ); +void vfree( void* ptr ); + +size_t vmemavail(); +size_t vlargestblock(); + + +#ifdef __cplusplus +} +#endif + +#endif // _VALLOC_H diff --git a/JGE/src/JGfx.cpp b/JGE/src/JGfx.cpp index b76524255..6f438a858 100644 --- a/JGE/src/JGfx.cpp +++ b/JGE/src/JGfx.cpp @@ -18,8 +18,7 @@ #include #include #include -#include -#include +#include "../include/valloc.h" #ifdef __cplusplus extern "C" { diff --git a/JGE/src/valloc.c b/JGE/src/valloc.c new file mode 100644 index 000000000..4c602ba90 --- /dev/null +++ b/JGE/src/valloc.c @@ -0,0 +1,284 @@ +/* + * Helper for use with the PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed as 'free to use and modify as long as credited appropriately' + * + * valloc.c - Standard C library VRAM allocation routines. + * + * Copyright (c) 2006 Alexander Berl + * + */ +//#include +//#include +#include +#include +#include "valloc.h" + + +/* Use this to set the default valloc() alignment. */ +#define DEFAULT_VALIGNMENT 16 + +#ifndef ALIGN +#define ALIGN(x, align) (((x)+((align)-1))&~((align)-1)) +#endif + + +#define VRAM_SIZE 0x200000 +#define VRAM_BASE ((unsigned int)sceGeEdramGetAddr()) + +/* _vram_mem_block_header structure. */ +typedef struct _vram_mem_header { + void * ptr; + size_t size; + struct _vram_mem_header * prev; + struct _vram_mem_header * next; +} vram_mem_header_t; + + + +void * __valloc_vram_base = (void*)0; +vram_mem_header_t *__valloc_vram_head = NULL; +vram_mem_header_t *__valloc_vram_tail = NULL; + + + +size_t vgetMemorySize(unsigned int width, unsigned int height, unsigned int psm) +{ + switch (psm) + { + case GU_PSM_T4: + return (width * height) >> 1; + + case GU_PSM_T8: + return width * height; + + case GU_PSM_5650: + case GU_PSM_5551: + case GU_PSM_4444: + case GU_PSM_T16: + return 2 * width * height; + + case GU_PSM_8888: + case GU_PSM_T32: + return 4 * width * height; + + default: + return 0; + } +} + +inline void* vGuPointer( void *ptr ) +{ + return (void*)((u32)ptr & ~VRAM_BASE); +} + +inline void* vCPUPointer( void *ptr ) +{ + return (void*)((u32)ptr | VRAM_BASE); +} + +/* Find the smallest block that we can allocate AFTER, returning NULL if there + are none. */ +vram_mem_header_t * _vram_mem_fit(vram_mem_header_t *head, size_t size) +{ + vram_mem_header_t *prev_mem = head, *best_fit = NULL; + u32 prev_top, next_bot; + size_t best_size = 0; + + if (((u32)head->ptr+head->size+size)ptr+head->size); + } + + while (prev_mem != NULL) { + if (prev_mem->next != NULL) { + prev_top = (u32)prev_mem->ptr; + next_bot = prev_top - ((u32)prev_mem->next->ptr + prev_mem->next->size); + if (next_bot >= size) { + if (best_fit==NULL || next_botnext; + best_size = next_bot; + } + } + } + + prev_mem = prev_mem->next; + } + + return best_fit; +} + +void * valloc(size_t size) +{ + void *ptr = NULL; + vram_mem_header_t *new_mem, *prev_mem; + size_t mem_sz; + + mem_sz = size; + + if ((mem_sz & (DEFAULT_VALIGNMENT - 1)) != 0) + mem_sz = ALIGN(mem_sz, DEFAULT_VALIGNMENT); + + + /* If we don't have any allocated blocks, reserve the first block + and initialize __valloc_vram_tail. */ + if (__valloc_vram_head == NULL) { + if (size>VRAM_SIZE) + return ptr; + + __valloc_vram_head = (vram_mem_header_t *)malloc( sizeof(vram_mem_header_t) ); + if (__valloc_vram_head == NULL) + return ptr; + + ptr = (void *)__valloc_vram_base; + + + __valloc_vram_head->ptr = ptr; + __valloc_vram_head->size = mem_sz; + __valloc_vram_head->prev = NULL; + __valloc_vram_head->next = NULL; + + __valloc_vram_tail = __valloc_vram_head; + + return vabsptr(ptr); + } + + /* Check to see if there's free space at the bottom of the heap. + NOTE: This case is now already handled in _vram_mem_fit */ + /*if (((u32)__valloc_vram_head->ptr + __valloc_vram_head->size + mem_sz) < VRAM_SIZE) { + new_mem = (vram_mem_header_t *)malloc( sizeof(vram_mem_header_t) ); + if (new_mem == NULL) + return ptr; + ptr = (void *)((u32)__valloc_vram_head->ptr + __valloc_vram_head->size); + + new_mem->ptr = ptr; + new_mem->size = mem_sz; + new_mem->prev = NULL; + new_mem->next = __valloc_vram_head; + new_mem->next->prev = new_mem; + __valloc_vram_head = new_mem; + + return ptr; + }*/ + + /* See if we can allocate the block anywhere. */ + prev_mem = _vram_mem_fit(__valloc_vram_head, mem_sz); + if (prev_mem != NULL) { + new_mem = (vram_mem_header_t *)malloc( sizeof(vram_mem_header_t) ); + if (new_mem == NULL) + return ptr; + ptr = (void *)((u32)prev_mem->ptr + prev_mem->size); + + new_mem->ptr = ptr; + new_mem->size = mem_sz; + new_mem->prev = prev_mem->prev; + if (new_mem->prev!=NULL) + new_mem->prev->next = new_mem; + new_mem->next = prev_mem; + prev_mem->prev = new_mem; + if (prev_mem == __valloc_vram_head) + __valloc_vram_head = new_mem; + + return vabsptr(ptr); + } + + /* Now we have a problem: There's no room at the bottom and also no room in between. + So either we do compact the memory (time critical because memcopies needed) or we + just return NULL so the application has to handle this case itself. + For now we'll just return NULL + */ + + return ptr; +} + + + +void vfree(void *ptr) +{ + vram_mem_header_t *cur; + + if (!ptr) + return; + + if (!__valloc_vram_head) + return; + + ptr = vrelptr(ptr); + + /* Freeing the head pointer is a special case. */ + if (ptr == __valloc_vram_head->ptr) { + + cur = __valloc_vram_head->next; + free(__valloc_vram_head); + + __valloc_vram_head = cur; + + if (__valloc_vram_head != NULL) { + __valloc_vram_head->prev = NULL; + } else { + __valloc_vram_tail = NULL; + } + + return; + } + + cur = __valloc_vram_head; + while (ptr != cur->ptr) { + /* ptr isn't in our list */ + if (cur->next == NULL) { + return; + } + cur = cur->next; + } + + /* Deallocate the block. */ + if (cur->next != NULL) { + cur->next->prev = cur->prev; + } else { + /* If this block was the last one in the list, shrink the heap. */ + __valloc_vram_tail = cur->prev; + } + + cur->prev->next = cur->next; + free( cur ); + +} + + +size_t vmemavail() +{ + if (__valloc_vram_head==NULL) + return VRAM_SIZE; + + vram_mem_header_t *cur; + size_t size = VRAM_SIZE - ((u32)__valloc_vram_head->ptr + __valloc_vram_head->size); + + cur = __valloc_vram_head; + while (cur->next!=NULL) { + size += (u32)cur->ptr - ((u32)cur->next->ptr + cur->next->size); + cur = cur->next; + } + + return size; +} + + +size_t vlargestblock() +{ + if (__valloc_vram_head==NULL) + return VRAM_SIZE; + + vram_mem_header_t *cur; + size_t size = VRAM_SIZE - ((u32)__valloc_vram_head->ptr + __valloc_vram_head->size); + size_t new_size; + + cur = __valloc_vram_head; + while (cur->next!=NULL) { + new_size = (u32)cur->ptr - ((u32)cur->next->ptr + cur->next->size); + if (new_size>size) size = new_size; + cur = cur->next; + } + + return size; +} + diff --git a/projects/mtg/Makefile b/projects/mtg/Makefile index 675db5e1b..759d63ee0 100644 --- a/projects/mtg/Makefile +++ b/projects/mtg/Makefile @@ -27,7 +27,7 @@ DEFAULT_RULE = 3xx TARGET_ARCHITECTURE = psp PSP_FW_VERSION=371 BUILD_PRX = 1 -LIBS = -ljge300 -lhgetools -lfreetype -ljpeg -lgif -lpng -lz -lm -lmikmod -lpsppower -lpspmpeg -lpspaudiocodec -lpspaudiolib -lpspaudio -lpspmp3 -lpspgum -lpspgu -lpsprtc -lstdc++ -lpspfpu -lpspvalloc +LIBS = -ljge300 -lhgetools -lfreetype -ljpeg -lgif -lpng -lz -lm -lmikmod -lpsppower -lpspmpeg -lpspaudiocodec -lpspaudiolib -lpspaudio -lpspmp3 -lpspgum -lpspgu -lpsprtc -lstdc++ -lpspfpu EXTRA_TARGETS = EBOOT.PBP PSP_EBOOT_TITLE = Wagic, the Homebrew?!