added partial support for Brunni's GB palettes, might make this more permanent in the future by improving the built in palette editor and adding pergame support to it.

This commit is contained in:
squall_leonhart69r 2008-02-29 02:52:45 +00:00
parent 26b66b04dd
commit 5341dc4218
15 changed files with 2352 additions and 11 deletions

353
src/Brunni/VirtualFile.c Normal file
View File

@ -0,0 +1,353 @@
#include "common.h"
/*
Note: seek ne retourne plus rien!
*/
VIRTUAL_FILE_SOURCE *VirtualFileSources[VF_MAX_SOURCES];
int VirtualFileSourcesNb = 0;
int VF_MEMORY = -1;
//List of files for RAM based devices
OSL_VIRTUALFILENAME *osl_virtualFileList;
//Number of entries
int osl_virtualFileListNumber = 0;
//For system use
int osl_virtualFileListSize;
int osl_defaultVirtualFileSource = -1;
const char *osl_tempFileName = "*tmp*";
OSL_VIRTUALFILENAME osl_tempFile;
#define DEFAULT_TABLE_SIZE 128
//Enregistre une nouvelle source
int VirtualFileRegisterSource(VIRTUAL_FILE_SOURCE *vfs) {
//Espace libre?
if (VirtualFileSourcesNb >= VF_MAX_SOURCES)
return -1;
//Ajoute la source
VirtualFileSources[VirtualFileSourcesNb] = vfs;
return VirtualFileSourcesNb++;
}
VIRTUAL_FILE *VirtualFileOpen(void *param1, int param2, int type, int mode) {
VIRTUAL_FILE *f = NULL;
if (type == VF_AUTO) {
if (param2 == 0) {
OSL_VIRTUALFILENAME *file = oslFindFileInVirtualFilenameList((const char*)param1, type);
if (file) {
param1 = file->data;
param2 = file->size;
type = *file->type;
}
else
type = osl_defaultVirtualFileSource;
}
}
if (type >= 0) {
f = (VIRTUAL_FILE*)malloc(sizeof(*f));
if (f) {
memset(f, 0, sizeof(*f));
f->type = type;
if (!VirtualFileGetSource(f)->fOpen(param1, param2, type, mode, f)) {
free(f);
f = NULL;
}
}
}
return f;
}
int VirtualFileClose(VIRTUAL_FILE *f) {
int result = VirtualFileGetSource(f)->fClose(f);
if (result)
free(f);
return result;
}
/*
SOURCE 1 par défaut: Mémoire
*/
int vfsMemOpen(void *param1, int param2, int type, int mode, VIRTUAL_FILE* f) {
//Tous les modes sont supportés mais pas très bien pour l'instant, ne vous amusez pas à écrire et lire en même temps
// if (mode != VF_O_READ || mode != VK_O_WRITE)
// return 0;
//C'est un nom de fichier?
if (param2 == 0) {
OSL_VIRTUALFILENAME *file = oslFindFileInVirtualFilenameList((const char*)param1, type);
if (file) {
param1 = file->data;
param2 = file->size;
}
}
//Initialisation du bloc mémoire
f->offset = 0;
f->ioPtr = param1;
f->maxSize = param2;
return 1;
}
int vfsMemClose(VIRTUAL_FILE *f) {
return 1;
}
int vfsMemWrite(const void *ptr, size_t size, size_t n, VIRTUAL_FILE* f) {
int realSize = size * n, writeSize = 0;
if (f->ioPtr) {
//Débordement?
writeSize = oslMin(realSize, f->maxSize - f->offset);
if (writeSize > 0) {
memcpy((char*)f->ioPtr + f->offset, ptr, writeSize);
//Brunni: ??? this is probably wrong ??? (08.07.2007)
// f->offset += realSize;
f->offset += writeSize;
}
}
return writeSize;
}
int vfsMemRead(void *ptr, size_t size, size_t n, VIRTUAL_FILE* f) {
int readSize = 0, realSize = size * n;
if (f->ioPtr) {
//min => pour éviter les débordements
readSize = oslMin(realSize, f->maxSize - f->offset);
if (readSize > 0) {
memcpy(ptr, (char*)f->ioPtr + f->offset, readSize);
//Brunni: Removed (08.07.2007)
// f->offset += realSize;
f->offset += readSize;
}
}
return readSize;
}
int vfsMemGetc(VIRTUAL_FILE *f) {
unsigned char car;
//Pour la sécurité, quand même un cas à part pour les fichiers
if (VirtualFileRead(&car, sizeof(car), 1, f) < 1)
return -1;
else
return (int)car;
}
int vfsMemPutc(int caractere, VIRTUAL_FILE *f) {
unsigned char car = caractere;
if (VirtualFileWrite(&car, sizeof(car), 1, f) < 1)
return -1;
else
return caractere;
}
char *vfsMemGets(char *str, int maxLen, VIRTUAL_FILE *f) {
const int blockSize = 16;
int offset = 0, i, size;
while(1) {
size = VirtualFileRead(str + offset, 1, oslMin(maxLen - offset, blockSize), f);
if (offset + size < maxLen)
str[offset + size] = 0;
for (i=offset;i<offset+blockSize;i++) {
if (str[i] == 0)
return str;
//\r\n (Windows)
if (str[i] == '\r') {
str[i] = 0;
//Dernier bloc de la liste?
if (i + 1 >= offset + blockSize) {
char temp[1];
int tempSize;
tempSize = VirtualFileRead(temp, 1, 1, f);
//Prochain caractère est un \n?
if (!(tempSize > 0 && temp[0] == '\n'))
//Sinon on annule
i--;
}
else {
if (str[i + 1] == '\n')
i++;
}
//Retourne le pointeur
VirtualFileSeek(f, -size + (i - offset) + 1, SEEK_CUR);
return str;
}
else if (str[i] == '\n') {
str[i] = 0;
//ATTENTION: MODIFIE DE -blockSize + i à -blockSize + i + 1, à vérifier!!!
VirtualFileSeek(f, -blockSize + i + 1, SEEK_CUR);
//Retourne le pointeur
return str;
}
}
offset += blockSize;
}
return str;
}
void vfsMemPuts(const char *s, VIRTUAL_FILE *f) {
VirtualFileWrite(s, strlen(s), 1, f);
}
void vfsMemSeek(VIRTUAL_FILE *f, int offset, int whence) {
// int oldOffset = f->offset;
if (f->ioPtr) {
if (whence == SEEK_SET)
f->offset = offset;
else if (whence == SEEK_CUR)
f->offset += offset;
else if (whence == SEEK_END)
f->offset = f->maxSize + offset;
f->offset = oslMax(oslMin(f->offset, f->maxSize), 0);
}
// return oldOffset;
}
int vfsMemTell(VIRTUAL_FILE *f) {
return f->offset;
}
int vfsMemEof(VIRTUAL_FILE *f) {
return (f->offset < f->maxSize);
}
VIRTUAL_FILE_SOURCE vfsMemory = {
vfsMemOpen,
vfsMemClose,
vfsMemRead,
vfsMemWrite,
vfsMemGetc,
vfsMemPutc,
vfsMemGets,
vfsMemPuts,
vfsMemSeek,
vfsMemTell,
vfsMemEof,
};
//Définit la liste de fichiers pour les sources basées sur la mémoire
/*void oslSetVirtualFilenameList(OSL_VIRTUALFILENAME *vfl, int numberOfEntries) {
osl_virtualFileList = vfl;
osl_virtualFileListNumber = numberOfEntries;
}*/
//Adds files to the list
int oslAddVirtualFileList(OSL_VIRTUALFILENAME *vfl, int numberOfEntries) {
//Need to allocate more?
if (numberOfEntries + osl_virtualFileListNumber > osl_virtualFileListSize) {
int finalSize = numberOfEntries + osl_virtualFileListNumber;
OSL_VIRTUALFILENAME *v;
//Align (we are only reallocating this by blocks of DEFAULT_TABLE_SIZE)
if (finalSize % DEFAULT_TABLE_SIZE > 0)
finalSize = finalSize - finalSize % DEFAULT_TABLE_SIZE + DEFAULT_TABLE_SIZE;
v = (OSL_VIRTUALFILENAME*)realloc(osl_virtualFileList, finalSize * sizeof(OSL_VIRTUALFILENAME));
if (v) {
osl_virtualFileList = v;
osl_virtualFileListSize = finalSize;
}
else
//Failed
return 0;
}
//Copy the new entries
memcpy(osl_virtualFileList + osl_virtualFileListNumber, vfl, numberOfEntries * sizeof(OSL_VIRTUALFILENAME));
osl_virtualFileListNumber += numberOfEntries;
return 1;
}
void oslRemoveVirtualFileList(OSL_VIRTUALFILENAME *vfl, int numberOfEntries) {
int i;
for (i=0;i<=osl_virtualFileListNumber-numberOfEntries;i++) {
//Try to find it in the list
if (!memcmp(osl_virtualFileList + i, vfl, numberOfEntries * sizeof(OSL_VIRTUALFILENAME))) {
//Décale le tout
if (osl_virtualFileListNumber - i - numberOfEntries > 0)
memmove(osl_virtualFileList + i, osl_virtualFileList + i + numberOfEntries, osl_virtualFileListNumber - i - numberOfEntries);
osl_virtualFileListNumber -= numberOfEntries;
}
}
}
OSL_VIRTUALFILENAME *oslFindFileInVirtualFilenameList(const char *fname, int type) {
int i;
OSL_VIRTUALFILENAME *file;
if (fname) {
//Skip the first / that means root for libFat
if (fname[0] == '/')
fname++;
for (i=-1;i<osl_virtualFileListNumber;i++) {
//Include the temporary file in the search
if (i == -1)
file = &osl_tempFile;
else
file = osl_virtualFileList + i;
//Null file type => impossible
if (!file->type)
continue;
//Compare the type and the file name
if ((type == *file->type || type == VF_AUTO)
&& !strcmp(fname, file->name))
return file;
}
}
return NULL;
}
void VirtualFileInit() {
//On enregistre les sources par défaut
if (VF_MEMORY < 0)
VF_MEMORY = VirtualFileRegisterSource(&vfsMemory);
if (VF_FILE < 0)
VF_FILE = oslInitVfsFile();
//By default, load from files
oslSetDefaultVirtualFileSource(VF_FILE);
//Allocate data for the virtual file list
osl_virtualFileListSize = DEFAULT_TABLE_SIZE;
osl_virtualFileListNumber = 0;
//I suppose it never fails
osl_virtualFileList = (OSL_VIRTUALFILENAME*)malloc(DEFAULT_TABLE_SIZE * sizeof(OSL_VIRTUALFILENAME));
osl_tempFile.name = osl_tempFileName;
osl_tempFile.type = NULL;
}
//Par blocs de 4 ko
#define BLOCK_SIZE (4 << 10)
//Lit un fichier entier vers la mémoire
void *oslReadEntireFileToMemory(VIRTUAL_FILE *f, int *fileSize) {
void *block = NULL;
int add = 0;
int size = 0, readSize, finalSize = 0;
do {
size += BLOCK_SIZE;
if (block)
block = realloc(block, size);
else
block = malloc(size);
//L'allocation a échoué?
if (!block)
return NULL;
readSize = VirtualFileRead((char*)block + add, 1, BLOCK_SIZE, f);
add += BLOCK_SIZE;
finalSize += readSize;
} while (readSize >= BLOCK_SIZE);
if (fileSize)
*fileSize = finalSize;
return block;
}
void oslSetTempFileData(void *data, int size, int *type) {
osl_tempFile.data = data;
osl_tempFile.size = size;
osl_tempFile.type = type;
}

