- Main Page
- Classes
- Files

- File List
- File Members

# flMemory.c

Go to the documentation of this file.

    00001 #include "flGlobal.h"
    00002 #if FL_MEMORY != 0
    00003 #include <malloc.h>
    00004 #include <stdio.h>
    00005 #include <string.h>
    00006 #include <pspkernel.h>
    00007
    00008 #if FL_INCLUDE_ALL_C == 0
    00009 #include "flMemory.h"
    00010 #include "flFile.h"
    00011
    00012 #if FL_DEBUG
    00013 #include "flDebug.h"
    00014 #endif
    00015 #endif
    00016
    00017 #if FL_MEMORY_PAGE
    00018 unsigned int memPageID = 0; // Current page ID.
    00019 #endif
    00020
    00021 #if FL_MEMORY_ERRORBYTES
    00022 MemoryTree* memErrorTree = NULL;
    00023 #endif
    00024
    00025 bool memInitialized = false;
    00026 bool memScratchpadUsed = false;
    00027
    00028 void memInit() {
    00029      #if ((FL_MEMORY_PAGE) || (FL_MEMORY_SCRATCHPAD))
    00030      FILE* tempFile;
    00031      #endif
    00032
    00033      #if FL_MEMORY_PAGE
    00034      tempFile = fopen(MEMORY_PAGE_PATH, "w");
    00035      if(!tempFile) {
    00036           #if FL_DEBUG_ERROR
    00037           debugError("Couldn't create blank memory page file at \"%s\".", MEMORY_PAGE_PATH);
    00038           #endif
    00039           return;
    00040      }
    00041      #if FL_DEBUG_STATUS
    00042      debugStatusLog("Clearing page file.");
    00043      #endif
    00044      fclose(tempFile);
    00045      #endif
    00046
    00047      #if FL_MEMORY_SCRATCHPAD
    00048      bool tempClear = true; u32 i;
    00049      for(i = MEMORY_SCRATCHPAD_BASE; i < (MEMORY_SCRATCHPAD_BASE + MEMORY_SCRATCHPAD_SIZE); i++) {
    00050           if(*((u8*)i)) {
    00051                tempClear = false;
    00052                break;
    00053           }
    00054      }
    00055      if(!tempClear) {
    00056           #if FL_DEBUG_STATUS
    00057           debugStatusLog("Dumping scratchpad.");
    00058           #endif
    00059           u8 tempBuffer[16384];
    00060           memCopy(tempBuffer, (void*)MEMORY_SCRATCHPAD_BASE, MEMORY_SCRATCHPAD_SIZE);
    00061           tempFile = fopen("./scratchpad.dump", "w");
    00062           if(tempFile) {
    00063                fwrite(tempBuffer, 512, 32, tempFile);
    00064                fclose(tempFile);
    00065           }
    00066      }
    00067      #endif
    00068
    00069      memInitialized = true;
    00070 }
    00071
    00072 void memTerm() {
    00073      #if FL_MEMORY_PAGE
    00074      #if FL_DEBUG_STATUS
    00075      debugStatusLog("Deleting page file.");
    00076      #endif
    00077      fileDelete(FL_MEMORY_PAGE_PATH);
    00078      #endif
    00079
    00080      #if FL_MEMORY_SCRATCHPAD
    00081      #if FL_DEBUG_STATUS
    00082      debugStatusLog("Restoring scratchpad.");
    00083      #endif
    00084      u8 tempBuffer[16384];
    00085      FILE* tempFile = fopen("./scratchpad.dump", "r");
    00086      if(tempFile) {
    00087           fread(tempBuffer, 4, 4096, tempFile);
    00088           fclose(tempFile);
    00089           fileDelete("./scratchpad.dump");
    00090           memCopy((void*)MEMORY_SCRATCHPAD_BASE, tempBuffer, MEMORY_SCRATCHPAD_SIZE);
    00091      } else
    00092           memClear((void*)MEMORY_SCRATCHPAD_BASE, MEMORY_SCRATCHPAD_SIZE);
    00093      #endif
    00094
    00095      memInitialized = false;
    00096      #if FL_DEBUG_STATUS
    00097      debugStatusLog("Memory terminated.");
    00098      #endif
    00099 }
    00100
    00101 u32 memFreeSpace(u32 inAccuracy) {
    00102      if(!inAccuracy)
    00103           inAccuracy = 1;
    00104
    00105      u32 tempBlockSize = (MEMORY_USER_SIZE >> 1);
    00106      u32 tempFreeSpace = 0;
    00107      void* tempPointers[8192];
    00108      u32 tempPtr = 0;
    00109      while((tempPtr < 8192) && (tempBlockSize > inAccuracy)) {
    00110           tempPointers[tempPtr] = malloc(tempBlockSize);
    00111           while(tempPointers[tempPtr]) {
    00112                tempPtr++;
    00113                tempFreeSpace += tempBlockSize;
    00114                tempPointers[tempPtr] = malloc(tempBlockSize);
    00115           }
    00116           tempBlockSize >>= 1;
    00117      }
    00118
    00119      tempPtr = 0;
    00120      while(tempPointers[tempPtr]) {
    00121           free(tempPointers[tempPtr]);
    00122           tempPtr++;
    00123      }
    00124
    00125      return tempFreeSpace;
    00126 }
    00127
    00128 u32 memFreeSpaceTotal() {
    00129      u32 tempTotal = (memScratchpadUsed ? 0 : 16384);
    00130      tempTotal += memFreeSpace(1);
    00131      #if FL_MEMORY_VMEM
    00132      tempTotal += vmemFreeSpace();
    00133      #endif
    00134      return tempTotal;
    00135 }
    00136
    00137 char* memString(u32 inBytes, bool inBinary) {
    00138       u32 i = 0;
    00139       float tempBytes = inBytes;
    00140
    00141       if(inBinary) {
    00142            while(inBytes >> 10) {
    00143                 i++;
    00144                 tempBytes /= 1024.0f;
    00145                 inBytes >>= 10;
    00146            }
    00147       } else {
    00148            while(inBytes / 1000) {
    00149                 i++;
    00150                 tempBytes /= 1000.0f;
    00151                 inBytes /= 1000;
    00152            }
    00153       }
    00154
    00155       char* tempOut = memAlloc(16);
    00156       sprintf(tempOut, "%4.2f ", tempBytes);
    00157
    00158       if(i & 1) {
    00159            if(i == 1)
    00160                 strcat(tempOut, "K");
    00161            else
    00162                 strcat(tempOut, "G");
    00163       } else
    00164            strcat(tempOut, "M");
    00165
    00166       if(i && inBinary)
    00167            strcat(tempOut, "i");
    00168
    00169       strcat(tempOut, "B");
    00170
    00171       return tempOut;
    00172 }
    00173
    00174 #if FL_DEBUG_CALLEDFROM
    00175 void memSetByteFrom(void* inPtr, int inVal, unsigned int inSize, const char* inFile, const char* inFunc, int inLine) {
    00176 #else
    00177 void memSetByte(void* inPtr, int inVal, unsigned int inSize) {
    00178 #endif
    00179      if(!inPtr || !inSize) {
    00180           #if FL_DEBUG_WARNING
    00181           char tempString[256];
    00182           tempString[0] = 0;
    00183           if(!inPtr)
    00184                strcat(tempString, "memSetByte failed, pointer is NULL.\n");
    00185           if(!inSize)
    00186                strcat(tempString, "Trying to memSetByte 0 bytes of memory.\n");
    00187
    00188           #if FL_DEBUG_CALLEDFROM
    00189           debugWarningFrom(inFile, inFunc, inLine, tempString);
    00190           #else
    00191           debugWarning(tempString);
    00192           #endif
    00193           #endif
    00194           return;
    00195      }
    00196      if(!memBlockValid(inPtr, inSize)) {
    00197           #if FL_DEBUG_WARNING
    00198           #if FL_DEBUG_CALLEDFROM
    00199           debugWarningFrom(inFile, inFunc, inLine, "(memSetByte) Trying to memSetByte an invalid memory block.");
    00200           #else
    00201           debugWarning("Trying to memSetByte an invalid memory block.");
    00202           #endif
    00203           #endif
    00204           return;
    00205      }
    00206
    00207      inSize += (u32)inPtr;
    00208      if((inSize & 3) || ((u32)inPtr & 3)) {
    00209           if((inSize & 1) || ((u32)inPtr & 1)) {
    00210                u8 tempVal = ((inVal & 0xFF) ^ (inVal < 0 ? 0x80 : 0x00));
    00211                u8* tempPtr = (u8*)inPtr;
    00212                while((u32)tempPtr < inSize)
    00213                     *(tempPtr++) = tempVal;
    00214           } else {
    00215                u16 tempVal = ((inVal & 0xFF) ^ (inVal < 0 ? 0x80 : 0x00));
    00216                tempVal |= (tempVal << 8);
    00217                u16* tempPtr = (u16*)inPtr;
    00218                while((u32)tempPtr < inSize)
    00219                     *(tempPtr++) = tempVal;
    00220           }
    00221      } else {
    00222           u32 tempVal = ((inVal & 0xFF) ^ (inVal < 0 ? 0x80 : 0x00));
    00223           tempVal |= (tempVal << 8);
    00224           tempVal |= (tempVal << 16);
    00225           u32* tempPtr = (u32*)inPtr;
    00226           while((u32)tempPtr < inSize)
    00227                *(tempPtr++) = tempVal;
    00228      }
    00229
    00230      #if FL_MEMORY_ERRORBYTES
    00231      #if FL_DEBUG_CALLEDFROM
    00232      memtErrorBytesCheckFrom(&memErrorTree, inFile, inFunc, inLine);
    00233      #else
    00234      memtErrorBytesCheck(&memErrorTree);
    00235      #endif
    00236      #endif
    00237 }
    00238
    00239 #if FL_DEBUG_CALLEDFROM
    00240 void memSetShortFrom(void* inPtr, int inVal, unsigned int inSize, const char* inFile, const char* inFunc, int inLine) {
    00241 #else
    00242 void memSetShort(void* inPtr, int inVal, unsigned int inSize) {
    00243 #endif
    00244      if(!inPtr || !inSize) {
    00245           #if FL_DEBUG_WARNING
    00246           char tempString[256];
    00247           tempString[0] = 0;
    00248           if(!inPtr)
    00249                strcat(tempString, "memSetShort failed, pointer is NULL.\n");
    00250           if(!inSize)
    00251                strcat(tempString, "Trying to memSetShort 0 bytes of memory.\n");
    00252
    00253           #if FL_DEBUG_CALLEDFROM
    00254           debugWarningFrom(inFile, inFunc, inLine, tempString);
    00255           #else
    00256           debugWarning(tempString);
    00257           #endif
    00258           #endif
    00259           return;
    00260      }
    00261      if(!memBlockValid(inPtr, inSize)) {
    00262           #if FL_DEBUG_WARNING
    00263           #if FL_DEBUG_CALLEDFROM
    00264           debugWarningFrom(inFile, inFunc, inLine, "(memSetShort) Trying to memSetShort an invalid memory block.");
    00265           #else
    00266           debugWarning("Trying to memSetShort an invalid memory block.");
    00267           #endif
    00268           #endif
    00269           return;
    00270      }
    00271
    00272      inSize += (u32)inPtr;
    00273      if((inSize & 3) || ((u32)inPtr & 3)) {
    00274           if((inSize & 1) || ((u32)inPtr & 1)) {
    00275                u16 tempVal = ((inVal & 0xFF) ^ (inVal < 0 ? 0x8000 : 0x0000));
    00276                u8* tempPtr = (u8*)inPtr;
    00277                if(inSize & 1)
    00278                     tempVal = ((tempVal & 0x00FF) << 8) | ((tempVal & 0xFF00) >> 8);
    00279                while((u32)tempPtr < inSize) {
    00280                     *tempPtr = ((u32)tempPtr ? (tempVal & 0x00FF) : ((tempVal & 0xFF00) >> 8));
    00281                     tempPtr++;
    00282                }
    00283           } else {
    00284                u16 tempVal = ((inVal & 0xFF) ^ (inVal < 0 ? 0x8000 : 0x0000));
    00285                u16* tempPtr = (u16*)inPtr;
    00286                while((u32)tempPtr < inSize)
    00287                     *(tempPtr++) = tempVal;
    00288           }
    00289      } else {
    00290           u32 tempVal = ((inVal & 0xFF) ^ (inVal < 0 ? 0x8000 : 0x0000));
    00291           tempVal |= (tempVal << 16);
    00292           u32* tempPtr = (u32*)inPtr;
    00293           while((u32)tempPtr < inSize)
    00294                *(tempPtr++) = tempVal;
    00295      }
    00296
    00297      #if FL_MEMORY_ERRORBYTES
    00298      #if FL_DEBUG_CALLEDFROM
    00299      memtErrorBytesCheckFrom(&memErrorTree, inFile, inFunc, inLine);
    00300      #else
    00301      memtErrorBytesCheck(&memErrorTree);
    00302      #endif
    00303      #endif
    00304 }
    00305
    00306 #if FL_DEBUG_CALLEDFROM
    00307 void memClearFrom(void* inPtr, unsigned int inSize, const char* inFile, const char* inFunc, int inLine) {
    00308 #else
    00309 void memClear(void* inPtr, unsigned int inSize) {
    00310 #endif
    00311      if(!inPtr || !inSize) {
    00312           #if FL_DEBUG_WARNING
    00313           char tempString[256];
    00314           tempString[0] = 0;
    00315           if(!inPtr)
    00316                strcat(tempString, "memClear failed, pointer is NULL.\n");
    00317           if(!inSize)
    00318                strcat(tempString, "Trying to memClear 0 bytes of memory.\n");
    00319
    00320           #if FL_DEBUG_CALLEDFROM
    00321           debugWarningFrom(inFile, inFunc, inLine, tempString);
    00322           #else
    00323           debugWarning(tempString);
    00324           #endif
    00325           #endif
    00326           return;
    00327      }
    00328      if(!memBlockValid(inPtr, inSize)) {
    00329           #if FL_DEBUG_WARNING
    00330           #if FL_DEBUG_CALLEDFROM
    00331           debugWarningFrom(inFile, inFunc, inLine, "(memClear) Trying to memClear an invalid memory block.");
    00332           #else
    00333           debugWarning("Trying to memClear an invalid memory block.");
    00334           #endif
    00335           #endif
    00336           return;
    00337      }
    00338
    00339      inSize += (u32)inPtr;
    00340      if((inSize & 3) || ((u32)inPtr & 3)) {
    00341           if((inSize & 3) || ((u32)inPtr & 3)) {
    00342                u8* tempPtr = (u8*)inPtr;
    00343                while((u32)tempPtr < inSize)
    00344                     *(tempPtr++) = 0x00;
    00345           } else {
    00346                u16* tempPtr = (u16*)inPtr;
    00347                while((u32)tempPtr < inSize)
    00348                     *(tempPtr++) = 0x0000;
    00349           }
    00350      } else {
    00351           u32* tempPtr = (u32*)inPtr;
    00352           while((u32)tempPtr < inSize)
    00353                *(tempPtr++) = 0x00000000;
    00354      }
    00355
    00356      #if FL_MEMORY_ERRORBYTES
    00357      #if FL_DEBUG_CALLEDFROM
    00358      memtErrorBytesCheckFrom(&memErrorTree, inFile, inFunc, inLine);
    00359      #else
    00360      memtErrorBytesCheck(&memErrorTree);
    00361      #endif
    00362      #endif
    00363 }
    00364
    00365 #if FL_DEBUG_CALLEDFROM
    00366 void memCopyFrom(void* inDest, void* inSrc, unsigned int inSize, const char* inFile, const char* inFunc, int inLine) {
    00367 #else
    00368 void memCopy(void* inDest, void* inSrc, unsigned int inSize) {
    00369 #endif
    00370      if(!inDest || !inSrc || !inSize) {
    00371           #if FL_DEBUG_WARNING
    00372           char tempString[256];
    00373           tempString[0] = 0;
    00374           if(!inDest)
    00375                strcat(tempString, "Trying to memCopy to a NULL destination.\n");
    00376           if(!inSrc)
    00377                strcat(tempString, "Trying to memCopy from a NULL source.\n");
    00378           if(!inSize)
    00379                strcat(tempString, "Trying to memCopy 0 bytes of memory.\n");
    00380
    00381           #if FL_DEBUG_CALLEDFROM
    00382           debugWarningFrom(inFile, inFunc, inLine, tempString);
    00383           #else
    00384           debugWarning(tempString);
    00385           #endif
    00386           #endif
    00387           return;
    00388      }
    00389
    00390      if((((u32)inDest + inSize) < (u32)inDest) || (((u32)inSrc + inSize) < (u32)inSrc)) {
    00391           #if FL_DEBUG_WARNING
    00392           #if FL_DEBUG_CALLEDFROM
    00393           debugWarningFrom(inFile, inFunc, inLine, "(memCopy) Unsigned integer overflow while copying data.");
    00394           #else
    00395           debugWarning("Unsigned integer overflow while copying data.");
    00396           #endif
    00397           #endif
    00398           return;
    00399      }
    00400
    00401      // Handle overlaps
    00402      if((((u32)inSrc + inSize) > (u32)inDest) && (((u32)inSrc + inSize) <= ((u32)inDest + inSize))) {
    00403           u32 tempSize = (((u32)inSrc + inSize) - (u32)inDest);
    00404           void* tempBuffer = memQalloc(tempSize);
    00405           memCopy(tempBuffer, (void*)((u32)inSrc + (inSize - tempSize)), tempSize);
    00406           memCopy((void*)((u32)inDest + tempSize), inSrc, (inSize - tempSize));
    00407           memCopy(inDest, tempBuffer, tempSize);
    00408           memFree(tempBuffer);
    00409           return;
    00410      }
    00411
    00412      if(!memBlockValid(inSrc, inSize) || !memBlockValid(inDest, inSize)) {
    00413           #if FL_DEBUG_WARNING
    00414           #if FL_DEBUG_CALLEDFROM
    00415           debugWarningFrom(inFile, inFunc, inLine, "(memCopy) Trying to memCopy to/from an invalid memory block (0x%08X-0x%08X <- 0x%08X-0x%08X).", (unsigned int)inDest, ((unsigned int)inDest + inSize), (unsigned int)inSrc, ((unsigned int)inSrc + inSize));
    00416           #else
    00417           debugWarning("Trying to memCopy to/from an invalid memory block (0x%08X-0x%08X <- 0x%08X-0x%08X).", (unsigned int)inDest, ((unsigned int)inDest + inSize), (unsigned int)inSrc, ((unsigned int)inSrc + inSize));
    00418           #endif
    00419           #endif
    00420           return;
    00421      }
    00422
    00423      inSize += (u32)inDest;
    00424      if((inSize & 3) || ((u32)inDest & 3) || ((u32)inSrc & 3)) {
    00425           if((inSize & 1) || ((u32)inDest & 1) || ((u32)inSrc & 1)) {
    00426                u8* tempDest = (u8*)inDest;
    00427                u8* tempSrc = (u8*)inSrc;
    00428                while((u32)tempDest < inSize)
    00429                     *(tempDest++) = *(tempSrc++);
    00430           } else {
    00431                u16* tempDest = (u16*)inDest;
    00432                u16* tempSrc = (u16*)inSrc;
    00433                while((u32)tempDest < inSize)
    00434                     *(tempDest++) = *(tempSrc++);
    00435           }
    00436      } else {
    00437           u32* tempDest = (u32*)inDest;
    00438           u32* tempSrc = (u32*)inSrc;
    00439           while((u32)tempDest < inSize)
    00440                *(tempDest++) = *(tempSrc++);
    00441      }
    00442
    00443      #if FL_MEMORY_ERRORBYTES
    00444      #if FL_DEBUG_CALLEDFROM
    00445      memtErrorBytesCheckFrom(&memErrorTree, inFile, inFunc, inLine);
    00446      #else
    00447      memtErrorBytesCheck(&memErrorTree);
    00448      #endif
    00449      #endif
    00450 }
    00451
    00452 #if FL_DEBUG_CALLEDFROM
    00453 int memCompareFrom(void* inSrc0, void* inSrc1, unsigned int inSize, const char* inFile, const char* inFunc, int inLine) {
    00454 #else
    00455 int memCompare(void* inSrc0, void* inSrc1, unsigned int inSize) {
    00456 #endif
    00457      if(!inSrc0 || !inSrc1 || !inSize) {
    00458           #if FL_DEBUG_WARNING
    00459           char tempString[256];
    00460           tempString[0] = 0;
    00461           if(!inSrc0 || !inSrc1)
    00462                strcat(tempString, "Trying to memCompare to a NULL region.\n");
    00463           if(!inSize)
    00464                strcat(tempString, "Trying to memCompare 0 bytes of memory.\n");
    00465           #if FL_DEBUG_CALLEDFROM
    00466           debugWarningFrom(inFile, inFunc, inLine, tempString);
    00467           #else
    00468           debugWarning(tempString);
    00469           #endif
    00470           #endif
    00471           return -1;
    00472      }
    00473
    00474      if((((u32)inSrc0 + inSize) < (u32)inSrc1) || (((u32)inSrc0 + inSize) < (u32)inSrc1)) {
    00475           #if FL_DEBUG_WARNING
    00476           #if FL_DEBUG_CALLEDFROM
    00477           debugWarningFrom(inFile, inFunc, inLine, "(memCompare) Unsigned integer overflow while comparing data.");
    00478           #else
    00479           debugWarning("Unsigned integer overflow while comparing data.");
    00480           #endif
    00481           #endif
    00482           return -1;
    00483      }
    00484
    00485      if(!memBlockValid(inSrc0, inSize) || !memBlockValid(inSrc1, inSize)) {
    00486           #if FL_DEBUG_WARNING
    00487           #if FL_DEBUG_CALLEDFROM
    00488           debugWarningFrom(inFile, inFunc, inLine, "(memCompare) Trying to memCompare to/from an invalid memory block (0x%08X-0x%08X <- 0x%08X-0x%08X).", (unsigned int)inSrc0, ((unsigned int)inSrc0 + inSize), (unsigned int)inSrc1, ((unsigned int)inSrc1 + inSize));
    00489           #else
    00490           debugWarning("Trying to memCompare to/from an invalid memory block (0x%08X-0x%08X <- 0x%08X-0x%08X).", (unsigned int)inSrc0, ((unsigned int)inSrc0 + inSize), (unsigned int)inSrc1, ((unsigned int)inSrc1 + inSize));
    00491           #endif
    00492           #endif
    00493           return -1;
    00494      }
    00495
    00496      int tempOut = memcmp(inSrc0, inSrc1, inSize);
    00497
    00498      #if FL_MEMORY_ERRORBYTES
    00499      #if FL_DEBUG_CALLEDFROM
    00500      memtErrorBytesCheckFrom(&memErrorTree, inFile, inFunc, inLine);
    00501      #else
    00502      memtErrorBytesCheck(&memErrorTree);
    00503      #endif
    00504      #endif
    00505
    00506      return tempOut;
    00507 }
    00508
    00509
    00510 #if FL_DEBUG_CALLEDFROM
    00511 void* memAllocFrom(int inSize, const char* inFile, const char* inFunc, int inLine) {
    00512      return memAlignFrom(FL_MEMORY_ALIGNMENT_DEFAULT, inSize, inFile, inFunc, inLine);
    00513 }
    00514 #else
    00515 void* memAlloc(int inSize) {
    00516      return memAlign(FL_MEMORY_ALIGNMENT_DEFAULT, inSize);
    00517 }
    00518 #endif
    00519
    00520 #if FL_DEBUG_CALLEDFROM
    00521 void* memQallocFrom(int inSize, const char* inFile, const char* inFunc, int inLine) {
    00522 #else
    00523 void* memQalloc(int inSize) {
    00524 #endif
    00525      #if FL_MEMORY_SCRATCHPAD
    00526      if(memInitialized) {
    00527           if((inSize <= MEMORY_SCRATCHPAD_SIZE) && !memScratchpadUsed) {
    00528                memScratchpadUsed = true;
    00529                return (void*)MEMORY_SCRATCHPAD_BASE;
    00530           }
    00531      }
    00532      #endif
    00533
    00534      void* tempOut;
    00535
    00536      #if FL_MEMORY_VMEM
    00537      if(vmemInitialized) {
    00538           tempOut = vmemAlloc(inSize);
    00539           if(tempOut)
    00540                return tempOut;
    00541      }
    00542      #endif
    00543
    00544      tempOut = memAlloc(inSize);
    00545
    00546      #if FL_DEBUG_WARNING
    00547      if(!tempOut) {
    00548           #if FL_DEBUG_CALLEDFROM
    00549           debugWarningFrom(inFile, inFunc, inLine, "Error allocating memory using memQalloc.\nMemory full/fragmented.");
    00550           #else
    00551           debugWarningFrom("Error allocating memory using memQalloc.\nMemory full/fragmented.");
    00552           #endif
    00553      }
    00554      #endif
    00555
    00556      return tempOut;
    00557 }
    00558
    00559 #if FL_DEBUG_CALLEDFROM
    00560 void* memCallocFrom(int inSize0, int inSize1, const char* inFile, const char* inFunc, int inLine) {
    00561      void* tempOut = memAllocFrom((inSize0 * inSize1), inFile, inFunc, inLine);
    00562 #else
    00563 void* memCalloc(int inSize0, int inSize1) {
    00564      void* tempOut = memAlloc(inSize0 * inSize1);
    00565 #endif
    00566      if(!tempOut)
    00567           return NULL;
    00568      #if FL_DEBUG_CALLEDFROM
    00569      memClearFrom(tempOut, (inSize0 * inSize1), inFile, inFunc, inLine);
    00570      #else
    00571      memClear(tempOut, (inSize0 * inSize1));
    00572      #endif
    00573      return tempOut;
    00574 }
    00575
    00576 #if FL_DEBUG_CALLEDFROM
    00577 void* memAllocUncachedFrom(int inSize, const char* inFile, const char* inFunc, int inLine) {
    00578 #else
    00579 void* memAllocUncached(int inSize) {
    00580 #endif
    00581      void* tempOut = memAlign(max(64, FL_MEMORY_ALIGNMENT_DEFAULT), inSize);
    00582      if(!tempOut) {
    00583           #if FL_DEBUG_WARNING
    00584           #if FL_DEBUG_CALLEDFROM
    00585           debugWarningFrom(inFile, inFunc, inLine, "(memAllocUncached) Error allocating uncached memory, memory is probably full/fragmented.");
    00586           #else
    00587           debugWarning("Error allocating uncached memory, memory is probably full/fragmented.");
    00588           #endif
    00589           #endif
    00590           return NULL;
    00591      }
    00592      #if FL_MEMORY_ERRORBYTES
    00593      if((inSize + (max(64, FL_MEMORY_ALIGNMENT_DEFAULT) << 1)) >= 16384)
    00594           sceKernelDcacheWritebackInvalidateAll();
    00595      else
    00596           sceKernelDcacheWritebackInvalidateRange((void*)((unsigned int)tempOut - max(64, FL_MEMORY_ALIGNMENT_DEFAULT)), (inSize + (max(64, FL_MEMORY_ALIGNMENT_DEFAULT) << 1)));
    00597      #else
    00598      if(inSize >= 16384)
    00599           sceKernelDcacheWritebackInvalidateAll();
    00600      else
    00601           sceKernelDcacheWritebackInvalidateRange(tempOut, inSize);
    00602      #endif
    00603      tempOut = memUncachedPtr(tempOut);
    00604      return tempOut;
    00605 }
    00606
    00607 #if FL_DEBUG_CALLEDFROM
    00608 void* memReallocFrom(void* inData, int inSize, const char* inFile, const char* inFunc, int inLine) {
    00609 #else
    00610 void* memRealloc(void* inData, int inSize) {
    00611 #endif
    00612      #if FL_MEMORY_VMEM
    00613      if(vmemPointer(inData))
    00614           return vmemRealloc(inData, inSize);
    00615      #endif
    00616      if(!inSize) {
    00617           #if FL_DEBUG_WARNING
    00618           #if FL_DEBUG_CALLEDFROM
    00619           debugWarningFrom(inFile, inFunc, inLine, "(memRealloc) Trying to re-allocate to 0 bytes.");
    00620           #else
    00621           debugWarning("Trying to re-allocate to 0 bytes.");
    00622           #endif
    00623           #endif
    00624           return NULL;
    00625      }
    00626      #if FL_MEMORY_ERRORBYTES
    00627      if(!memErrorBytesCheck(inData)) {
    00628           #if FL_DEBUG_ERROR
    00629           #if FL_DEBUG_CALLEDFROM
    00630           debugErrorFrom(inFile, inFunc, inLine, "Error re-allocating memory, original data was corrupt.");
    00631           #else
    00632           debugError("Error re-allocating memory, original data was corrupt.");
    00633           #endif
    00634           #endif
    00635           return NULL;
    00636      }
    00637      u32* tempData = (u32*)((unsigned int)inData - 16);
    00638      u32 tempBoundry = tempData[0];
    00639      while(inSize & (tempBoundry - 1))
    00640           inSize++;
    00641      inData = (void*)((unsigned int)inData - tempBoundry);
    00642      void* tempOut = realloc(inData, (inSize + (tempBoundry << 1)));
    00643      if(!tempOut) {
    00644           #if FL_DEBUG_WARNING
    00645           #if FL_DEBUG_CALLEDFROM
    00646           debugWarningFrom(inFile, inFunc, inLine, "(memRealloc) Error re-allocating memory, memory is probably full/fragmented.");
    00647           #else
    00648           debugWarning("Error re-allocating memory, memory is probably full/fragmented.");
    00649           #endif
    00650           #endif
    00651           return NULL;
    00652      }
    00653
    00654      #if FL_DEBUG_CALLEDFROM
    00655      memtAddFrom(&memErrorTree, tempOut, inSize, tempBoundry, inFile, inFunc, inLine);
    00656      #else
    00657      memtAdd(&memErrorTree, tempOut, inSize, tempBoundry);
    00658      #endif
    00659
    00660      tempOut = (void*)((unsigned int)tempOut + tempBoundry);
    00661      u32* tempPattern = (u32*)((unsigned int)tempOut - 16);
    00662      tempPattern[0] = tempBoundry;
    00663      tempPattern[1] = inSize;
    00664      tempPattern[2] = 0xFEEBDAED;
    00665      tempPattern[3] = 0x76543210;
    00666      tempPattern = (u32*)((unsigned int)tempOut + inSize);
    00667      tempPattern[0] = 0xDEADBEEF;
    00668      tempPattern[1] = 0x01234567;
    00669      tempPattern[2] = tempBoundry;
    00670      tempPattern[3] = inSize;
    00671
    00672      #if FL_DEBUG_CALLEDFROM
    00673      memtErrorBytesCheckFrom(&memErrorTree, inFile, inFunc, inLine);
    00674      #else
    00675      memtErrorBytesCheck(&memErrorTree);
    00676      #endif
    00677      #else
    00678      if((unsigned int)inData & MEMORY_UNCACHED_OFFSET) {
    00679           while(inSize & 63)
    00680                inSize++;
    00681      } else {
    00682           while(inSize & 15)
    00683                inSize++;
    00684      }
    00685      void* tempOut = realloc(inData, inSize);
    00686      #if FL_DEBUG_WARNING
    00687      if(!tempOut) {
    00688           #if FL_DEBUG_CALLEDFROM
    00689           debugWarningFrom(inFile, inFunc, inLine, "(memRealloc) Error re-allocating memory, memory is probably full/fragmented.");
    00690           #else
    00691           debugWarning("Error re-allocating memory, memory is probably full/fragmented.");
    00692           #endif
    00693      }
    00694      #endif
    00695      #endif
    00696      if((unsigned int)inData & MEMORY_UNCACHED_OFFSET)
    00697           tempOut = memUncachedPtr(tempOut);
    00698      return tempOut;
    00699 }
    00700
    00701 #if FL_DEBUG_CALLEDFROM
    00702 void* memAlignFrom(int inBoundry, int inSize, const char* inFile, const char* inFunc, int inLine) {
    00703 #else
    00704 void* memAlign(int inBoundry, int inSize) {
    00705 #endif
    00706      if(!inSize) {
    00707           #if FL_DEBUG_WARNING
    00708           #if FL_DEBUG_CALLEDFROM
    00709           debugWarningFrom(inFile, inFunc, inLine, "(memAlign) Trying to allocate aligned data of 0 bytes.");
    00710           #else
    00711           debugWarning("Trying to allocate aligned data of 0 bytes.");
    00712           #endif
    00713           #endif
    00714           return NULL;
    00715      }
    00716      if(!inBoundry) {
    00717           #if FL_DEBUG_WARNING
    00718           #if FL_DEBUG_CALLEDFROM
    00719           debugWarningFrom(inFile, inFunc, inLine, "(memAlign) Trying to align to 0 byte boundry.\nReverting to default allocation alignment.");
    00720           #else
    00721           debugWarning("Trying to align to 0 byte boundry.\nReverting to default allocation alignment.");
    00722           #endif
    00723           #endif
    00724      }
    00725
    00726      if(inBoundry < FL_MEMORY_ALIGNMENT_DEFAULT)
    00727           inBoundry = FL_MEMORY_ALIGNMENT_DEFAULT;
    00728
    00729      int i, tempBoundZeroCnt = 0, tempBoundMaxPower = 0;
    00730      for(i = 0; i < (sizeof(void*) << 3); i++) {
    00731           if(inBoundry & (1 << i)) {
    00732                tempBoundZeroCnt++;
    00733                tempBoundMaxPower = i;
    00734           }
    00735      }
    00736      if(tempBoundZeroCnt > 1) {
    00737           #if FL_DEBUG_WARNING
    00738           #if FL_DEBUG_CALLEDFROM
    00739           debugWarningFrom(inFile, inFunc, inLine, "(memAlign) Trying to align to a non-binary boundry.\nReverting to next valid boundry.");
    00740           #else
    00741           debugWarning("Trying to align to a non-binary boundry.\nReverting to next valid boundry.");
    00742           #endif
    00743           #endif
    00744           inBoundry = (1 << (tempBoundMaxPower + 1));
    00745      }
    00746
    00747      while(inSize & (inBoundry - 1))
    00748           inSize++;
    00749
    00750      void* tempOut;
    00751
    00752      #if FL_MEMORY_VMEM_STRIDE_FILL
    00753      tempOut = vmemStrideAlign(inBoundry, inSize);
    00754      if(tempOut)
    00755           return tempOut;
    00756      #endif
    00757
    00758      #if FL_MEMORY_ERRORBYTES
    00759      tempOut = memalign(inBoundry, (inSize + (inBoundry << 1)));
    00760      if(!tempOut) {
    00761           #if FL_DEBUG_WARNING
    00762           #if FL_DEBUG_CALLEDFROM
    00763           debugWarningFrom(inFile, inFunc, inLine, "(memAlign) Error allocating aligned memory, memory is probably full/fragmented.");
    00764           #else
    00765           debugWarning("Error allocating aligned memory, memory is probably full/fragmented.");
    00766           #endif
    00767           #endif
    00768           return NULL;
    00769      }
    00770      #if FL_DEBUG_CALLEDFROM
    00771      memtAddFrom(&memErrorTree, tempOut, inSize, inBoundry, inFile, inFunc, inLine);
    00772      #else
    00773      memtAdd(&memErrorTree, tempOut, inSize, inBoundry);
    00774      #endif
    00775
    00776      tempOut = (void*)((unsigned int)tempOut + inBoundry);
    00777      u32* tempPattern = (u32*)((unsigned int)tempOut - 16);
    00778      tempPattern[0] = inBoundry;
    00779      tempPattern[1] = inSize;
    00780      tempPattern[2] = 0xFEEBDAED;
    00781      tempPattern[3] = 0x76543210;
    00782      tempPattern = (u32*)((unsigned int)tempOut + inSize);
    00783      tempPattern[0] = 0xDEADBEEF;
    00784      tempPattern[1] = 0x01234567;
    00785      tempPattern[2] = inBoundry;
    00786      tempPattern[3] = inSize;
    00787
    00788      #if FL_DEBUG_CALLEDFROM
    00789      memtErrorBytesCheckFrom(&memErrorTree, inFile, inFunc, inLine);
    00790      #else
    00791      memtErrorBytesCheck(&memErrorTree);
    00792      #endif
    00793      #else
    00794      tempOut = memalign(inBoundry, inSize);
    00795      #if FL_DEBUG_WARNING
    00796      if(!tempOut) {
    00797           #if FL_DEBUG_CALLEDFROM
    00798           debugWarningFrom(inFile, inFunc, inLine, "(memAlign) Error allocating aligned memory, memory is probably full/fragmented.");
    00799           #else
    00800           debugWarning("Error allocating aligned memory, memory is probably full/fragmented.");
    00801           #endif
    00802      }
    00803      #endif
    00804      #endif
    00805
    00806      #if FL_MEMORY_VMEM_OVERFLOW
    00807      if(!tempOut)
    00808           tempOut = vmemAlloc(inSize);
    00809      #endif
    00810
    00811      if(!tempOut && !memScratchpadUsed) {
    00812           memScratchpadUsed = true;
    00813           tempOut = (void*)MEMORY_SCRATCHPAD_BASE;
    00814      }
    00815
    00816      return tempOut;
    00817 }
    00818
    00819 #if FL_DEBUG_CALLEDFROM
    00820 void memFreeFrom(void* inData, const char* inFile, const char* inFunc, int inLine) {
    00821 #else
    00822 void memFree(void* inData) {
    00823 #endif
    00824      if(!inData) {
    00825           #if FL_DEBUG_WARNING
    00826           #if FL_DEBUG_CALLEDFROM
    00827           debugWarningFrom(inFile, inFunc, inLine, "(memFree) Trying to free NULL pointer.");
    00828           #else
    00829           debugWarning("Trying to free NULL pointer.");
    00830           #endif
    00831           #endif
    00832           return;
    00833      }
    00834      if(!memAddressValid(inData)) {
    00835           #if FL_DEBUG_WARNING
    00836           #if FL_DEBUG_CALLEDFROM
    00837           debugWarningFrom(inFile, inFunc, inLine, "(memFree) Trying to free invalid pointer (0x%08X).", (unsigned int)inData);
    00838           #else
    00839           debugWarning("Trying to free invalid pointer (0x%08X).", (unsigned int)inData);
    00840           #endif
    00841           #endif
    00842           return;
    00843      }
    00844      if(((u32)inData >= MEMORY_SCRATCHPAD_BASE) && ((u32)inData < (MEMORY_SCRATCHPAD_BASE + MEMORY_SCRATCHPAD_SIZE))) {
    00845           memScratchpadUsed = false;
    00846           return;
    00847      }
    00848      #if FL_MEMORY_VMEM
    00849      if(vmemPointer(inData)) {
    00850           #if FL_DEBUG_CALLEDFROM
    00851           return vmemFreeFrom(inData, inFile, inFunc, inLine);
    00852           #else
    00853           return vmemFree(inData);
    00854           #endif
    00855      }
    00856      #endif
    00857      #if FL_MEMORY_ERRORBYTES
    00858      if(!memErrorBytesCheck(inData)) {
    00859           #if FL_DEBUG_ERROR
    00860           #if FL_DEBUG_CALLEDFROM
    00861           debugErrorFrom(inFile, inFunc, inLine, "(memFree) Cannot free pointer, data corrupt.");
    00862           #else
    00863           debugError("Cannot free pointer, data corrupt.");
    00864           #endif
    00865           #endif
    00866           return;
    00867      }
    00868      u32* tempData = (u32*)((unsigned int)inData - 16);
    00869      inData = (void*)((unsigned int)inData - tempData[0]);
    00870      if(!inData) {
    00871           #if FL_DEBUG_WARNING
    00872           #if FL_DEBUG_CALLEDFROM
    00873           debugWarningFrom(inFile, inFunc, inLine, "(memFree) Trying to free NULL pointer.");
    00874           #else
    00875           debugWarning("Trying to free NULL pointer.");
    00876           #endif
    00877           #endif
    00878           return;
    00879      }
    00880      #endif
    00881      #if FL_MEMORY_ERRORBYTES
    00882      #if FL_DEBUG_CALLEDFROM
    00883      memtDelFrom(&memErrorTree, inData, inFile, inFunc, inLine);
    00884      memtErrorBytesCheckFrom(&memErrorTree, inFile, inFunc, inLine);
    00885      #else
    00886      memtDel(&memErrorTree, inData);
    00887      memtErrorBytesCheck(&memErrorTree);
    00888      #endif
    00889      #endif
    00890      free(inData);
    00891 }
    00892
    00893 #if FL_DEBUG_CALLEDFROM
    00894 void* memUncachedPtrFrom(void* inPtr, const char* inFile, const char* inFunc, int inLine) {
    00895 #else
    00896 void* memUncachedPtr(void* inPtr) {
    00897 #endif
    00898      if(!inPtr) {
    00899           #if FL_DEBUG_WARNING
    00900           #if FL_DEBUG_CALLEDFROM
    00901           debugWarningFrom(inFile, inFunc, inLine, "(memUncachedPtr) Trying to create uncached null pointer.");
    00902           #else
    00903           debugWarning("Trying to create uncached null pointer.");
    00904           #endif
    00905           #endif
    00906           return NULL;
    00907      }
    00908      inPtr = (void*)((unsigned int)inPtr | MEMORY_UNCACHED_OFFSET);
    00909      return inPtr;
    00910 }
    00911
    00912 u32  memAddressAlignment(void* inPtr) {
    00913      u32 i;
    00914      u32 tempBits = (sizeof(void*) << 3);
    00915      for(i = 0; i < tempBits; i++) {
    00916           if((u32)inPtr & (1 << i))
    00917                return (1 << i);
    00918      }
    00919      return (1 << (tempBits - 1));
    00920 }
    00921
    00922 bool memAddressValid(void* inPtr) {
    00923      u32 tempPtr = (u32)memCachedPtr(inPtr);
    00924      if((tempPtr >= MEMORY_USER_BASE) && (tempPtr < (MEMORY_USER_BASE + MEMORY_USER_SIZE)))
    00925           return true;
    00926      if((tempPtr >= MEMORY_SCRATCHPAD_BASE) && (tempPtr < (MEMORY_SCRATCHPAD_BASE + MEMORY_SCRATCHPAD_SIZE)))
    00927           return true;
    00928      if((tempPtr >= MEMORY_VMEM_BASE) && (tempPtr < (MEMORY_VMEM_BASE + (MEMORY_VMEM_SIZE << 2))))
    00929           return true;
    00930      return false;
    00931 }
    00932
    00933 bool memBlockValid(void* inPtr, u32 inSize) {
    00934      u32 tempPtr[2];
    00935      tempPtr[0] = (u32)memCachedPtr(inPtr);
    00936      tempPtr[1] = ((tempPtr[0] + inSize) - 1);
    00937      if((tempPtr[0] >= MEMORY_USER_BASE) && (tempPtr[0] < (MEMORY_USER_BASE + MEMORY_USER_SIZE))) {
    00938           if((tempPtr[1] >= MEMORY_USER_BASE) && (tempPtr[1] < (MEMORY_USER_BASE + MEMORY_USER_SIZE)))
    00939                return true;
    00940           return false;
    00941      }
    00942      if((tempPtr[0] >= MEMORY_SCRATCHPAD_BASE) && (tempPtr[0] < (MEMORY_SCRATCHPAD_BASE + MEMORY_SCRATCHPAD_SIZE))) {
    00943           if((tempPtr[1] >= MEMORY_SCRATCHPAD_BASE) && (tempPtr[1] < (MEMORY_SCRATCHPAD_BASE + MEMORY_SCRATCHPAD_SIZE)))
    00944                return true;
    00945           return false;
    00946      }
    00947      if((tempPtr[0] >= MEMORY_VMEM_BASE) && (tempPtr[0] < (MEMORY_VMEM_BASE + (MEMORY_VMEM_SIZE << 2)))) {
    00948           if((tempPtr[1] >= MEMORY_VMEM_BASE) && (tempPtr[1] < (MEMORY_VMEM_BASE + (MEMORY_VMEM_SIZE << 2)))) {
    00949                if((tempPtr[0] & (MEMORY_VMEM_SIZE - 1)) < (tempPtr[1] & (MEMORY_VMEM_SIZE - 1)))
    00950                     return true;
    00951                return false;
    00952           }
    00953           return false;
    00954      }
    00955      return false;
    00956 }
    00957
    00958 #if FL_MEMORY_PAGE
    00959 unsigned int memToPage(void* inData, unsigned int inSize) {
    00960      if(!inData) {
    00961           #if FL_DEBUG_WARNING
    00962           debugWarning("Trying to page NULL pointer.");
    00963           #endif
    00964           return 0;
    00965      }
    00966      if(!memBlockValid(inData, inSize)) {
    00967           #if FL_DEBUG_WARNING
    00968           debugWarning("Trying to page invalid memory block [%0x08X -> %0x08X].", (unsigned int)inData, ((unsigned int)inData + inSize));
    00969           #endif
    00970           return 0;
    00971      }
    00972      if(((unsigned int)inData >= MEMORY_SCRATCHPAD_BASE) && (inSize < MEMORY_SCRATCHPAD_SIZE)) {
    00973           #if FL_DEBUG_WARNING
    00974           debugWarning("Cannot page scratchpad data directly.");
    00975           #endif
    00976           return 0;
    00977      }
    00978
    00979      FILE* tempFile = fopen(MEMORY_PAGE_PATH, "ab");
    00980      if(!tempFile) {
    00981           #if FL_DEBUG_ERROR
    00982           debugError("Cannot open page file, to offload page.");
    00983           #endif
    00984           return 0;
    00985      }
    00986      unsigned int tempID = memPageID;
    00987      memPageID++;
    00988      fwrite(&tempID, 1, 4, tempFile);
    00989      fwrite(&inSize, 1, 4, tempFile);
    00990      fwrite(inData, 1, inSize, tempFile);
    00991      fclose(tempFile);
    00992      memFree(inData);
    00993      return tempID;
    00994 }
    00995
    00996 void* memFromPage(unsigned int inPageID) {
    00997      if(!inPageID) {
    00998           #if FL_DEBUG_WARNING
    00999           debugWarning("Trying to retrieve page 0 (Error page).");
    01000           #endif
    01001           return NULL;
    01002      }
    01003      FILE* tempFile = fopen(MEMORY_PAGE_PATH, "rb");
    01004      if(!tempFile) {
    01005           #if FL_DEBUG_ERROR
    01006           debugError("Cannot open page file, to retrieve paged data.");
    01007           #endif
    01008           return NULL;
    01009      }
    01010      unsigned int tempID = 0;
    01011      unsigned int tempSize = 0;
    01012      void* tempOut = NULL;
    01013      while(!feof(tempFile)) {
    01014           fread(&tempID, 1, 4, tempFile);
    01015           fread(&tempSize, 1, 4, tempFile);
    01016           if(tempID == inPageID) {
    01017                tempOut = memAlloc(tempSize);
    01018                if(!tempOut) {
    01019                     #if FL_DEBUG_ERROR
    01020                     debugError("Cannot load page file, memory allocation failed.");
    01021                     #endif
    01022                     return NULL;
    01023                }
    01024                fread(tempOut, 1, tempSize, tempFile);
    01025                return tempOut;
    01026           } else {
    01027                fseek(tempFile, tempSize, SEEK_CUR);
    01028           }
    01029      }
    01030      #if FL_DEBUG_ERROR
    01031      debugError("Page with matching PageID not found within page file.");
    01032      #endif
    01033      return NULL;
    01034 }
    01035 #endif
    01036
    01037 #if FL_MEMORY_ERRORBYTES
    01038 #if FL_DEBUG_CALLEDFROM
    01039 bool memErrorBytesCheckFrom(void* inPtr, const char* inFile, const char* inFunc, int inLine) {
    01040 #else
    01041 bool memErrorBytesCheck(void* inPtr) {
    01042 #endif
    01043      u32 tempBoundry;
    01044      u32 tempSize;
    01045      u32* tempPtr = (u32*)((unsigned int)inPtr - 16);
    01046      tempBoundry = tempPtr[0];
    01047      tempSize = tempPtr[1];
    01048      if((tempSize & (tempBoundry - 1)) || ((u32)inPtr & (tempBoundry - 1))) {
    01049           #if FL_DEBUG_ERROR
    01050           #if FL_DEBUG_CALLEDFROM
    01051           debugErrorFrom(inFile, inFunc, inLine, "(memErrorBytesCheck) Memory integrity error, alignment doesn't match description.");
    01052           #else
    01053           debugError("Memory integrity error, alignment doesn't match description.");
    01054           #endif
    01055           #endif
    01056           return false;
    01057      }
    01058      if((tempPtr[2] != 0xFEEBDAED) || (tempPtr[3] != 0x76543210)) {
    01059           #if FL_DEBUG_ERROR
    01060           #if FL_DEBUG_CALLEDFROM
    01061           debugErrorFrom(inFile, inFunc, inLine, "(memErrorBytesCheck) Memory integrity error, underflow.");
    01062           #else
    01063           debugError("Memory integrity error, underflow.");
    01064           #endif
    01065           #endif
    01066           return false;
    01067      }
    01068      tempPtr = (u32*)((unsigned int)inPtr + tempSize);
    01069      if((tempPtr[0] != 0xDEADBEEF) || (tempPtr[1]!= 0x01234567) || (tempPtr[2] != tempBoundry) || (tempPtr[3] != tempSize)) {
    01070           #if FL_DEBUG_ERROR
    01071           #if FL_DEBUG_CALLEDFROM
    01072           debugErrorFrom(inFile, inFunc, inLine, "(memErrorBytesCheck) Memory integrity error, probably overflow, small chance of underflow.");
    01073           #else
    01074           debugError("Memory integrity error, probably overflow, small chance of underflow.");
    01075           #endif
    01076           #endif
    01077           return false;
    01078      }
    01079      return true;
    01080 }
    01081
    01082 #if FL_DEBUG_CALLEDFROM
    01083 void memtAddFrom(MemoryTree** inMemTree, void* inPtr, u32 inSize, u32 inAlignment, const char* inFile, const char* inFunc, int inLine) {
    01084 #else
    01085 void memtAdd(MemoryTree** inMemTree, void* inPtr, u32 inSize, u32 inAlignment) {
    01086 #endif
    01087      if(!inPtr || !inSize || !inAlignment) {
    01088           #if FL_DEBUG_ERROR
    01089           #if FL_DEBUG_CALLEDFROM
    01090           debugErrorFrom(inFile, inFunc, inLine, "(memAdd) Trying to add a node with invalid properties to a memory tree.");
    01091           #else
    01092           debugError("Trying to add a node with invalid properties to a memory tree.");
    01093           #endif
    01094           #endif
    01095           return;
    01096      }
    01097
    01098      if(!memBlockValid(inPtr, (inSize + (inAlignment << 1)))) {
    01099           #if FL_DEBUG_ERROR
    01100           #if FL_DEBUG_CALLEDFROM
    01101           debugErrorFrom(inFile, inFunc, inLine, "(memAdd) Trying to add a node that points to an invalid memory block to a memory tree.");
    01102           #else
    01103           debugError("Trying to add a node that points to an invalid memory block to a memory tree.");
    01104           #endif
    01105           #endif
    01106           return;
    01107      }
    01108
    01109      if((inSize & (inAlignment - 1)) || ((u32)inPtr & (inAlignment - 1))) {
    01110           #if FL_DEBUG_ERROR
    01111           #if FL_DEBUG_CALLEDFROM
    01112           debugErrorFrom(inFile, inFunc, inLine, "(memAdd) Trying to add a node that breaks it's own alignment to a memory tree.");
    01113           #else
    01114           debugError("Trying to add a node that breaks it's own alignment to a memory tree.");
    01115           #endif
    01116           #endif
    01117           return;
    01118      }
    01119
    01120      if(!inMemTree) {
    01121           #if FL_DEBUG_ERROR
    01122           #if FL_DEBUG_CALLEDFROM
    01123           debugErrorFrom(inFile, inFunc, inLine, "(memAdd) Trying to add a node to a NULL memory tree.");
    01124           #else
    01125           debugError("Trying to add a node to a NULL memory tree.");
    01126           #endif
    01127           #endif
    01128           return;
    01129      }
    01130
    01131      MemoryTree* tempOut = malloc(sizeof(MemoryTree));
    01132      if(!tempOut) {
    01133           #if FL_DEBUG_ERROR
    01134           #if FL_DEBUG_CALLEDFROM
    01135           debugErrorFrom(inFile, inFunc, inLine, "(memAdd) Couldn't allocate node for memory tree.\nProbably out of memory.");
    01136           #else
    01137           debugError("Couldn't allocate node for memory tree.\nProbably out of memory.");
    01138           #endif
    01139           #endif
    01140           return;
    01141      }
    01142
    01143      tempOut->memtData = inPtr;
    01144      tempOut->memtSize = inSize;
    01145      tempOut->memtAlignment = inAlignment;
    01146      tempOut->memtNext = (*inMemTree ? *inMemTree : NULL);
    01147      *inMemTree = tempOut;
    01148 }
    01149
    01150 #if FL_DEBUG_CALLEDFROM
    01151 void memtDelFrom(MemoryTree** inMemTree, void* inPtr, const char* inFile, const char* inFunc, int inLine) {
    01152 #else
    01153 void memtDel(MemoryTree** inMemTree, void* inPtr) {
    01154 #endif
    01155      if(!inMemTree || !*inMemTree) {
    01156           #if FL_DEBUG_ERROR
    01157           #if FL_DEBUG_CALLEDFROM
    01158           debugErrorFrom(inFile, inFunc, inLine, "(memDel) Trying to delete a node from a NULL memory tree.");
    01159           #else
    01160           debugError("Trying to delete a node from a NULL memory tree.");
    01161           #endif
    01162           #endif
    01163           return;
    01164      }
    01165
    01166      MemoryTree* tempDelNode = NULL;
    01167      if((*inMemTree)->memtData == inPtr) {
    01168           tempDelNode = *inMemTree;
    01169           *inMemTree = (MemoryTree*)tempDelNode->memtNext;
    01170           free(tempDelNode);
    01171           return;
    01172      }
    01173
    01174      MemoryTree* tempLastNode = *inMemTree;
    01175      while(flRunning) {
    01176           if(!tempLastNode->memtNext) {
    01177                #if FL_DEBUG_ERROR
    01178                #if FL_DEBUG_CALLEDFROM
    01179                debugErrorFrom(inFile, inFunc, inLine, "(memDel) Pointer not found within memory tree.");
    01180                #else
    01181                debugError("Pointer not found within memory tree.");
    01182                #endif
    01183                #endif
    01184                return;
    01185           }
    01186           tempDelNode = (MemoryTree*)tempLastNode->memtNext;
    01187           if(tempDelNode->memtData == inPtr)
    01188                break;
    01189           tempLastNode = tempDelNode;
    01190      }
    01191      tempLastNode->memtNext = (MemoryTree*)tempDelNode->memtNext;
    01192      free(tempDelNode);
    01193 }
    01194
    01195 #if FL_DEBUG_CALLEDFROM
    01196 void memtErrorBytesCheckFrom(MemoryTree** inMemTree, const char* inFile, const char* inFunc, int inLine) {
    01197 #else
    01198 void memtErrorBytesCheck(MemoryTree** inMemTree) {
    01199 #endif
    01200      if(!inMemTree) {
    01201           #if FL_DEBUG_WARNING
    01202           #if FL_DEBUG_CALLEDFROM
    01203           debugWarningFrom(inFile, inFunc, inLine, "(memtErrorBytesCheck) Trying to error check a NULL memory tree.");
    01204           #else
    01205           debugWarning("Trying to error check a NULL memory tree.");
    01206           #endif
    01207           #endif
    01208           return;
    01209      }
    01210      if(!*inMemTree) {
    01211           #if FL_DEBUG_WARNING
    01212           #if FL_DEBUG_CALLEDFROM
    01213           debugWarningFrom(inFile, inFunc, inLine, "(memtErrorBytesCheck) Trying to error check an empty memory tree.");
    01214           #else
    01215           debugWarning("Trying to error check an empty memory tree.");
    01216           #endif
    01217           #endif
    01218           return;
    01219      }
    01220      MemoryTree* tempNode = *inMemTree;
    01221      u32* tempPtr;
    01222      u32 tempSize;
    01223      u32 tempBoundry;
    01224      while(tempNode) {
    01225           if(!memBlockValid(tempNode->memtData, (tempNode->memtSize + (tempNode->memtAlignment << 1)))) {
    01226                #if FL_DEBUG_ERROR
    01227                #if FL_DEBUG_CALLEDFROM
    01228                debugErrorFrom(inFile, inFunc, inLine, "(memtErrorBytesCheck) Memory tree data corrupt.\nPoints to invalid memory block.");
    01229                #else
    01230                debugError("Memory tree data corrupt.\nPoints to invalid memory block.");
    01231                #endif
    01232                #endif
    01233                return;
    01234           }
    01235
    01236           int i, j = 0;
    01237           for(i = 0; i < 32; i++) {
    01238                if(tempNode->memtAlignment & (1 << i))
    01239                    j++;
    01240           }
    01241           if(j != 1) {
    01242                #if FL_DEBUG_ERROR
    01243                #if FL_DEBUG_CALLEDFROM
    01244                debugErrorFrom(inFile, inFunc, inLine, "(memtErrorBytesCheck) Memory tree data corrupt.\nBad alignment value.");
    01245                #else
    01246                debugError("Memory tree data corrupt.\nBad alignment value.");
    01247                #endif
    01248                #endif
    01249                return;
    01250           }
    01251
    01252           if((u32)tempNode->memtData & (tempNode->memtAlignment - 1)) {
    01253                #if FL_DEBUG_ERROR
    01254                #if FL_DEBUG_CALLEDFROM
    01255                debugErrorFrom(inFile, inFunc, inLine, "(memtErrorBytesCheck) Memory tree data corrupt.\nData is not aligned as described in memory tree.");
    01256                #else
    01257                debugError("Memory tree data corrupt.\nData is not aligned as described in memory tree.");
    01258                #endif
    01259                #endif
    01260                return;
    01261           }
    01262           if((u32)tempNode->memtSize & (tempNode->memtAlignment - 1)) {
    01263                #if FL_DEBUG_ERROR
    01264                #if FL_DEBUG_CALLEDFROM
    01265                debugErrorFrom(inFile, inFunc, inLine, "(memtErrorBytesCheck) Memory tree data corrupt.\nSize is not aligned as described in memory tree.");
    01266                #else
    01267                debugError("Memory tree data corrupt.\nSize is not aligned as described in memory tree.");
    01268                #endif
    01269                #endif
    01270                return;
    01271           }
    01272
    01273           if(tempNode->memtNext && !memBlockValid(tempNode->memtNext, sizeof(MemoryTree))) {
    01274                #if FL_DEBUG_ERROR
    01275                #if FL_DEBUG_CALLEDFROM
    01276                debugErrorFrom(inFile, inFunc, inLine, "(memtErrorBytesCheck) Memory tree data corrupt.\nPoints to invalid next node.");
    01277                #else
    01278                debugError("Memory tree data corrupt.\nPoints to invalid next node.");
    01279                #endif
    01280                #endif
    01281                return;
    01282           }
    01283
    01284           tempPtr = (u32*)tempNode->memtData;
    01285           tempSize = tempNode->memtSize;
    01286           tempBoundry = tempNode->memtAlignment;
    01287
    01288           if((tempPtr[0] != tempBoundry) || (tempPtr[1] != tempSize) || (tempPtr[2] != 0xFEEBDAED) || (tempPtr[3] != 0x76543210)) {
    01289                #if FL_DEBUG_ERROR
    01290                #if FL_DEBUG_CALLEDFROM
    01291                debugErrorFrom(inFile, inFunc, inLine, "(memtErrorBytesCheck) Memory integrity error, underflow.");
    01292                #else
    01293                debugError("Memory integrity error, underflow.");
    01294                #endif
    01295                #endif
    01296                return;
    01297           }
    01298           tempPtr = (u32*)(((unsigned int)tempNode->memtData + tempNode->memtAlignment) + tempSize);
    01299           if((tempPtr[0] != 0xDEADBEEF) || (tempPtr[1] != 0x01234567) || (tempPtr[2] != tempBoundry) || (tempPtr[3] != tempSize)) {
    01300                #if FL_DEBUG_ERROR
    01301                #if FL_DEBUG_CALLEDFROM
    01302                debugErrorFrom(inFile, inFunc, inLine, "(memtErrorBytesCheck) Memory integrity error, overflow.");
    01303                #else
    01304                debugError("Memory integrity error, overflow.");
    01305                #endif
    01306                #endif
    01307                return;
    01308           }
    01309           tempNode = (MemoryTree*)tempNode->memtNext;
    01310      }
    01311 }
    01312 #endif
    01313
    01314 #endif