From c17fc7734af1033b20724152a6f41489ef67fc9e Mon Sep 17 00:00:00 2001 From: Diogo Autilio Date: Sat, 31 Aug 2024 22:50:46 -0300 Subject: [PATCH] Document oslib --- src/ccc.h | 13 +- src/oslib.h | 1249 ++++++++++++++++++++++++++++++++------------------- 2 files changed, 786 insertions(+), 476 deletions(-) diff --git a/src/ccc.h b/src/ccc.h index 2b9c7da..9710067 100644 --- a/src/ccc.h +++ b/src/ccc.h @@ -3,12 +3,13 @@ * @brief Header file for character code conversion functions in OSLib. * * This file provides macros that map to functions in BenHur's intraFont library for character code conversion. - * The functions allow for converting characters from various encodings to UCS2, setting error characters, - * and shutting down the Character Code Conversion Library. - * - * @defgroup CharacterCodeConversion Character Code Conversion (ccc) + * These functions enable converting characters from various encodings to UCS2, setting error characters, + * and managing the shutdown of the Character Code Conversion Library. + */ + +/** @defgroup CharacterCodeConversion Character Code Conversion (ccc) * - * Functions to convert characters from BenHur's intraFont. + * Functions for character code conversion using BenHur's intraFont library. * @{ */ @@ -104,7 +105,7 @@ extern "C" { */ #define oslCccShutDown cccShutDown -/** @} */ // end of Character Code Conversion +/** @} */ // end of Character Code Conversion (ccc) #ifdef __cplusplus } diff --git a/src/oslib.h b/src/oslib.h index 3bbb0a1..50dc1a3 100644 --- a/src/oslib.h +++ b/src/oslib.h @@ -1,17 +1,24 @@ -/*! \file oslib.h - \brief Main Oldschool Library file. -*/ +/** + * @file oslib.h + * @brief Main Oldschool Library header file. + * + * This header defines the main structures, macros, and functions used in the + * OldSchool Library (OSLib) framework. OSLib provides a comprehensive set of tools + * for developing applications on the PSP platform, including graphics, input handling, + * memory management, and more. This file includes both general utility functions + * and platform-specific implementations for the PSP. + */ #ifndef _OSLIB_H_ #define _OSLIB_H_ #ifdef PSP - #include - #include - #include + #include + #include + #include #else - #define _CRT_SECURE_NO_DEPRECATE - #include "emu.h" + #define _CRT_SECURE_NO_DEPRECATE + #include "emu.h" #endif #include #include @@ -21,571 +28,873 @@ #include #include #ifdef PSP - #include - #include - #include - #include - #include - #include - #include + #include + #include + #include + #include + #include + #include + #include #endif #ifdef __cplusplus extern "C" { #endif - -/** @defgroup main Main - - Main OSLib section. - @{ -*/ - -/** @defgroup main_general General - - Contains general routines to initialize and terminate the library. - @{ -*/ - -/** OSLib version */ +/** + * @defgroup main Main + * @brief Main OSLib section. + * + * This section contains the core functionalities of OSLib, including initialization, + * termination, and synchronization routines. It also includes various utility functions + * and definitions that are commonly used throughout the library. + * @{ + */ + +/** + * @defgroup main_general General + * @brief General routines to initialize and terminate the library. + * + * These functions are responsible for setting up and tearing down the OSLib environment. + * Initialization typically involves configuring system settings and allocating necessary + * resources, while termination handles cleanup and resource deallocation. + * @{ + */ + +/** @brief OSLib version. */ #define OSL_VERSION "1.2.0" -extern int osl_intraInit; - -/** Initializes the library. The options for the flags parameters are for advanced users only, let it to zero if you're beginning. - - \param flags - Can be formed of one or more of the values from the #OSL_INITFLAGS enumeration (ORed together). -*/ +/** @brief Initializes the library. + * + * This function initializes the OSLib environment. The flags parameter is used + * to control specific initialization options, which are primarily intended for + * advanced users. + * + * @param flags Can be formed of one or more of the values from the + * \ref OSL_INITFLAGS enumeration (ORed together). + */ extern void oslInit(int flags); -/** Flags for oslInit. */ -enum OSL_INITFLAGS { - OSL_IF_USEOWNCALLBACKS=1, //!< Does not set up the standard callbacks. You'll have to provide them by yourself as shown in almost all PSPSDK samples. - OSL_IF_NOVBLANKIRQ=2, //!< Does not reserve the VBLANK IRQ. You should set up your own VBL handler, which should call oslVblankNextFrame() if osl_vblankCounterActive is TRUE, else oslSyncFrame(Ex) will not work properly. +/** @brief Flags for oslInit function. + * + * These flags control specific aspects of the initialization process. + */ +enum OSL_INITFLAGS { + OSL_IF_USEOWNCALLBACKS = 1, /*!< Do not set up the standard callbacks. You'll have to provide them by yourself as shown in almost all PSPSDK samples. */ + OSL_IF_NOVBLANKIRQ = 2 /*!< Do not reserve the VBLANK IRQ. You should set up your own VBL handler, which should call oslVblankNextFrame() if osl_vblankCounterActive is TRUE, else oslSyncFrame(Ex) will not work properly. */ }; -/** Exits the application immediately, returning to the XMB (PSP main menu) or to the calling application (e.g. IRShell). -*/ +/** @brief Exits the application immediately. + * + * This function terminates the application and returns to the XMB (PSP main menu) or + * to the calling application (e.g., IRShell). + */ extern void oslQuit(); -/** Sets the "no fail" mode. In this mode, if OSLib can't load a file (for example an image) it will display a gentleful message indicating to the user the name of the missing file, and quit immediately. - -\code -//Our objects (will be loaded) -OSL_IMAGE *img; -OSL_FONT *font; -OSL_SOUND *sound; - -//Initialize OSLib -oslInit(0); -//Set-up drawing on a 5650 (16-bit) screen -oslInitGfx(OSL_PF_5650, 1); -//Enable the no-fail feature -oslSetQuitOnLoadFailure(1); - -//An error will be displayed if any of these files could not be loaded properly. -image = oslLoadImageFilePNG("test.png", OSL_IN_RAM | OSL_SWIZZLED, OSL_PF_5551); -font = oslLoadFontFile("font.oft"); -sound = oslLoadSoundFileWAV("noise.wav", OSL_FMT_NONE); - -//Here, we are sure everything is okay, we don't even need checking if they are NULL. -oslSetFont(font); -oslDrawImage(img); -oslPlaySound(sound, 0); -\endcode */ -#define oslSetQuitOnLoadFailure(enabled) (osl_noFail = (enabled)) - -/** Sets the function to call in case of failure to load something. Default displays a message box. - -\code -//Our own function called when a loading has failed -void MyNoFailCallback(const char *filename, u32 reserved) { - //Display an error - myDisplayMessage("Unable to locate the following file: %s\nPlease reinstall the application.", filename); - //Always quit because we can't continue without these precious files - oslQuit(); -} - -//Set-up no-fail. -oslSetQuitOnLoadFailure(1); -oslSetQuitOnLoadFailureCallback(MyNoFailCallback); -//This function will call MyNoFailCallback because the specified file doesn't exist -oslLoadImageFileJPG("void:/notexisting.xyz", OSL_IN_RAM, OSL_PF_4BIT); -\endcode -*/ -#define oslSetQuitOnLoadFailureCallback(function) (osl_noFailCallback = function) - -/** Sets an exit callback. This function is executed when the user chooses "Exit" from the HOME menu. By default, all what OSLib does is set osl_quit to True, so that you -know that you should quit (all your game loops should watch out for osl_quit). A typical but dirty callback may be to force quitting immediately using oslQuit. Example: - -\code -int myExitCallback(int arg1, int arg2, void *common) -{ - oslQuit(); - return 0; -} - -void main() { - oslSetExitCallback(myExitCallback); - while(1); -} -\endcode */ -#define oslSetExitCallback(function) (osl_exitCallback = function) - +/** @brief Sets the "no fail" mode. + * + * In this mode, if OSLib cannot load a file (for example, an image), it will display a + * message indicating the name of the missing file and then quit immediately. + * + * @param enabled Enables or disables the no-fail feature. + */ +#define oslSetQuitOnLoadFailure(enabled) (osl_noFail = (enabled)) + +/** @brief Sets the function to call in case of failure to load something. + * + * The default behavior is to display a message box. This function allows you to + * override that behavior with your custom function. + * + * @param function Function pointer to be called on load failure. + */ +#define oslSetQuitOnLoadFailureCallback(function) (osl_noFailCallback = function) + +/** @brief Sets an exit callback. + * + * This function is executed when the user chooses "Exit" from the HOME menu. + * By default, this callback sets osl_quit to true, indicating that the application + * should quit. You can provide your custom callback function to handle the exit process. + * + * @param function Function pointer to be executed as the exit callback. + */ +#define oslSetExitCallback(function) (osl_exitCallback = function) + +/** + * @brief Indicates if the internal initialization process of OSLib is complete. + * + * This variable is used internally by OSLib to track the state of the library's initialization. + * It is set to 1 when the initialization is complete and 0 otherwise. + */ +extern int osl_intraInit; -//Don't access these +/** + * @brief Controls the "no fail" mode in OSLib. + * + * This variable is used to enable or disable the "no fail" mode, which automatically + * quits the application with an error message if a file cannot be loaded. + * + * - 0: "No fail" mode is disabled. + * - 1: "No fail" mode is enabled. + */ extern int osl_noFail; + +/** + * @brief Pointer to the callback function used when a file load operation fails in "no fail" mode. + * + * This function is called whenever a file fails to load while "no fail" mode is enabled. + * The callback function receives the name of the file that failed to load and a reserved + * parameter that can be used for additional context. + * + * @param filename The name of the file that failed to load. + * @param reserved Reserved parameter for additional context (usually not used). + */ extern void (*osl_noFailCallback)(const char *filename, u32 reserved); + +/** + * @brief Handles errors when a file fails to load in "no fail" mode. + * + * This function is called internally by OSLib when a file fails to load and "no fail" mode + * is enabled. It invokes the callback function specified by `osl_noFailCallback` if one is set, + * or displays a default error message and quits the application. + * + * @param filename The name of the file that failed to load. + */ extern void oslHandleLoadNoFailError(const char *filename); /** @} */ // end of main_general - -/** @defgroup main_sync Synchronization - - Contains routines for synchronizing your game. - @{ -*/ - -/** Sets the current fix frameskipping value. - \param val - 1 = enables auto frameskip - 2 or more: enables fixed skipping (val-1 frames out of val are skipped) -*/ +/** + * @defgroup main_sync Synchronization + * @brief Synchronization routines for your game. + * + * These functions are used to synchronize the game's frame rate and ensure smooth + * rendering and input handling. They include functions for managing frame skipping + * and VSync. + * @{ + */ + +/** @brief Sets the current fixed frameskipping value. + * + * @param val 1 enables auto frameskip, 2 or more enables fixed skipping + * (val-1 frames out of val are skipped). + */ #define oslSetFrameskip(val) (osl_frameskip = val) -/** Sets the maximum frameskip value. If you set a too high value, the game may become unusable when lagging, if you set a too low value, frameskip is no more useful. -*/ + +/** @brief Sets the maximum frameskip value. + * + * @param val Maximum frameskip value. + */ #define oslSetMaxFrameskip(val) (osl_maxFrameskip = val) -/** Sets the VSync parameter. - \param val - 0: Automatic VSync (enabled if the game is not lagging). - 1: VSync always enabled. - +4: If you add 4, with a frameskip > 1, synchronizes to the wanted framerate, e.g. 2 -> 30 fps (DON'T USE THIS ANYMORE) - +0: Else, fixes the minimum frameskip (e.g. 2: the game will run at 60 fps, 30 images per second, that is one frame out of two is skipped) - +8: Alternative synchronization method without VSync - +16: Do not swap buffers. Handy if you want temporary to "disable double buffering". -*/ + +/** @brief Sets the VSync parameter. + * + * @param val VSync parameter value. + */ #define oslSetVSync(val) (osl_vsyncEnabled = val) -/** Synchronization. Call it to the end of a frame. A frame is one step when animating your game. The PSP LCD refreshes at 60 images per second (and thus, you'll have to generate 60 frames per second). - This function uses the frameskip & vsync parameters defined above. - \return - A boolean value indicating if you're in late. - - Note: When you're indicated to be in late, you should skip the rendering to speed up things, else your game will slow down. Usually the whole render is surrounded by a "if (!skip)" block, and when - skip is true, the render is completely skipped. Skip is the return value from oslSyncFrame. - - Here is the structure of an automatically frameskipped program: -\code -//This variable holds whether a frame should be skipped or not -int skip = 0; -//Enable frameskipping, 0 frame out of 1 is skipped by default (60 fps) -oslSetFrameskip(1); -//But skip a maximum of 3 frames out of 4, else the game seems very laggy -oslSetMaxFrameskip(4); - -//Our main loop -while(1) { - //If skip is 1, then we should skip rendering to speed up things - if (!skip) { - //Begin drawing - oslStartDrawing(); - //We can now draw as much as we want - oslDrawFillRect(0, 0, 100, 100, RGBA(0, 0, 255, 128)); - oslDrawString(0, 0, "Hello!"); - //We have now finished with drawing - oslEndDrawing(); - } - - //End of a frame - oslEndFrame(); - //Synchronize to ensure the game runs at 60 fps - skip = oslSyncFrame(); -} -\endcode -*/ -#define oslSyncFrame() oslSyncFrameEx(osl_frameskip,osl_maxFrameskip,osl_vsyncEnabled) -/** Call this function when a frame has ended, just before a call to oslSyncFrame or oslWaitVSync or anything. -\b Important: If you are calling this function, you do not need to call #oslAudioVSync anymore. Newer programs should always call #oslEndFrame instead. */ +/** @brief Synchronization function to be called at the end of a frame. + * + * This function synchronizes the frame rate based on the current frameskip and VSync settings. + * + * @return A boolean value indicating if the game is running late. + */ +#define oslSyncFrame() oslSyncFrameEx(osl_frameskip, osl_maxFrameskip, osl_vsyncEnabled) + +/** @brief Call this function when a frame has ended. + * + * This function should be called just before calling oslSyncFrame or oslWaitVSync. + * It handles audio synchronization and other end-of-frame tasks. + */ extern void oslEndFrame(); - -/** This variable is set to TRUE to indicate the application should exit (happens when the user pressed HOME and selected Yes). You should always keep an eye on this variable, clean up everything and -then quit when this variable has become TRUE. */ +/** + * @brief Indicates whether the application should exit. + * + * This variable is set to 1 when the user chooses "Exit" from the HOME menu, + * signaling that the application should clean up resources and quit. + * Game loops should monitor this variable and exit gracefully when it is set to 1. + */ extern int osl_quit; -//Document these +/** + * @brief Controls whether standby mode is permitted. + * + * This variable can be set to 1 to prevent the PSP from entering standby mode. + * If set to 0, standby mode is allowed. + */ extern int osl_standByUnpermitted; -extern int (*osl_powerCallback)(int, int, void*); -extern int (*osl_exitCallback)(int, int, void*); -extern int osl_vblInterruptNumber; //Num�ro de l'interruption VBLANK utilis�e -//Don't access these -extern int osl_maxFrameskip, osl_vsyncEnabled, osl_frameskip; -extern volatile int osl_vblCount, osl_vblCallCount, osl_vblankCounterActive, osl_skip; +/** + * @brief Pointer to the power callback function. + * + * This function is called when a power event occurs, such as low battery, + * power switch action, or other power-related events. The callback receives + * three parameters: two integers and a void pointer for user-defined data. + * + * @param arg1 First argument, typically indicating the type of power event. + * @param arg2 Second argument, providing additional context or flags related to the event. + * @param common A pointer to user-defined data, typically passed when setting up the callback. + * + * @return Typically returns 0, but the return value may be used to influence power event handling. + */ +extern int (*osl_powerCallback)(int arg1, int arg2, void* common); + +/** + * @brief Pointer to the exit callback function. + * + * This function is executed when the user chooses "Exit" from the HOME menu. By default, + * it sets `osl_quit` to 1. You can override this function to handle exit events in a custom way. + * + * @param arg1 First argument, usually indicating the reason for the exit request. + * @param arg2 Second argument, providing additional context or flags related to the exit request. + * @param common A pointer to user-defined data, typically passed when setting up the callback. + * + * @return Typically returns 0, but the return value may be used to influence exit event handling. + */ +extern int (*osl_exitCallback)(int arg1, int arg2, void* common); + +/** + * @brief The interrupt number for the VBLANK interrupt. + * + * This variable stores the number of the VBLANK interrupt used by OSLib. + * It is generally set during initialization and used to manage frame synchronization. + */ +extern int osl_vblInterruptNumber; + +/** + * @brief Maximum allowed frameskip value. + * + * This variable determines the maximum number of frames that can be skipped + * to maintain a stable frame rate. A higher value may result in a less smooth + * visual experience but can help the game maintain its target frame rate. + */ +extern int osl_maxFrameskip; + +/** + * @brief Indicates whether VSync is enabled. + * + * This variable controls the VSync setting for the application. When VSync is enabled, + * the rendering process is synchronized with the screen refresh rate to prevent screen tearing. + */ +extern int osl_vsyncEnabled; + +/** + * @brief Current frameskip setting. + * + * This variable determines how many frames should be skipped between rendering + * frames. A value of 1 disables frameskipping, while higher values increase the number + * of frames skipped, potentially improving performance at the cost of smoothness. + */ +extern int osl_frameskip; + +/** + * @brief Count of VBLANK interrupts. + * + * This volatile variable tracks the number of VBLANK interrupts that have occurred. + * It is used internally to synchronize rendering with the display's refresh rate. + */ +extern volatile int osl_vblCount; + +/** + * @brief Count of VBLANK interrupt calls. + * + * This volatile variable tracks the number of times the VBLANK interrupt has been handled. + * It is used to ensure that the application correctly responds to each interrupt. + */ +extern volatile int osl_vblCallCount; + +/** + * @brief Indicates if the VBLANK counter is active. + * + * This volatile variable is set to 1 when the VBLANK counter is actively tracking + * VBLANK interrupts. It is used internally by OSLib for frame synchronization. + */ +extern volatile int osl_vblankCounterActive; + +/** + * @brief Indicates whether the current frame should be skipped. + * + * This volatile variable is used internally to determine if rendering for the current + * frame should be skipped based on the frameskip settings and current performance. + */ +extern volatile int osl_skip; + +/** + * @brief Current framerate setting. + * + * This volatile variable stores the current target framerate, typically set to 60 for a + * standard PSP display. It can be modified to simulate different framerates, such as 50 for PAL games. + */ extern volatile int osl_currentFrameRate; -/** Same as oslSyncFrame but with all parameters set in one call. This method is a bit cleaner because the other one stores parameters in global variables and oslSyncFrame calls oslSyncFrameEx with them -as arguments. */ +/** @brief Synchronization function with explicit parameters. + * + * This function is similar to oslSyncFrame but allows you to pass all synchronization + * parameters directly in one call. + * + * @param frameskip Frameskip value. + * @param max_frameskip Maximum frameskip value. + * @param vsync VSync parameter. + * + * @return A boolean value indicating if the game is running late. + */ extern int oslSyncFrameEx(int frameskip, int max_frameskip, int vsync); -/** Sets the framerate for oslSyncFrame(Ex). This can be any value from 1 to 60. For example, use 50 to simulate a PAL (european) game. */ -static inline void oslSetFramerate(int framerate) { - if (framerate <= 60) - osl_currentFrameRate = framerate; +/** @brief Sets the framerate for oslSyncFrame(Ex). + * + * This can be any value from 1 to 60. For example, use 50 to simulate a PAL (European) game. + * + * @param framerate Desired framerate. + */ +static inline void oslSetFramerate(int framerate) { + if (framerate <= 60) + osl_currentFrameRate = framerate; } -/** Waits for the VSync (60 times per second), synchronizing your game. This is a simplier and less efficient method than oslSyncFrame. */ +/** @brief Waits for the VSync, synchronizing your game. + * + * This function is a simpler and less efficient method than oslSyncFrame. + */ extern void oslWaitVSync(); /** @} */ // end of main_sync - -/** @defgroup main_memory Memory - - Contains routines about memory (cache, copy, etc.). - @{ -*/ - -/** Copies data using the internal DMAC. Should be faster than a memcpy, but requires that data to be copied is no more in the cache, so usually you should issue a oslUncacheData on the source and -destination addresses else very strange bugs may happen. */ -extern int sceDmacMemcpy(void *dest, const void *source, unsigned int size); //Copie DMA -/** Same as sceDmacMemcpy. */ +/** + * @defgroup main_memory Memory + * @brief Memory management routines. + * + * This section includes functions and macros for managing memory in OSLib, including + * cache management, memory copying, and alignment. + * @{ + */ + +/** @brief Copies data using the internal DMAC. + * + * This function is generally faster than memcpy but requires that the data to be copied + * is no longer in the cache. + * + * @param dest Destination address. + * @param source Source address. + * @param size Size of the data to be copied. + * + * @return Result of the DMA copy operation. + */ +extern int sceDmacMemcpy(void *dest, const void *source, unsigned int size); + +/** @brief Same as sceDmacMemcpy. + * + * This function is identical to sceDmacMemcpy but may be less reliable. + * + * @param dest Destination address. + * @param source Source address. + * @param size Size of the data to be copied. + * + * @return Result of the DMA copy operation. + */ extern int sceDmacTryMemcpy(void *dest, const void *source, unsigned int size); -/** Does a memset using the 64-bit capabilities of the CPU. Faster than memcpy. */ -extern void oslFasterMemset(u64 *dst, u64 *src, u32 length); - -/** This routine will make sure that the data will no more reside in the CPU cache. The CPU does automatically put data in cache when you want to read or write to it, making subsequent accesses faster -(because the cache is way faster than conventional RAM). The problem is that if the GE (graphic processor) for example wants to access it, it will read the real memory, and thus if some data is still -sitting in the cache (not written to actual RAM yet) the GE will get incorrect data, making it crash or display corrupt graphics. - -To avoid problems, you can either bypass the cache by writting to uncached addresses (oslGetUncachedPtr) or by flushing the data from cache before sending them to the GE (or DMA). This function, -oslUncacheData, will flush the actual data from cache, writing it to real memory. This does take some time so don't abuse and call it only when necessary. - - \param data - Adress of the memory area to flush. - \param size - Size (in bytes) of the area. - -Uncaching should be done after you've accessed raw image / palette / something contents. This includes oslSetImagePixel and accesses to the raw image data pointed to by OSL_IMAGE::data. -Note: There are specific functions to uncache palettes and images, simplier to use. You should rather use them instead. -*/ -#define oslUncacheData(data,size) sceKernelDcacheWritebackInvalidateRange(data, size); - -/** Returns a pointer to an uncached address. In this case, cache will be bypassed and you'll not have to call oslUncache[something] after modifying data. However performance is usually worse and caching -is a good thing, so do it if you know what you are doing. +/** @brief Does a memset using the 64-bit capabilities of the CPU. + * + * This function is faster than memcpy for certain operations. + * + * @param dst Destination address. + * @param src Source address. + * @param length Length of the data to be set. + */ +extern void oslFasterMemset(u64 *dst, u64 *src, u32 length); -Important: NEVER mix cached and uncached addresses when accessing somewhere. Either always access them as cached or unached. If you mix them some weird bugs may appear -because you could for example write directly in memory bypassing the cache, but some data is still sitting in the cache. So, once the cache is full, data will be flushed and written to the memory, replacing the -data you wrote in an uncached way. You will not understand why your data gets corrupted, and as this will maybe happen seconds later in special circumstances, so it will be impossible to detect or -debug. */ -#define oslGetUncachedPtr(adr) ((void*)((int)(adr)|0x40000000)) -/** Get a pointer to cached data. Same remark as above. */ -#define oslGetCachedPtr(adr) ((void*)((int)(adr)&(~0x40000000))) +/** @brief Ensures that the data is no longer in the CPU cache. + * + * This function flushes the cache, writing the data to the actual memory. + * + * @param data Address of the memory area to flush. + * @param size Size (in bytes) of the area. + */ +#define oslUncacheData(data, size) sceKernelDcacheWritebackInvalidateRange(data, size); + +/** @brief Returns a pointer to an uncached address. + * + * This function allows you to bypass the cache, but it is generally less efficient + * than using cached addresses. + * + * @param adr Cached address. + * + * @return Uncached pointer. + */ +#define oslGetUncachedPtr(adr) ((void*)((int)(adr) | 0x40000000)) + +/** @brief Returns a pointer to cached data. + * + * This function allows you to revert to using cached addresses. + * + * @param adr Uncached address. + * + * @return Cached pointer. + */ +#define oslGetCachedPtr(adr) ((void*)((int)(adr) & (~0x40000000))) #ifdef PSP - /** Flushes the whole cache. This is slow, absolutely avoid it! Use oslUncacheData instead if possible. */ - extern void oslFlushDataCache(); + /** @brief Flushes the whole cache. + * + * This function is slow and should be avoided if possible. + * Use oslUncacheData instead when appropriate. + */ + extern void oslFlushDataCache(); #else - extern void oslFlushDataCache(); + /** @brief Flushes the whole cache. + * + * This function is slow and should be avoided if possible. + * Use oslUncacheData instead when appropriate. + */ + extern void oslFlushDataCache(); #endif -/** Allocates a memory block, ensuring it is aligned. - \param alignment - Alignment in bytes - \param size - Size of the block -*/ +/** @brief Allocates a memory block, ensuring it is aligned. + * + * This function allocates memory with a specified alignment. + * + * @param alignment Alignment in bytes. + * @param size Size of the block. + * + * @return Pointer to the allocated memory block. + */ void *memalign(size_t alignment, size_t size); -/** Structure for the return value of oslGetRamStatus. */ -typedef struct { - int maxAvailable; //!< Maximum available memory - int maxBlockSize; //!< Maximum linear memory available +/** @brief Structure for the return value of oslGetRamStatus. + * + * This structure contains information about the available memory. + */ +typedef struct { + int maxAvailable; /*!< Maximum available memory */ + int maxBlockSize; /*!< Maximum linear memory available */ } OSL_MEMSTATUS; -/** Gets info about currently available memory in main RAM. The return value is a #OSL_MEMSTATUS -structure which contains info about available memory. - -Example: -\code - //You can either store the result to a structure and access its members - OSL_MEMSTATUS ram = oslGetRamStatus(); - oslDebug("%i bytes available", ram.maxAvailable); - - //Or directly use the return value from the function, like this - oslDebug("%i bytes available", oslGetRamStatus().maxAvailable); -\endcode - -\b Note: About the example above, just notice that each call to oslGetRamStatus costs a lot of time, so if you need to -retrieve several results (e.g. both maxAvailable and maxBlockSize) you should not use the second method as it will need two -calls to oslGetRamStatus. */ +/** @brief Gets info about currently available memory in main RAM. + * + * This function returns an OSL_MEMSTATUS structure with information about + * the available memory. + * + * @return OSL_MEMSTATUS structure containing available memory info. + */ OSL_MEMSTATUS oslGetRamStatus(); /** @} */ // end of main_memory - -/** @defgroup main_maths Maths - - Main OSLib section. Contains the main routines to initialize and terminate the library. - @{ -*/ - -/** Returns the absolute value of a number (that is, the positive part of the number). - -\code -//Prints 2 -oslPrintf("%i", oslAbs(2)); -//Prints 2 as well (the minus sign is ignored in an absolute value) -oslPrintf("%i", oslAbs(-2)); -\endcode */ -#define oslAbs(x) (((x)<0)?(-(x)):(x)) - -/** Returns the smallest value between the two. */ -#define oslMin(x, y) (((x)<(y))?(x):(y)) -/** Returns the greatest value between the two. - -\code -//Move the object 1 pixel to the left but make sure it will never go beyond the left corner of the screen. -posX = oslMax(posX - 1, 0); -\endcode */ -#define oslMax(x, y) (((x)>(y))?(x):(y)) -/** Returns a value clamped between a minimum and maximum. - -\code -int addColor(int colValue, int addValue) { - //We add addValue to colValue, but we must check the color component is always between 0 and 255. - colValue = oslMinMax(colValue + addValue, 0, 255); - return colValue; -} -\endcode */ -#define oslMinMax(x, min, max) ((x) < (max) ? ((x) > (min) ? (x) : (min)) : (max)) - -/** Returns the number of objects in an array. - -\code -OSL_VIRTUALFILENAME ram_files[] = { - {"ram:/file1.jpg", (void*)file1_jpg, file1_jpg_size, &VF_MEMORY}, - {"ram:/file2.png", (void*)file2_png, file2_png_size, &VF_MEMORY}, -}; - -//This will display 2, as 2 elements are contained in the table ram_files. -oslPrintf("%i", oslNumberof(ram_files)); -\endcode */ -#define oslNumberof(n) (sizeof(n)/sizeof(*(n))) - -/** Calculates the sine of an angle in degrees multiplicated by a radius. Returns the result as a float. oslSin and oslCos use the VFPU to compute the result, and thus it's very fast and very precise. - \param angle - Angle in degrees (360� means a full circle) - \param dist - Radius of the circle - \return - sin(angle * PI / 180) * dist - -\code -//Character coordinates -float cX, cY; -//Character speed -float cSpeed; -//Character angle -float cAngle; - -//Move the character depending on its instant speed and angle -cX += oslCos(cAngle, cSpeed); -//In mathematics, positive y coordinates are directed upwards, in informatics it's directed -//downwards, as if we were writing on a sheet of paper, so we need to substract the sine. -cY -= oslSin(cAngle, cSpeed); -\endcode -*/ +/** + * @defgroup main_maths Maths + * @brief Mathematical functions. + * + * This section provides mathematical utilities, such as trigonometric functions, + * commonly used in game development. + * @{ + */ + +/** @brief Returns the absolute value of a number. + * + * This function returns the positive part of the number. + * + * @param x Input value. + * + * @return Absolute value of the input. + */ +#define oslAbs(x) (((x) < 0) ? (-(x)) : (x)) + +/** @brief Returns the smallest value between the two. + * + * This function returns the smaller of the two provided values. + * + * @param x First value. + * @param y Second value. + * + * @return Smallest value. + */ +#define oslMin(x, y) (((x) < (y)) ? (x) : (y)) + +/** @brief Returns the greatest value between the two. + * + * This function returns the larger of the two provided values. + * + * @param x First value. + * @param y Second value. + * + * @return Greatest value. + */ +#define oslMax(x, y) (((x) > (y)) ? (x) : (y)) + +/** @brief Returns a value clamped between a minimum and maximum. + * + * This function ensures that the provided value is within the specified range. + * + * @param x Input value. + * @param min Minimum value. + * @param max Maximum value. + * + * @return Clamped value. + */ +#define oslMinMax(x, min, max) ((x) < (max) ? ((x) > (min) ? (x) : (min)) : (max)) + +/** @brief Returns the number of objects in an array. + * + * This function calculates the number of elements in an array. + * + * @param n Array. + * + * @return Number of elements in the array. + */ +#define oslNumberof(n) (sizeof(n) / sizeof(*(n))) + +/** @brief Calculates the sine of an angle in degrees multiplied by a radius. + * + * This function returns the sine of the specified angle, multiplied by the provided radius. + * + * @param angle Angle in degrees. + * @param dist Radius of the circle. + * + * @return Sine of the angle multiplied by the radius. + */ extern float oslSin(float angle, float dist); -/** Calculates the cosine of an angle in degrees multiplicated by a radius. Returns the result as a float. - \param angle - Angle in degrees (360� means a full circle) - \param dist - Radius of the circle - \return - cos(angle * PI / 180) * dist -*/ -extern float oslCos(float angle, float dist); -/** Returns the sine of an angle in degrees (0 to 360) multiplicated by an integer radius. Returns the result as an integer. These routines use a precalculated lookup table to compute the result. -Don't think oslSini and oslCosi are much faster than oslSin and oslCos, it's not the case. +/** @brief Calculates the cosine of an angle in degrees multiplied by a radius. + * + * This function returns the cosine of the specified angle, multiplied by the provided radius. + * + * @param angle Angle in degrees. + * @param dist Radius of the circle. + * + * @return Cosine of the angle multiplied by the radius. + */ +extern float oslCos(float angle, float dist); -\code -//This code draws a line in a circle which has a radius of 20 pixels. You can play with the angle to move the line. -int angle = 40, radius = 20; -//Draw our line. Same remark as for oslSin applies. -oslDrawLine(240, 136, 240 + oslCosi(angle, radius), 136 - oslSini(angle, radius)); -\endcode */ +/** @brief Returns the sine of an angle in degrees (0 to 360) multiplied by an integer radius. + * + * This function uses a lookup table for faster computation. + * + * @param angle Angle in degrees. + * @param dist Radius of the circle. + * + * @return Sine of the angle multiplied by the radius. + */ extern int oslSini(int angle, int dist); -/** Returns the cosine of an angle in degrees (0 to 360) multiplicated by an integer radius. Returns the result as an integer. */ -extern int oslCosi(int angle, int dist); -/** Returns the next (upper) power of two of a number. +/** @brief Returns the cosine of an angle in degrees (0 to 360) multiplied by an integer radius. + * + * This function uses a lookup table for faster computation. + * + * @param angle Angle in degrees. + * @param dist Radius of the circle. + * + * @return Cosine of the angle multiplied by the radius. + */ +extern int oslCosi(int angle, int dist); -\code -//Prints 256, as 256 = 2^8 (2^7 = 128, too low). -oslPrintf("%i", oslGetNextPower2(200); -\endcode */ +/** @brief Returns the next (upper) power of two of a number. + * + * This function calculates the next power of two that is greater than or equal to the input value. + * + * @param val Input value. + * + * @return Next power of two. + */ extern int oslGetNextPower2(int val); -//Don't access these! -//extern float osl_fsinus[361]; -//extern float osl_fcosinus[361]; +/** + * @brief Precomputed sine values for angles from 0 to 360 degrees. + * + * This array contains the precomputed sine values for each degree from 0 to 360. + * The values are scaled to a fixed-point format for faster computation in integer-based + * operations. This array is used by functions like `oslSini` for efficient trigonometric + * calculations without needing to compute sine values at runtime. + * + * @note The array index corresponds directly to the angle in degrees. + */ extern int osl_isinus[361]; + +/** + * @brief Precomputed cosine values for angles from 0 to 360 degrees. + * + * This array contains the precomputed cosine values for each degree from 0 to 360. + * Like `osl_isinus`, the values are scaled to a fixed-point format for efficient integer-based + * operations. This array is used by functions like `oslCosi` to quickly obtain cosine values + * without runtime computation. + * + * @note The array index corresponds directly to the angle in degrees. + */ extern int osl_icosinus[361]; + +/** + * @brief Sets up the floating-point trigonometric tables. + * + * This function initializes internal trigonometric tables that are used for floating-point + * trigonometric calculations. It must be called during the setup process of OSLib before + * any floating-point trigonometric functions are used. + * + * @note This setup is necessary for functions like `oslSin` and `oslCos` to work properly. + */ extern void oslSetupFTrigo(); /** @} */ // end of main_maths -/** @defgroup main_debug Debug console - - Debugging features. - @{ -*/ +/** + * @defgroup main_debug Debug console + * @brief Debugging features. + * + * This section includes functions and macros for debugging, such as printing + * formatted text to the screen and controlling the debug console. + * @{ + */ #ifdef PSP - /** Prints formatted text to the current position of the cursor. The format system is the same as printf (you can find the description in every good C tutorial or documentation). */ - #define oslPrintf(format...) ({ char __str[1000]; sprintf(__str , ##format); oslConsolePrint(__str); }) - /** Prints formatted text at a specific position on the screen. -\code -//Display the value of a variable on the top-left screen corner -oslPrintf_xy(0, 0, "Frame: %i", frameNumber); -\endcode */ - #define oslPrintf_xy(x,y, str, format...) ({ osl_consolePosX=x, osl_consolePosY=y; \ - oslPrintf(str,##format); }) + /** @brief Prints formatted text to the current position of the cursor. + * + * This macro uses a format string similar to printf. + * + * @param format Formatted text. + */ + #define oslPrintf(format...) ({ char __str[1000]; sprintf(__str, ##format); oslConsolePrint(__str); }) + + /** @brief Prints formatted text at a specific position on the screen. + * + * This macro prints formatted text at the specified screen coordinates. + * + * @param x X-coordinate (in characters). + * @param y Y-coordinate (in characters). + * @param str Formatted string. + * @param format Additional formatted text. + */ + #define oslPrintf_xy(x, y, str, format...) ({ osl_consolePosX = x; osl_consolePosY = y; oslPrintf(str, ##format); }) #else - #define oslPrintf(...) { char __str[1000]; sprintf(__str , __VA_ARGS__); oslConsolePrint(__str); } - #define oslPrintf_xy(x,y, ...) { osl_consolePosX=x, osl_consolePosY=y; \ - oslPrintf(__VA_ARGS__); } + #define oslPrintf(...) { char __str[1000]; sprintf(__str, __VA_ARGS__); oslConsolePrint(__str); } + #define oslPrintf_xy(x, y, ...) { osl_consolePosX = x; osl_consolePosY = y; oslPrintf(__VA_ARGS__); } #endif -/** Clears the screen (to black) and resets the cursor to the top-left corner of the screen. - -\code -oslCls(); -oslPrintf("Welcome...\n"); -\endcode */ -#define oslCls() (oslClearScreen(0), oslMoveTo(0,0)) -/** Moves the cursor to a place on the screen. The x, y coordinates are indicated in terms of characters (by default 8x8 pixels, but depends on the current font). */ -#define oslMoveTo(x,y) (osl_consolePosX=x*osl_sceFont->charWidths['0'], osl_consolePosY=y*osl_sceFont->charHeight) +/** @brief Clears the screen (to black) and resets the cursor to the top-left corner of the screen. + * + * This macro clears the screen and moves the cursor to the origin. + */ +#define oslCls() (oslClearScreen(0), oslMoveTo(0, 0)) + +/** @brief Moves the cursor to a place on the screen. + * + * This macro moves the cursor to the specified screen coordinates, using character units. + * + * @param x X-coordinate (in characters). + * @param y Y-coordinate (in characters). + */ +#define oslMoveTo(x, y) (osl_consolePosX = x * osl_sceFont->charWidths['0'], osl_consolePosY = y * osl_sceFont->charHeight) /** @} */ // end of main_debug - -/** @defgroup main_misc Miscellaneous - - Miscellaneous. - @{ -*/ -/** Does a benchmark action. - \param startend - - OSL_BENCH_INIT: Initialize the benchmark (done at beginning by OSLib) - - OSL_BENCH_START: Start the measure from here - - OSL_BENCH_END: End of a benchmark - - OSL_BENCH_GET: Get the value (milliseconds between the call to start and end - - OSL_BENCH_DISPLAY: Avoid - \param slot - 0-3: User slots - 4-7: System slots (4 contains the CPU load in percent if you multiply its value by 6 and divide by 1000) - - \return - The time elapsed between start and end in microseconds. -*/ -extern int oslBenchmarkTestEx(int startend, int slot); //Permet de choisir un slot (0-3: user, 4:7: system) -/** Same as oslBenchmarkTestEx but does a mean of 20 samples before returning a value. */ -extern int oslMeanBenchmarkTestEx(int startend, int slot); //Benchmark syst�me sur une moyenne de 20 �chantillons -/** Does a benchmark in the slot 0. Easier for testing. */ -static inline int oslBenchmarkTest(int startend) { - return oslBenchmarkTestEx(startend, 0); +/** + * @defgroup main_misc Miscellaneous + * @brief Miscellaneous utilities. + * + * This section includes various utility functions and definitions that do not fall + * under other categories. + * @{ + */ + +/** @brief Does a benchmark action. + * + * This function performs a benchmarking action, such as starting or stopping a benchmark, + * or retrieving the elapsed time. + * + * @param startend Benchmark action type (e.g., OSL_BENCH_START, OSL_BENCH_END). + * @param slot Benchmark slot (0-3 for user, 4-7 for system). + * + * @return Time elapsed between start and end in microseconds. + */ +extern int oslBenchmarkTestEx(int startend, int slot); + +/** @brief Same as oslBenchmarkTestEx but does a mean of 20 samples before returning a value. + * + * This function performs a benchmarking action and returns the mean of 20 samples. + * + * @param startend Benchmark action type. + * @param slot Benchmark slot. + * + * @return Mean benchmark value. + */ +extern int oslMeanBenchmarkTestEx(int startend, int slot); + +/** @brief Does a benchmark in slot 0. + * + * This function performs a benchmarking action in slot 0. + * + * @param startend Benchmark action type. + * + * @return Benchmark result for slot 0. + */ +static inline int oslBenchmarkTest(int startend) { + return oslBenchmarkTestEx(startend, 0); } -/** Displays the system benchmark results on the top-left corner of the screen. Useful for debugging: you know that if the first number approaches or exceeds 16.6 then your game has insufficient performance (for 60 fps). */ + +/** @brief Displays the system benchmark results on the top-left corner of the screen. + * + * This function displays the benchmark results, which can be useful for debugging performance issues. + */ extern void oslSysBenchmarkDisplay(); -//Undocumented -enum {OSL_BENCH_INIT=0, OSL_BENCH_START, OSL_BENCH_END, OSL_BENCH_GET, OSL_BENCH_GET_LAST, OSL_BENCH_DISPLAY}; +/** + * @brief Enumeration for benchmark actions in OSLib. + * + * This enumeration defines the various actions that can be performed during a benchmark test + * in OSLib. These actions are used with functions like `oslBenchmarkTestEx` to control the + * start, end, and retrieval of benchmark data. + */ +enum { + OSL_BENCH_INIT = 0, /*!< Initializes the benchmark. This is typically done at the beginning of the benchmarking process. */ + OSL_BENCH_START, /*!< Starts the benchmark timer. This marks the beginning of the period you want to measure. */ + OSL_BENCH_END, /*!< Ends the benchmark timer. This marks the end of the period you want to measure. */ + OSL_BENCH_GET, /*!< Retrieves the time elapsed between the start and end of the benchmark in microseconds. */ + OSL_BENCH_GET_LAST, /*!< Retrieves the last benchmark result without starting or ending a new benchmark. */ + OSL_BENCH_DISPLAY /*!< Displays the benchmark results. This action is primarily used for debugging and performance analysis. */ +}; + +/** + * @brief Number of available benchmark slots. + * + * This macro defines the number of benchmark slots that can be used concurrently. + * Each slot can hold independent benchmark data, allowing multiple benchmarks + * to be performed and compared simultaneously. + */ #define OSL_BENCH_SLOTS 8 + +/** + * @brief Number of samples used for mean benchmarking. + * + * This macro defines the number of samples to be averaged when performing + * a mean benchmark. This helps in obtaining a more accurate and stable + * benchmark result by averaging multiple measurements. + */ #define OSL_BENCH_SAMPLES 20 #ifndef PSP - extern void Debug(const char *format, ...); +/** + * @brief Debugging function for non-PSP platforms. + * + * This function is used to print formatted debug messages to the console or other + * logging facilities on platforms other than the PSP. It behaves similarly to `printf`, + * allowing you to format and output debug information. + * + * @param format A format string that specifies how subsequent arguments are converted + * for output, following the standard C printf conventions. + * @param ... Additional arguments to be formatted and output according to the format string. + */ +extern void Debug(const char *format, ...); #endif -extern void oslVblankInterrupt(int sub, void *parg); +/** + * @brief Handles the VBLANK interrupt. + * + * This function is called during the VBLANK interrupt to perform tasks that need to be + * synchronized with the vertical blanking period of the display. The function can be + * used to update frame counters, synchronize rendering, or perform other time-sensitive + * operations that should occur during the VBLANK period. + * + * @param sub A sub-parameter used to provide additional context or configuration for the interrupt handling. + * @param parg A pointer to user-defined data or structure that may be used within the interrupt handler. + */ +extern void oslVblankInterrupt(int sub, void *parg); +/** + * @brief Displays the first predefined splash screen. + * + * This function shows the first splash screen provided by the OldSchool Library, typically + * the OSLib logo. It can be used at the start of your application as an introduction. + * + * @return Returns 1 on success, 0 if the splash screen could not be displayed. + */ extern int oslShowSplashScreen1(); + +/** + * @brief Displays the second predefined splash screen. + * + * This function shows the second splash screen provided by the OldSchool Library, typically + * associated with the Neoflash logo. It can be used at the start of your application as an introduction. + * + * @return Returns 1 on success, 0 if the splash screen could not be displayed. + */ extern int oslShowSplashScreen2(); -/** Shows one of the predefined splash screens in OldSchool Library. - \param splashType - - 1: Shows the OldSchool Library logo. This logo is not very long and can constitute a great introduction to a game. It can be skipped with cross, circle or start buttons. - - 2: Shows the neoflash logo. Requires and uses the following file: "logo/neoflash.png". - - \return - 1 in case of success, 0 otherwise. - - Call this function just after having initialized OSLib. - - \code -int main(void) -{ - //Init oslib. - oslInit(0); - oslInitGfx(OSL_PF_8888, 1); - - //Show our splash screen - oslShowSplashScreen(1); - - //Begin our game - [...] -\endcode - - \b Warning: This function tries to load images files located on your memory stick. It will do nothing if they are not present. But if your application is running in kernel mode and you are - creating an user thread, your thread will not have a default running directory, making this function to always fail! You should always set a working folder (e.g. with sceIoChdir) before calling this - functions! - - These files can be found in the Resource folder of your OSLib distribution. -*/ -static inline int oslShowSplashScreen(int splashType) { - if (splashType == 1) - return oslShowSplashScreen1(); - else if (splashType == 2) - return oslShowSplashScreen2(); - return 0; +/** @brief Shows one of the predefined splash screens in OldSchool Library. + * + * This function displays a predefined splash screen, such as the OSLib or Neoflash logo. + * + * @param splashType 1 shows the OSLib logo, 2 shows the Neoflash logo. + * + * @return 1 in case of success, 0 otherwise. + */ +static inline int oslShowSplashScreen(int splashType) { + if (splashType == 1) + return oslShowSplashScreen1(); + else if (splashType == 2) + return oslShowSplashScreen2(); + return 0; } -static inline int oslShowNeoflashLogo() { - return oslShowSplashScreen(2); +/** @brief Shows the Neoflash logo splash screen. + * + * This function displays the Neoflash logo splash screen. + * + * @return 1 in case of success, 0 otherwise. + */ +static inline int oslShowNeoflashLogo() { + return oslShowSplashScreen(2); } #ifdef PSP - #define OSL_UVRAM_BASE ((u8*)0x04000000) +/** + * @brief Base address of the UVRAM (Uncached Video RAM) on the PSP. + * + * This macro defines the base address of the uncached video RAM on the PSP. + * This memory region is used for operations that require direct access to video + * memory without the benefits of CPU caching. It is typically used for graphics + * operations where cache coherence with the GPU is critical. + */ +#define OSL_UVRAM_BASE ((u8*)0x04000000) #else - extern u8 *OSL_UVRAM_BASE; - #define alloca _alloca -// void *_alloca(size_t size); +/** + * @brief Pointer to the base address of the UVRAM (Uncached Video RAM) on non-PSP platforms. + * + * On non-PSP platforms, this variable represents the base address of the uncached video RAM. + * This is useful for emulation or testing environments where direct memory access to video + * RAM is simulated. + */ +extern u8 *OSL_UVRAM_BASE; + +/** + * @brief Macro for stack memory allocation on non-PSP platforms. + * + * This macro is used to allocate memory on the stack with a specified size. On non-PSP platforms, + * it is typically mapped to `_alloca`, which performs stack allocation. + * + * @param size The size of the memory block to allocate. + */ +#define alloca _alloca #endif -#define OSL_UVRAM_SIZE (2 << 20) -#define OSL_UVRAM_END ((u8*)((u32)OSL_UVRAM_BASE + OSL_UVRAM_SIZE)) -/** @} */ // end of main_misc +/** + * @brief Size of the UVRAM (Uncached Video RAM) in bytes. + * + * This macro defines the size of the uncached video RAM region. The value represents + * 2 megabytes (2 << 20), which is typically the size allocated for video memory operations + * that require uncached access on the PSP. + */ +#define OSL_UVRAM_SIZE (2 << 20) + +/** + * @brief End address of the UVRAM (Uncached Video RAM) region. + * + * This macro calculates the end address of the uncached video RAM region by adding the size + * of the UVRAM to its base address. It is useful for determining the bounds of the video + * memory area when performing operations that involve the entire UVRAM. + */ +#define OSL_UVRAM_END ((u8*)((u32)OSL_UVRAM_BASE + OSL_UVRAM_SIZE)) +/** @} */ // end of main_misc /** @} */ // end of main - -// *** Console SONY *** -/*#define oslCls() pspDebugScreenClear() -#define oslPrintf(str, format...) pspDebugScreenPrintf(str,##format) -#define oslMoveTo(x,y) pspDebugScreenSetXY(x,y) -#define oslPrintf_xy(x,y, str, format...) ({ oslMoveTo(x,y); \ - oslPrintf(str,##format); })*/ - - -//#include "vfpu.h" #include "oslmath.h" - #include "vram_mgr.h" #include "VirtualFile.h" #include "drawing.h" @@ -609,4 +918,4 @@ static inline int oslShowNeoflashLogo() { } #endif -#endif +#endif /* _OSLIB_H_ */