360
src/Brunni/VirtualFile.h Normal file
View File

@ -0,0 +1,360 @@
/*! \file VirtualFile.h
\brief
Virtual File support for Oldschool Library.
This API is meant to be an universal mean to manipulate every file source possible as you can define your own.
*/
#ifndef __OSL_VIRTUALFILE_H__
#define __OSL_VIRTUALFILE_H__
#ifdef __cplusplus
extern "C" {
#endif
/** @defgroup virtualfile Virtual Files
Virtual File support for OSLib.
This API is meant to be an universal mean to manipulate every file source possible as you can define your own.
@{
*/
/** Virtual File type. */
typedef struct {
void *ioPtr; //!< User data for IO processing (usually a pointer to data, FILE*, usw.)
unsigned short type; //!< Virtual file type (source number).
unsigned long userData; //!< Additional data
int offset, maxSize; //!< Internal variables for memory-based (RAM / ROM) sources
} VIRTUAL_FILE;
/** Enumeration describing the available file open modes. Please note that some sources do not support some modes like READWRITE or WRITE, in
this case they'll fail when an attempt to open a file in one of these modes is made. The resulting file returned by VirtualFileOpen will be NULL. */
enum VF_OPEN_MODES {
VF_O_READ, //!< Read only
VF_O_READWRITE, //!< Read & Write
VF_O_WRITE //!< Write only
};
//enum {SEEK_SET, SEEK_CUR, SEEK_END};
/** Structure of a Virtual File Source. */
typedef struct {
/**
Open a file.
Return 1 if anything went well, or 0 to throw an error (the opening will be cancelled and NULL will be returned to the user).
*/
int (*fOpen)(void *param1, int param2, int type, int mode, VIRTUAL_FILE* f);
/**
Close a file.
Return 1 if anything went well, 0 to throw an error.
*/
int (*fClose)(VIRTUAL_FILE *f);
/**
Read in a file.
Returns the number of bytes effectively read.
*/
int (*fRead)(void *ptr, size_t size, size_t n, VIRTUAL_FILE* f);
/**
Write in a file
Returns the number of bytes effectively written.
*/
int (*fWrite)(const void *ptr, size_t size, size_t n, VIRTUAL_FILE* f);
/**
Read a single character.
Returns the next character (byte) in the file.
*/
int (*fGetc)(VIRTUAL_FILE *f);
/**
Write a single character
Writes a single character. Returns the character value if anything went well, -1 else.
*/
int (*fPutc)(int caractere, VIRTUAL_FILE *f);
/**
Read a string
Reads a string to the buffer pointed to by str, of a maximum size of maxLen. Returns a pointer to the read string (str in general).
Reading stops to the next carriage return found (\\n). The routine should handle correctly the following sequences by reading them
entirely: \\r, \\r\\n, \\n. If a \\r is found, you should read the following byte and rewind one byte behind if it's not a \\n.
If you cannot afford a rewind, then keep the next character in cache and return it to the next read.
*/
char* (*fGets)(char *str, int maxLen, VIRTUAL_FILE *f);
/**
Write a string
Writes an entire string to the file.
*/
void (*fPuts)(const char *s, VIRTUAL_FILE *f);
/**
Moving in the file
Sets the current file position and returns the old one. The whence parameter uses the same values as stdio (SEEK_SET, SEEK_CUR, SEEK_END).
*/
void (*fSeek)(VIRTUAL_FILE *f, int offset, int whence);
/**
Get current file position
Returns the current pointer position in the file. You can then use VirtualFileSeek(f, position, SEEK_SET) to return to it.
*/
int (*fTell)(VIRTUAL_FILE *f);
/**
End of file
Returns true (1) if it's the end of the file, false (0) else.
*/
int (*fEof)(VIRTUAL_FILE *f);
} VIRTUAL_FILE_SOURCE;
/** Virtual file list item. Used for RAM based devices. */
typedef struct {
const char *name; //!< Virtual file name
void *data; //!< RAM data block
int size; //!< Block data size
int *type; //!< Associated source (e.g. &VF_MEMORY). Don't forget the &, which is there so you can pass a variable which is not known at compile time (virtual file sources are registered upon start, so the compiler doesn't know the ID it will be given in advance).
} OSL_VIRTUALFILENAME;
/** Initializes the virtual filesystem. Done by default by OSLib, so there is no need to call it by yourself. */
void VirtualFileInit();
/** Open a new file.
\param param1
Pointer to a string representing the file name.
\param type
File type. By default, can be:
- VF_MEMORY: read/write from a memory block
- VF_FILE: read from standard stdio routines.
\param mode
One of VF_OPEN_MODES.
*/
VIRTUAL_FILE *VirtualFileOpen(void *param1, int param2, int type, int mode);
/** Closes an open file. */
int VirtualFileClose(VIRTUAL_FILE *f);
/** @defgroup virtualfile_io I/O routines
Routines for reading / writing to a virtual file. Make sure to check the Virtual File main page to know how to open files, etc.
@{
*/
/** Writes in a file and returns the number of bytes effectively written. */
#define VirtualFileWrite(ptr, size, n, f) (VirtualFileGetSource(f)->fWrite(ptr, size, n, f))
/** Reads in a file and returns the number of bytes effectively read. */
#define VirtualFileRead(ptr, size, n, f) (VirtualFileGetSource(f)->fRead(ptr, size, n, f))
/** Reads a single character. Returns the next character (byte) in the file. */
#define VirtualFileGetc(f) (VirtualFileGetSource(f)->fGetc(f))
/** Writes a single character. Returns the character value if anything went well, -1 else. */
#define VirtualFilePutc(caractere, f) (VirtualFileGetSource(f)->fPutc(caractere, f))
/** Reads a string to the buffer pointed to by str, of a maximum size of maxLen. Returns a pointer to the read string (str in general).
Reading stops to the next carriage return found (\\n, \\r\\n or \\r), supporting files created by every OS (I think). */
#define VirtualFileGets(str, maxLen, f) (VirtualFileGetSource(f)->fGets(str, maxLen, f))
/** Writes a string to the file. */
#define VirtualFilePuts(s, f) (VirtualFileGetSource(f)->fPuts(s, f))
/** Sets the current file position and returns the old one. The whence parameter uses the same values as stdio (SEEK_SET, SEEK_CUR, SEEK_END). */
#define VirtualFileSeek(f, offset, whence) (VirtualFileGetSource(f)->fSeek(f, offset, whence))
/** Returns the current file pointer. */
#define VirtualFileTell(f) (VirtualFileGetSource(f)->fTell(f))
/** Returns true (1) if it's the end of the file, false (0) else. */
#define VirtualFileEof(f) (VirtualFileGetSource(f)->fEof(f))
/** @} */ // end of virtualfile_io
/** Adds a new file source to the virtual file system.
\param vfs
Must be a pointer to a valid VIRTUAL_FILE_SOURCE interface containing all your functions for handling the file source.
\return
Returns the identifier of your source or -1 if it has failed. You can then use this ID as a file type (parameter for VirtualFileOpen). */
int VirtualFileRegisterSource(VIRTUAL_FILE_SOURCE *vfs);
/* UNSUPPORTED! SEE oslAddVirtualFileList INSTEAD!
Registers a file list for RAM based devices (such as VF_MEMORY).
\param vfl
List of files (each file is a UL_VIRTUALFILENAME item)
*/
//void oslSetVirtualFilenameList(OSL_VIRTUALFILENAME *vfl, int numberOfEntries);
/** Call this function in your virtual file source OPEN handler, if it's a RAM based device and param2 == 0 (means null size, impossible).
It will return a UL_VIRTUALFILENAME where you can get a pointer to the data and their size. Note that the return value can be NULL if the file has not been found or an error occured (e.g. fname is NULL). */
OSL_VIRTUALFILENAME *oslFindFileInVirtualFilenameList(const char *fname, int type);
//Maximum number of sources
#define VF_MAX_SOURCES 16
//Gets a pointer to the virtual file source associated to a file
#define VirtualFileGetSource(vf) (VirtualFileSources[(vf)->type])
//List of virtual file sources
extern VIRTUAL_FILE_SOURCE *VirtualFileSources[VF_MAX_SOURCES];
extern int VirtualFileSourcesNb;
extern OSL_VIRTUALFILENAME *osl_virtualFileList;
extern int osl_virtualFileListNumber;
extern int osl_defaultVirtualFileSource;
extern const char *osl_tempFileName;
/** Reads an entire file to memory and returns a pointer to the memory block. The block memory usage is stepped by 4 kB, so even a 1 kB file will take 16 kB, so this function is not recommended for opening a lot of small files. The bloc must be freed (using free) once you've finished with it!
\param f
Pointer to an open virtual file.
\param size
Pointer to an integer that will contain the number of bytes read from the file. Can be NULL (in this case the value is discarded).
\code
int size;
VIRTUAL_FILE *f;
char *data;
//Open a file
f = VirtualFileOpen("test.txt", 0, VF_AUTO, VF_O_READ);
//Read it entirely to RAM
data = oslReadEntireFileToMemory(f, &size);
//Print each character
for (i=0;i<size;i++)
oslPrintf("%c", data[i]);
\endcode */
extern void *oslReadEntireFileToMemory(VIRTUAL_FILE *f, int *size);
/*
Source par défaut: mémoire
*/
extern int vfsMemOpen(void *param1, int param2, int type, int mode, VIRTUAL_FILE* f);
extern int vfsMemClose(VIRTUAL_FILE *f);
extern int vfsMemWrite(const void *ptr, size_t size, size_t n, VIRTUAL_FILE* f);
extern int vfsMemRead(void *ptr, size_t size, size_t n, VIRTUAL_FILE* f);
extern int vfsMemGetc(VIRTUAL_FILE *f);
extern int vfsMemPutc(int caractere, VIRTUAL_FILE *f);
extern char *vfsMemGets(char *str, int maxLen, VIRTUAL_FILE *f);
extern void vfsMemPuts(const char *s, VIRTUAL_FILE *f);
extern void vfsMemSeek(VIRTUAL_FILE *f, int offset, int whence);
extern int vfsMemTell(VIRTUAL_FILE *f);
extern int vfsMemEof(VIRTUAL_FILE *f);
extern VIRTUAL_FILE_SOURCE vfsMemory;
/** @defgroup virtualfile_sources Virtual file sources
There are two virtual file sources available by default: memory and file.
@{
*/
/** Initializes the file system. You do not need to call it by yourself as it's done automatically by OSLib. */
int oslInitVfsFile();
/**
Sets the default virtual file source (VF_FILE by default). Used if you use VF_AUTO, that is any oslLoad[...]File routine.
OSLib will search in the current file list to find wether the file exists and is of a different type (e.g. VF_MEMORY). If the file is not found, it will treat it with the default type.
\param source
Can be VF_FILE, VF_MEMORY or any virtual file device registered by you.
*/
extern __inline void oslSetDefaultVirtualFileSource(int source) {
osl_defaultVirtualFileSource = source;
}
/** Read and write from memory. Automatically registered when initializing OSLib. */
extern int VF_MEMORY;
/** Read and write from a file. */
extern int VF_FILE;
/** Auto select source. Uses the current file list to find whether the file name exists in it. If it's not found, it uses the currently active source. */
#define VF_AUTO -2
/** @} */ // end of virtualfile_sources
/** @defgroup virtualfile_ram RAM virtual files
There are two virtual file sources available by default: memory and file.
@{
*/
/** Gets the name of the temporary file. See #oslSetTempFileData for a code sample. */
extern __inline char *oslGetTempFileName() {
return (char*)osl_tempFileName;
}
/** Sets the data associated to a temporary file.
\code
//Binary data representing a JPG file
const int test_data[] = {...};
//The file is 1280 bytes (it's the length of the test_data array)
const int test_data_size = 1280;
//Set data for the temporary file
oslSetTempFileData(test_data, test_data_size, &VF_MEMORY);
//Load a JPG file using the temporary file (oslGetTempFileName to get its name)
image = oslLoadImageFileJPG(oslGetTempFileName(), OSL_IN_RAM | OSL_SWIZZLED, OSL_PF_5650);
\endcode */
extern void oslSetTempFileData(void *data, int size, int *type);
/** Adds a list of virtual files. You will then be able to open these files as if they were real.
\param vfl
Pointer to an array of #OSL_VIRTUALFILENAME entries
\param numberOfEntries
Number of #OSL_VIRTUALFILENAME entries in the array
\code
//Binary data representing a JPG file
const int test_jpg[] = {...};
const char *text = "This is a text file";
//Each entry consists of a name, a pointer to the data, the size of the data, and
//a file type. See the OSL_VIRTUALFILENAME documentation for more information.
OSL_VIRTUALFILENAME ram_files[] = {
{"ram:/test.jpg", (void*)test_jpg, sizeof(test_jpg), &VF_MEMORY},
{"ram:/something.txt", (void*)text, strlen(text), &VF_MEMORY},
};
//Add these files to the list
oslAddVirtualFileList(ram_files, oslNumberof(ram_files));
//We can now open them as if they were real files...
VirtualFileOpen("ram:/something.txt", 0, VF_AUTO, VF_O_READ);
oslLoadImageFileJPG("ram:/test.jpg", OSL_IN_VRAM, OSL_PF_5650);
[...]
\endcode */
extern int oslAddVirtualFileList(OSL_VIRTUALFILENAME *vfl, int numberOfEntries);
/** Removes file entries from the virtual file list.
\code
OSL_VIRTUALFILENAME ram_files[] = {
[..]
};
//Add these files to the list
oslAddVirtualFileList(ram_files, oslNumberof(ram_files));
//Removing them is as simple as adding them
oslRemoveVirtualFileList(ram_files, oslNumberof(ram_files));
\endcode */
extern void oslRemoveVirtualFileList(OSL_VIRTUALFILENAME *vfl, int numberOfEntries);
/** @} */ // end of virtualfile_ram
/** @} */ // end of virtualfile
#ifdef __cplusplus
}
#endif
#endif

24
src/Brunni/common.h Normal file
View File

@ -0,0 +1,24 @@
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <string.h>
#include "VirtualFile.h"
#include <windows.h>
#define oslMin(x, y) (((x)<(y))?(x):(y))
#define oslMax(x, y) (((x)>(y))?(x):(y))
typedef signed char s8;
typedef signed short s16;
typedef signed int s32;
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
#include "config.h"
//Dans gbGfx.cpp
extern void tilePalReinit();
void tilePalInit();

1193
src/Brunni/config.cpp Normal file

File diff suppressed because it is too large Load Diff

93
src/Brunni/config.h Normal file
View File

@ -0,0 +1,93 @@
#ifndef PSP_CONFIG_H
#define PSP_CONFIG_H
#include "common.h"
typedef unsigned long OSL_COLOR;
//For game boy ColorIt.
#define NB_PALETTES 48
#ifdef RGB
#undef RGB
#endif
/** Pixelformats (color types / modes). */
enum OSL_PIXELFORMATS {
OSL_PF_5650, //!< 16 bits, 5 bits per component, except green which has 6, no alpha
OSL_PF_5551, //!< 15 bits, 5 bits per component, 1 alpha bit
OSL_PF_4444, //!< 12 bits, 4 bits per component, 4 alpha bits
OSL_PF_8888, //!< 32 bits, 8 bits per component, 8 alpha bits
OSL_PF_4BIT, //!< Paletted format, 4 bits (16 colors), cannot be set as drawbuffer
OSL_PF_8BIT //!< Paletted format, 8 bits (256 colors), cannot be set as drawbuffer
};
/** Creates a 32-bit opaque color. */
#define RGB(r,v,b) ((r) | ((v)<<8) | ((b)<<16) | (0xff<<24))
/** Creates a 32-bit color. 32-bit colors is what all OSLib calls asking for a color want. Use RGB if you don't want to bother about alpha (semi transparency). */
#define RGBA(r,v,b,a) ((r) | ((v)<<8) | ((b)<<16) | ((a)<<24))
/** Creates a 12-bit color with 3 coefficients (red, green, blue). Alpha is set to the maximum (opaque). The r, v, b values can be from 0 to 255, they're divided to match the 12-bit pixel format. */
#define RGB12(r,v,b) ((((b)>>4)<<8) | (((v)>>4)<<4) | ((r)>>4) | (0xf<<12))
/** Creates a 12-bit color with 4 coefficients (red, green, blue, alpha). */
#define RGBA12(r,v,b,a) ((((a)>>4)<<12) | (((b)>>4)<<8) | (((v)>>4)<<4) | ((r)>>4))
/** Creates a 15-bit opaque color. */
#define RGB15(r,v,b) ((((b)>>3)<<10) | (((v)>>3)<<5) | ((r)>>3) | (1<<15))
/** Creates a 15-bit color with alpha. */
#define RGBA15(r,v,b,a) ((((a)>>7)<<15) | (((b)>>3)<<10) | (((v)>>3)<<5) | ((r)>>3))
/** Creates a 16-bit color. */
#define RGB16(r,v,b) ((((b)>>3)<<11) | (((v)>>2)<<5) | ((r)>>3))
#define oslRgbaGet8888(data, r, g, b, a) ((r)=((data)&0xff), (g)=(((data)>>8)&0xff), (b)=(((data)>>16)&0xff), (a)=(((data)>>24)&0xff))
#define oslRgbaGet4444(data, r, g, b, a) ((r)=((data)&0xf)<<4, (g)=(((data)>>4)&0xf)<<4, (b)=(((data)>>8)&0xf)<<4, (a)=(((data)>>12)&0xf)<<4)
#define oslRgbaGet5551(data, r, g, b, a) ((r)=((data)&0x1f)<<3, (g)=(((data)>>5)&0x1f)<<3, (b)=(((data)>>10)&0x1f)<<3, (a)=(((data)>>15)&0x1)<<7)
#define oslRgbGet5650(data, r, g, b) ((r)=((data)&0x1f)<<3, (g)=(((data)>>5)&0x3f)<<2, (b)=(((data)>>11)&0x1f)<<3)
#define oslRgbaGet4444f(data, r, g, b, a) ((r)=((data)&0xf)<<4 | ((data)&0xf), (g)=(((data)>>4)&0xf)<<4 | (((data)>>4)&0xf), (b)=(((data)>>8)&0xf)<<4 | (((data)>>8)&0xf), (a)=(((data)>>12)&0xf)<<4 | (((data)>>12)&0xf))
#define oslRgbaGet5551f(data, r, g, b, a) ((r)=((data)&0x1f)<<3 | ((data)&0x1f)>>2, (g)=(((data)>>5)&0x1f)<<3 | (((data)>>5)&0x1f)>>2, (b)=(((data)>>10)&0x1f)<<3 | (((data)>>10)&0x1f)>>2, (a)=(((data)>>15)&0x1)*255)
#define oslRgbGet5650f(data, r, g, b) ((r)=((data)&0x1f)<<3 | ((data)&0x1f)>>2, (g)=(((data)>>5)&0x3f)<<2 | (((data)>>5)&0x3f)>>4, (b)=(((data)>>11)&0x1f)<<3 | (((data)>>10)&0x1f)>>2)
#define numberof(a) (sizeof(a)/sizeof(*(a)))
typedef struct {
char *nom;
void *handle;
unsigned char type, flags;
void *handle2;
} IDENTIFICATEUR;
typedef struct {
int taille;
const IDENTIFICATEUR *objet;
} INFOS_OBJET;
typedef struct {
int taille;
int type;
const void *tableau;
} INFOS_TABLEAU;
//Dans un tableau, toutes les chaînes ont cette taille!!!
#define TAILLE_MAX_CHAINES 512
enum {SAVETYPE_DEFAULT, SAVETYPE_GAME, SAVETYPE_CHANGESONLY};
extern int gblIndice;
extern char menuDefaultExecute[TAILLE_MAX_CHAINES];
extern int gblModeColorIt;
extern char gblColorItPaletteFileName[MAX_PATH];
extern int gblConfigAutoShowCrc;
extern int ExecScript(VIRTUAL_FILE *f, char *fonction, char *command);
extern void SetVariableValue(const IDENTIFICATEUR *id, char *ptr);
extern char *GetVariableValue(const IDENTIFICATEUR *id, int withQuotes);
extern const IDENTIFICATEUR *GetVariableAddress(char *str);
extern int OuvreFichierConfig(char *nom_fichier, char *fonction);
extern char *GetChaine(char **dest);
//extern u32 GetAddedColor(int color, int value);
extern void ScriptSave(const char *filename, int type);
extern int oslConvertColor(int pfDst, int pfSrc, int color);
extern int CheckFichierPalette(char *file);
extern void OuvreFichierPalette(int crc, char *fonction);
extern u8 *getGbExtVramAddr();
extern char *extractFilePath(char *file, char *dstPath, int level);
#endif

3
src/Brunni/gb.h Normal file
View File

@ -0,0 +1,3 @@
void gb_invalidate_all_colors();
void gb_invalidate_palette(int palNo);

84
src/Brunni/vfsFile.c Normal file
View File

@ -0,0 +1,84 @@
#include "common.h"
/*
SOURCE VFS: file
*/
#define FLAG_EOF 1
int VF_FILE = -1;
#define _file_ ((FILE*)f->ioPtr)
int vfsFileOpen(void *param1, int param2, int type, int mode, VIRTUAL_FILE* f) {
char *stdMode = "rb";
if (mode == VF_O_WRITE)
stdMode = "wb";
else if (mode == VF_O_READWRITE)
stdMode = "a+";
f->ioPtr = (void*)fopen((char*)param1, stdMode);
return (int)f->ioPtr;
}
int vfsFileClose(VIRTUAL_FILE *f) {
fclose(_file_);
return 1;
}
int vfsFileWrite(const void *ptr, size_t size, size_t n, VIRTUAL_FILE* f) {
return fwrite(ptr, size, n, _file_);
}
int vfsFileRead(void *ptr, size_t size, size_t n, VIRTUAL_FILE* f) {
return fread(ptr, size, n, _file_);
}
int vfsFileGetc(VIRTUAL_FILE *f) {
return fgetc(_file_);
}
int vfsFilePutc(int caractere, VIRTUAL_FILE *f) {
return fputc(caractere, _file_);
}
char *vfsFileGets(char *str, int maxLen, VIRTUAL_FILE *f) {
return vfsMemGets(str, maxLen, f);
}
void vfsFilePuts(const char *s, VIRTUAL_FILE *f) {
fputs(s, _file_);
}
void vfsFileSeek(VIRTUAL_FILE *f, int offset, int whence) {
fseek(_file_, offset, whence);
}
int vfsFileTell(VIRTUAL_FILE *f) {
return ftell(_file_);
}
int vfsFileEof(VIRTUAL_FILE *f) {
return feof(_file_);
}
VIRTUAL_FILE_SOURCE vfsFile = {
vfsFileOpen,
vfsFileClose,
vfsFileRead,
vfsFileWrite,
vfsFileGetc,
vfsFilePutc,
vfsFileGets,
vfsFilePuts,
vfsFileSeek,
vfsFileTell,
vfsFileEof,
};
int oslInitVfsFile() {
VF_FILE = VirtualFileRegisterSource(&vfsFile);
return VF_FILE;
}

View File

@ -25,7 +25,7 @@
#include "GBAcpu.h"
#include "GBAinline.h"
#include "../Globals.h"
#include "GBAGFX.h"
#include "GBAGfx.h"
#include "../EEprom.h"
#include "../Flash.h"
#include "../Sound.h"

View File

@ -22,7 +22,7 @@
#define VBA_GFX_H
#include "GBA.h"
#include "gbaGfx.h"
#include "GBAGfx.h"
#include "../Globals.h"
#include "../Port.h"

View File

@ -4011,6 +4011,12 @@ void gbCleanUp()
gbSgbShutdown();
//Brunni/
if (gbExternalVram != NULL) {
free(gbExternalVram);
gbExternalVram = NULL;
}
if(gbVram != NULL) {
free(gbVram);
gbVram = NULL;

View File

@ -17,11 +17,63 @@
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include <memory.h>
#include "../Brunni/common.h"
#include "../agb/GBA.h"
#include "gbGlobals.h"
#include "gbSGB.h"
/** BRUNNI ADDED CODE **/
int gblModeColorIt=0;
byte tilePalList[384];
short tilePalPalette[NB_PALETTES][4];
byte tilePalCrc[384 / 8];
short tileMapTileList[384];
int gb_lastVramCrc;
u8 *gbExternalVram;
void tilePalReinit() {
int i;
memset(tilePalList, 0, sizeof(tilePalList));
for (i=0;i<numberof(tileMapTileList);i++)
tileMapTileList[i] = i;
}
void tilePalInit() {
memset(tilePalCrc, 0, sizeof(tilePalCrc));
gb_lastVramCrc = 0;
}
int tileMapGetVramChecksum() {
int i;
u32 crc = 0;
u8 *vram = &gbMemory[0x8000];
for (i=0;i<384;i++) {
if (tilePalCrc[i >> 3] & (1 << (i & 7)))
crc = crc32(crc, vram + i * 16, 16);
}
return crc;
}
void exiting_lcdc() {
//Do nothing in GBC mode (VBA uses another VRAM address)
if (!gblModeColorIt || gbCgbMode)
return;
u32 crc = tileMapGetVramChecksum();
if (crc != gb_lastVramCrc /*|| gblConfigAutoShowCrc*/) {
OuvreFichierPalette(crc, NULL);
if (gblConfigAutoShowCrc) {
char temp[256];
sprintf(temp, "New VRAM CRC: %08x", crc);
systemScreenMessage(temp);
}
gb_lastVramCrc = crc;
}
}
/** END BRUNNI **/
u8 gbInvertTab[256] = {
0x00,0x80,0x40,0xc0,0x20,0xa0,0x60,0xe0,
0x10,0x90,0x50,0xd0,0x30,0xb0,0x70,0xf0,
@ -66,14 +118,19 @@ void gbRenderLine()
memset(gbLineMix, 0, sizeof(gbLineMix));
u8 * bank0;
u8 * bank1;
//Brunni/
u8 * externalVram = NULL;
if(gbCgbMode) {
bank0 = &gbVram[0x0000];
bank1 = &gbVram[0x2000];
} else {
bank0 = &gbMemory[0x8000];
bank1 = NULL;
//Brunni/ Additional memory for custom tiles - we should have done just like the GBC, two banks
if (gblModeColorIt)
externalVram = getGbExtVramAddr();
}
int tile_map = 0x1800;
if((register_LCDC & 8) != 0)
tile_map = 0x1c00;
@ -128,6 +185,25 @@ void gbRenderLine()
u8 tile_a = 0;
u8 tile_b = 0;
u8 colorItPaletteNb = 0, colorItUseExtVram = 0;
//Brunni/ Pattern change (custom tile)
if (gblModeColorIt) {
//Brunni/ Get the tile number (+128 if LCDC bit4 is zero)
s16 tilenb = (tile_pattern >> 4) + tile;
colorItPaletteNb = tilePalList[tilenb];
//Brunni/ Select the associated custom tile
tilenb = tileMapTileList[tilenb];
//Brunni/ Does it use additional GB vram? ("bank 1")
if (tilenb >= 512)
colorItUseExtVram = 1, tilenb -= 512;
//Brunni/ Nothing to do => return to the normal range (within current bank)
tilenb -= (tile_pattern >> 4);
tile_pattern_address = tile_pattern + tilenb * 16 + by * 2;
}
if(attrs & 0x40) {
tile_pattern_address = tile_pattern + tile * 16 + (7-by)*2;
@ -136,6 +212,11 @@ void gbRenderLine()
if(attrs & 0x08) {
tile_a = bank1[tile_pattern_address++];
tile_b = bank1[tile_pattern_address];
}
else if (colorItUseExtVram) {
//Brunni/ "bank 1" (additional GB vram)
tile_a = externalVram[tile_pattern_address++];
tile_b = externalVram[tile_pattern_address];
} else {
tile_a = bank0[tile_pattern_address++];
tile_b = bank0[tile_pattern_address];
@ -170,6 +251,10 @@ void gbRenderLine()
c = c + 4*palette;
}
//Brunni/ Find the right palette
if (gblModeColorIt)
c += 4 * colorItPaletteNb;
}
gbLineMix[x] = gbColorOption ? gbColorFilter[gbPalette[c] & 0x7FFF] :
gbPalette[c] & 0x7FFF;
@ -323,6 +408,25 @@ void gbRenderLine()
while(x < 160) {
u8 tile_a = 0;
u8 tile_b = 0;
u8 colorItPaletteNb = 0, colorItUseExtVram = 0;
//Brunni/ Define the actual palette and custom pattern for this tile
if (gblModeColorIt) {
//Brunni/ Get the tile number (+128 if LCDC bit4 is zero)
s16 tilenb = (tile_pattern >> 4) + tile;
colorItPaletteNb = tilePalList[tilenb];
//Brunni/ Select the associated custom tile
tilenb = tileMapTileList[tilenb];
//Brunni/ Does it use additional GB vram? ("bank 1")
if (tilenb >= 512)
colorItUseExtVram = 1, tilenb -= 512;
//Brunni/ Nothing to do => return to the normal range (within current bank)
tilenb -= (tile_pattern >> 4);
tile_pattern_address = tile_pattern + tilenb * 16 + by * 2;
}
if(attrs & 0x40) {
tile_pattern_address = tile_pattern + tile * 16 + (7-by)*2;
@ -331,6 +435,11 @@ void gbRenderLine()
if(attrs & 0x08) {
tile_a = bank1[tile_pattern_address++];
tile_b = bank1[tile_pattern_address];
}
else if (colorItUseExtVram) {
//Brunni/ "bank 1" (additional GB vram)
tile_a = externalVram[tile_pattern_address++];
tile_b = externalVram[tile_pattern_address];
} else {
tile_a = bank0[tile_pattern_address++];
tile_b = bank0[tile_pattern_address];
@ -367,6 +476,9 @@ void gbRenderLine()
c = c + 4*palette;
}
//Brunni/ Find the right palette
if (gblModeColorIt)
c += 4 * colorItPaletteNb;
}
gbLineMix[x] = gbColorOption ? gbColorFilter[gbPalette[c] & 0x7FFF] :
gbPalette[c] & 0x7FFF;
@ -424,6 +536,8 @@ void gbDrawSpriteTile(int tile, int x,int y,int t, int flags,
{
u8 * bank0;
u8 * bank1;
//Brunni/
u8 * externalVram = NULL;
if(gbCgbMode) {
if(register_VBK & 1) {
bank0 = &gbVram[0x0000];
@ -435,6 +549,8 @@ void gbDrawSpriteTile(int tile, int x,int y,int t, int flags,
} else {
bank0 = &gbMemory[0x8000];
bank1 = NULL;
if (gblModeColorIt)
externalVram = getGbExtVramAddr();
}
int init = 0x0000;
@ -461,10 +577,27 @@ void gbDrawSpriteTile(int tile, int x,int y,int t, int flags,
int address = init + tile * 16 + 2*t;
int a = 0;
int b = 0;
u8 colorItPaletteNb = 0, colorItUseExtVram = 0;
//Brunni/ Define the actual palette and custom pattern for this tile
if (gblModeColorIt) {
//Brunni/ Get the tile number (+128 if LCDC bit4 is zero)
colorItPaletteNb = tilePalList[tile];
//Brunni/ Associated custom tile
tile = tileMapTileList[tile];
//Brunni/ Same way as BGs => additional GB vram
if (tile >= 512)
colorItUseExtVram = 1, tile -= 512;
address = init + tile * 16 + 2*t;
}
if(gbCgbMode && (flags & 0x08)) {
a = bank1[address++];
b = bank1[address++];
} else if (colorItUseExtVram) {
//Brunni/ "bank 1" (additional GB vram)
a = externalVram[address++];
b = externalVram[address++];
} else {
a = bank0[address++];
b = bank0[address++];
@ -538,6 +671,11 @@ void gbDrawSpriteTile(int tile, int x,int y,int t, int flags,
c = c + 4*palette;
} else {
//Brunni/ Set the color palette
if (gblModeColorIt)
c += 4 * colorItPaletteNb;
else
//Brunni/ Normal GB behaviour (first 4 colors for the BG, etc.)
c += 4;
}
}
@ -590,6 +728,9 @@ void gbDrawSprites(bool draw)
}
count++;
} else if(!size && t >= 0 && t < 8) {
gbDrawSpriteTile(tile, x-8, yc, t, flags,size,i);
count++;
}
}
// sprite limit reached!

View File

@ -34,6 +34,8 @@ extern u8 *gbWram;
extern u8 *gbMemory;
extern u16 *gbLineBuffer;
extern u8 *gbTAMA5ram;
//Brunni/ Used for custom tiles
extern u8 *gbExternalVram;
extern u8 *gbMemoryMap[16];
@ -85,5 +87,7 @@ extern int gbDmaTicks;
extern void gbRenderLine();
extern void gbDrawSprites(bool);
//Brunni/ Needs to be called when the screen switches from "blank" to "normal"
extern void exiting_lcdc();
extern u8 (*gbSerialFunction)(u8);

View File

@ -177,6 +177,7 @@ void AccelEditor::OnAssign()
CAccelsOb* pAccel;
WORD wIDCommand;
POSITION pos;
int index;
WORD wKey;
bool bCtrl, bAlt, bShift;
@ -199,10 +200,10 @@ void AccelEditor::OnAssign()
m_alreadyAffected.SetWindowText(pCmdAccel->m_szCommand);
m_key.SetSel(0, -1);
return; // abort
}
}
}
}
}
}
// OK, we can add the accel key in the currently selected group
index = m_commands.GetCurSel();
if (index == LB_ERR)

View File

@ -30,7 +30,7 @@
#include "Reg.h"
#include "WinResUtil.h"
#include "Logging.h"
#include "../Brunni/common.h"
#include "../System.h"
#include "../AutoBuild.h"
#include "../cheatSearch.h"
@ -54,6 +54,8 @@ static char THIS_FILE[] = __FILE__;
extern void remoteCleanUp();
extern int gbHardware;
//Brunni/ Routine that checks when the configuration file has been modified
void startCheckRoutine(char *fullFileName);
/////////////////////////////////////////////////////////////////////////////
// MainWnd
@ -535,6 +537,21 @@ bool MainWnd::FileRun()
theApp.romSize = size;
}
}
//Brunni/ Try to load the palette configuration file
VirtualFileInit();
if (theApp.gbColorization) {
gblModeColorIt = CheckFichierPalette(theApp.szFile.GetBuffer());
if (gblModeColorIt) {
char name[2048];
OuvreFichierPalette(0, "init");
_fullpath(name, gblColorItPaletteFileName, 1024);
//Brunni/ To be informed when the file changes
startCheckRoutine(name);
}
}
else
gblModeColorIt = 0;
} else {
int size = CPULoadRom(theApp.szFile);
if(!size)
@ -1238,7 +1255,8 @@ void MainWnd::OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized)
}
} else {
theApp.wasPaused = true;
if(theApp.pauseWhenInactive) {
//Brunni/ Always disable this in ColorIt debug mode
if(theApp.pauseWhenInactive && !gblConfigAutoShowCrc) {
if(emulating) {
soundPause();
}

View File

@ -45,7 +45,7 @@
#include "../Util.h"
#include "../dmg/gbGlobals.h"
#include "../dmg/gbPrinter.h"
#include "../Brunni/common.h"
/* Link
---------------------*/
#include "../agb/GBALink.h"
@ -2656,3 +2656,64 @@ void Sm60FPS_Sleep()
}
}
}
//Brunni/ Check when the configuration file is modified
void FileCheckThread(void* fname)
{
char *fileName;
char dirName[1024];
fileName = extractFilePath((char*)fname, dirName, 1);
HANDLE hDir = CreateFile((char*)dirName, // File name
FILE_LIST_DIRECTORY, // access (read/write) mode
FILE_SHARE_READ|FILE_SHARE_DELETE, // share mode
NULL, // security descriptor
OPEN_EXISTING, // how to create
FILE_FLAG_BACKUP_SEMANTICS, // file attributes
NULL // file with attributes to copy
);
FILE_NOTIFY_INFORMATION Buffer[1024];
DWORD BytesReturned;
while (ReadDirectoryChangesW(
hDir, // handle to directory
&Buffer, // read results buffer
sizeof(Buffer), // length of buffer
FALSE, // monitoring option
FILE_NOTIFY_CHANGE_SECURITY|
FILE_NOTIFY_CHANGE_CREATION|
FILE_NOTIFY_CHANGE_LAST_ACCESS|
FILE_NOTIFY_CHANGE_LAST_WRITE|
FILE_NOTIFY_CHANGE_SIZE|
FILE_NOTIFY_CHANGE_ATTRIBUTES|
FILE_NOTIFY_CHANGE_DIR_NAME|
FILE_NOTIFY_CHANGE_FILE_NAME, // filter conditions
&BytesReturned, // bytes returned
NULL, // overlapped buffer
NULL // completion routine
))
{
int i=0;
do {
CString str = CString(Buffer[i].FileName).Left(Buffer[i].FileNameLength / 2);
if (!str.Compare(fileName)) {
//C'est le bon fichier
if (Buffer[0].Action == FILE_ACTION_MODIFIED) {
gb_lastVramCrc = 0;
exiting_lcdc();
}
}
/* m_Sec.Lock();
int item = pList1->InsertItem(pList1->GetItemCount(), CString(Buffer[i].FileName).Left(Buffer[i].FileNameLength / 2) + " - " + helper_txt );
pList1->SetItemText(item, 1, tm.Format("%Y/%m/%d/ - %H:%M:%S"));*/
// m_Sec.Unlock();
} while (!Buffer[++i].NextEntryOffset);
}
}
void startCheckRoutine(char *fullFileName) {
//Begin checking for an update of the file
_beginthread(FileCheckThread, 0, fullFileName);
}