mirror of
https://github.com/AntonioND/palib.git
synced 2025-06-18 14:45:43 -04:00
425 lines
13 KiB
C
425 lines
13 KiB
C
#ifndef _PA_GENERAL
|
|
#define _PA_GENERAL
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
#include <PA_IPC.h>
|
|
#include <PA_FifoMessages.h>
|
|
|
|
#include <arm9/as_lib9.h>
|
|
#include <arm9/PA_Sound.h>
|
|
#include <arm9/PA_Interrupt.h>
|
|
|
|
#include <nds.h>
|
|
#include <nds/memory.h>
|
|
#include <nds/bios.h>
|
|
#include <malloc.h>
|
|
|
|
#include "../PA_Transfer.h"
|
|
|
|
#include <stdarg.h> // Pour le système de text
|
|
#include <string.h>
|
|
|
|
#ifndef PA_NO_DEPRECATION
|
|
#define DEPRECATED __attribute__ ((deprecated))
|
|
#define PA_DEPRECATED_MACRO _PA_DeprecationStub()
|
|
#else
|
|
#define DEPRECATED
|
|
#define PA_DEPRECATED_MACRO ((void)0)
|
|
#endif
|
|
|
|
static inline void _PA_DeprecationStub() __attribute__((deprecated));
|
|
static inline void _PA_DeprecationStub(){}
|
|
|
|
extern u8 PA_Screen;
|
|
|
|
typedef struct {
|
|
u16 Year;
|
|
u8 Month;
|
|
u8 Day;
|
|
u8 Hour;
|
|
u8 Minutes;
|
|
u8 Seconds;
|
|
// u8 FPS, Frames, OldSeconds; // To test the FPS...
|
|
} RTC;
|
|
extern RTC PA_RTC;
|
|
|
|
static inline void PA_WaitForVBL();
|
|
|
|
extern s16 PA_ScreenSpace; // Espace entre les 2 écrans...+192
|
|
|
|
#define PAWaitForVBL() swiWaitForVBlank()
|
|
/*
|
|
static inline void PAWaitForVBL(){
|
|
//PA_RTC.Frames ++; // For the FPS counter
|
|
swiWaitForVBlank();
|
|
}
|
|
*/
|
|
static inline void PA_PowerOff(){
|
|
powerOn(PM_SYSTEM_PWR);
|
|
}
|
|
|
|
extern u8 pa_checklid;
|
|
|
|
#define BG_GFX1 0x6000000
|
|
#define BG_GFX2 0x6200000
|
|
#define SPRITE_GFX1 0x6400000
|
|
#define SPRITE_GFX2 0x6600000
|
|
|
|
//Pour le DMA Copy...
|
|
#define REG_DMA3SRC *(volatile u32*)0x040000D4
|
|
#define REG_DMA3DST *(volatile u32*)0x040000D8
|
|
#define REG_DMA3CNT *(volatile u32*)0x040000DC
|
|
#define DMA_ON 0x80000000
|
|
#define DMA_NOW 0x00000000
|
|
#define DMA_16 0x00000000
|
|
#define DMA_32 0x04000000
|
|
#define DMA_16NOW (DMA_ON | DMA_NOW | DMA_16)
|
|
#define DMA_32NOW (DMA_ON | DMA_NOW | DMA_32)
|
|
|
|
#define DMA_Copy(source, dest, count, mode) do { \
|
|
if (((u32)(source)) == 0) { \
|
|
DMA_Clear(dest, count, mode); \
|
|
} else { \
|
|
dmaSetParams(3, (const void*)(source), (void *)(dest), (count) | (mode)); \
|
|
\
|
|
if (((mode) & (7 << 27)) == DMA_START_NOW) \
|
|
while (DMA_CR(3) & DMA_BUSY); \
|
|
} \
|
|
} while(0)
|
|
|
|
#define DMA_Clear(dest, count, mode) do { \
|
|
if((mode) & DMA_32) \
|
|
dmaFillWords(0, (void*) (dest), (count) << 2); \
|
|
else \
|
|
dmaFillHalfWords(0, (void*) (dest), (count) << 1); \
|
|
\
|
|
if (((mode) & (7 << 27)) == DMA_START_NOW) \
|
|
while (DMA_CR(0) & DMA_BUSY); \
|
|
} while(0)
|
|
|
|
#define DMA_Force(ulVal, dest, count, mode) do { \
|
|
dmaSetParams(3, (const void*)(&ulVal), (void *)(dest), (count) | (mode) | DMA_SRC_FIX); \
|
|
\
|
|
if (((mode) & (7 << 27)) == DMA_START_NOW) \
|
|
while (DMA_CR(3) & DMA_BUSY); \
|
|
} while (0)
|
|
|
|
#define DMA_CopyEx(ch, source, dest, count, mode) do { \
|
|
dmaSetParams(ch, (const void*)(source), (void *)(dest), (count) | (mode)); \
|
|
\
|
|
if (((mode) & (7 << 27)) == DMA_START_NOW) \
|
|
while (DMA_CR(ch) & DMA_BUSY); \
|
|
} while (0)
|
|
|
|
// Commandes pour la lumière des écrans
|
|
#define BACKLIGHT(screen) BIT(2+screen)
|
|
|
|
#define ALWAYSINLINE __attribute__((always_inline)) static inline
|
|
|
|
#define _REG8 *(vu16*)
|
|
#define _REG16 *(vu16*)
|
|
#define _REG32 *(vu32*)
|
|
|
|
#define SWITCH_SCREENS (1<<15)
|
|
|
|
#define N_HBLS 263
|
|
|
|
/*! \file PA_General.h
|
|
\brief Contains prototypes and macros... for the arm9
|
|
|
|
Contains prototypes and macros... for the arm9
|
|
*/
|
|
|
|
// The PAlib IPC is deprecated...
|
|
extern volatile DEPRECATED PA_IPCType PA_IPC;
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// Général
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
#define SIZEOF_8BIT(x) (sizeof(x))
|
|
#define SIZEOF_16BIT(x) (sizeof(x)>>1)
|
|
#define SIZEOF_32BIT(x) (sizeof(x)>>2)
|
|
|
|
#define PACKED __attribute__ ((packed))
|
|
|
|
// Jpeg functions:
|
|
void PA_jpeg_GetImageSize(char* name, int* width, int* height);
|
|
void PA_jpeg_BltImage(char* name, u16* vram, int output_width, int output_height);
|
|
|
|
extern const s16 PA_SIN[512];
|
|
|
|
typedef struct {
|
|
u8 Color; // Favorite Color
|
|
u8 BdayMonth; // Mois d'anniversaire
|
|
u8 BdayDay; // Jour de naissance
|
|
u8 AlarmHour;
|
|
u8 AlarmMinute;
|
|
u8 Name[21];
|
|
u8 NameLength;
|
|
u8 Message[53];
|
|
u8 MessageLength;
|
|
u8 Language; // Langue... 0 pour Jap, 1 pour anglais, 2 pour français...
|
|
} infos;
|
|
extern infos PA_UserInfo;
|
|
|
|
/** @defgroup General General Functions
|
|
* Initialise the lib, and other general functions...
|
|
* @{
|
|
*/
|
|
|
|
/*! \fn void PA_Init(void)
|
|
\brief
|
|
\~english Initialise the library. Should be used at the beginning of main()
|
|
\~french Initialise la lib... Doit etre placé au début de main()
|
|
*/
|
|
void PA_Init();
|
|
|
|
/*! \fn void PA_InitFifo()
|
|
\brief
|
|
\~english Initialize the Fifo system. It is automatically done in PA_Init().
|
|
\~french Initialise le système Fifo. C'est fait automatiquement dans PA_Init().
|
|
*/
|
|
void PA_InitFifo();
|
|
|
|
/*! \def PA_LegacyIPCInit()
|
|
\deprecated
|
|
\brief
|
|
\~english [DEPRECATED] Initialize the legacy IPC system.
|
|
\~french TODO
|
|
*/
|
|
|
|
#define PA_LegacyIPCInit() do{ \
|
|
memset((void*) &PA_IPC, 0, sizeof(PA_IPCType)); \
|
|
PA_Transfer->mailData = (u32)(&PA_IPC); \
|
|
}while(0)
|
|
|
|
/*! \fn void PA_Init2D(void)
|
|
\brief
|
|
\~english Resets to 2D state after using 3D functions
|
|
\~french Remet en mode 2D après avoir utilisé la 3D
|
|
*/
|
|
void PA_Init2D();
|
|
|
|
// for the video modes...
|
|
extern u8 PA_ExtPal[2][2];
|
|
|
|
/*! \fn void PA_SetVideoMode(u8 screen, u8 mode)
|
|
\brief
|
|
\~english Change the video mode... Use this with caution
|
|
\~french Changer de mode video... A utiliser avec précaution
|
|
\~\param screen
|
|
\~english Screen...
|
|
\~french Ecran...
|
|
\~\param mode
|
|
\~english Mode 0 for normal, 1 for 1 rotating backgrounds, 2 for 2
|
|
\~french Mode 0 pour normal, 1 pour 1 fond rotatif, 2 pour 2
|
|
*/
|
|
void PA_SetVideoMode(u8 screen, u8 mode);
|
|
|
|
#define PA_GetVideoMode(screen) (((screen) ? REG_DISPCNT_SUB : REG_DISPCNT) & 7)
|
|
|
|
|
|
/*! \fn void PA_UpdateUserInfo(void)
|
|
\brief
|
|
\~english Updates the user info. This is automatically done in PA_Init. You can then get any info with the following variables : PA_UserInfo.Color (favorite color), .BdayDay, .BdayMonth, .AlarmHour, .AlarmMinute, .Name, .NameLength, .Message, .MessageLength, .Language
|
|
\~french Met à jour les infos sur l'utilisateur... C'est fait automatiquement dans PA_Init. On peut ensuite récupérer toutes les infos avec PA_UserInfo.Color (couleur favorite), .BdayDay, .BdayMonth, .AlarmHour, .AlarmMinute, .Name, .NameLength, .Message, .MessageLength, .Language
|
|
*/
|
|
void PA_UpdateUserInfo(void);
|
|
|
|
|
|
/*! \fn void PA_UpdateRTC(void)
|
|
\brief
|
|
\~english Updates the Real Time Clock, with info on the current date and hour. Automatically updated in the PA VBL... Get the info with PA_RTC.Minutes, .Hour, .Seconds, .Day, .Month, and .Year
|
|
\~french Met à jour les infos sur l'heure et la date. C'est automatiquement mis à jour dans le VBL PA... On récupère les infos avec PA_RTC.Minutes, .Hour, .Seconds, .Day, .Month, et .Year
|
|
*/
|
|
void PA_UpdateRTC(void);
|
|
|
|
/*! \fn static inline void PA_SwitchScreens()
|
|
\brief
|
|
\~english Switch the bottom and top screens...
|
|
\~french Echange les écrans du haut et du bas
|
|
*/
|
|
static inline void PA_SwitchScreens() {
|
|
REG_POWERCNT ^= SWITCH_SCREENS;
|
|
PA_Screen = !PA_Screen;
|
|
}
|
|
|
|
extern vu8 _PA_LidDown;
|
|
|
|
/*! \def PA_LidClosed()
|
|
\brief
|
|
\~english Check if the DS is closed. Returns 0 if open, 1 if closed
|
|
\~french Vérifie si la DS est fermée. Renvoie 0 si ouverte, 1 si fermée
|
|
*/
|
|
#define PA_LidClosed() _PA_LidDown
|
|
|
|
/*! \fn static inline void PA_SetAutoCheckLid(u8 on)
|
|
\brief
|
|
\~english Automatically check if the DS is closed in PA_WaitForVBL
|
|
\~french Vérifie automatiquement si la DS est fermée dans PA_WaitForVBL
|
|
\~\param on
|
|
\~english 1 for on, 0 for off
|
|
\~french 1 pour activer, 0 pour désactiver
|
|
*/
|
|
static inline void PA_SetAutoCheckLid(u8 on){
|
|
pa_checklid = on;
|
|
}
|
|
|
|
static inline void PA_SetLedBlink(u8 blink, u8 speed);
|
|
|
|
/*! \fn u8 PA_CheckLid()
|
|
\brief
|
|
\~english Check if the DS is closed. If closed, it pauses the DS, and returns 1.
|
|
\~french Vérifie si la DS est fermée. Si fermée, ca met en pause la DS et renvoie 1.
|
|
*/
|
|
u8 PA_CheckLid();
|
|
|
|
/*! \fn static inline void PA_WaitForVBL()
|
|
\brief
|
|
\~english Wait for the VBlank to occur
|
|
\~french Attendre le vbl...
|
|
*/
|
|
static inline void PA_WaitForVBL(){
|
|
if(pa_checklid) PA_CheckLid();
|
|
|
|
// Let other threads interrupt the main thread
|
|
//swiWaitForVBlank();
|
|
cothread_yield_irq(IRQ_VBLANK);
|
|
}
|
|
|
|
#define PA_WaitForVBlank PA_WaitForVBL
|
|
|
|
/*! \def PA_CloseLidSound(close_sound)
|
|
\brief
|
|
\~english Check if the DS is closed. If closed, it pauses the DS, and plays a sound
|
|
\~french Vérifie si la DS est fermée. Si fermée, ca met en pause la DS et joue un son
|
|
\~\param close_sound
|
|
\~english Sound to play, check the sounds doc if you're not sure what to do here
|
|
\~french Son à jouer, regarder la doc son si pas certain de quoi mettre...
|
|
*/
|
|
#define PA_CloseLidSound(close_sound)do{\
|
|
if(PA_LidClosed()){\
|
|
PA_PlaySimpleSound(close_sound);\
|
|
PA_CheckLid(); \
|
|
}}while(0)
|
|
|
|
|
|
/*! \def PA_CloseLidSound2(close_sound, open_sound)
|
|
\brief
|
|
\~english Check if the DS is closed. If closed, it pauses the DS, and plays a sound. The sound system must be initialized before.
|
|
\~french Vérifie si la DS est fermée. Si fermée, ca met en pause la DS et joue un son
|
|
\~\param close_sound
|
|
\~english Sound to play when closes, check the sounds doc if you're not sure what to do here
|
|
\~french Son à jouer quand se ferme, regarder la doc son si pas certain de quoi mettre...
|
|
\~\param open_sound
|
|
\~english Sound to play when opens, check the sounds doc if you're not sure what to do here
|
|
\~french Son à jouer quand s'ouvre, regarder la doc son si pas certain de quoi mettre...
|
|
*/
|
|
#define PA_CloseLidSound2(close_sound, open_sound)do{\
|
|
if(PA_LidClosed()){\
|
|
PA_PlaySimpleSound(close_sound);\
|
|
PA_CheckLid(); \
|
|
PA_PlaySimpleSound(open_sound); \
|
|
}}while(0)
|
|
|
|
/*! \fn void PA_SetScreenLight(u8 screen, u8 light)
|
|
\brief
|
|
\~english Set on or off the screen's light
|
|
\~french Allumer ou eteindre la lumière d'un écran
|
|
\~\param screen
|
|
\~english Screen...
|
|
\~french Ecran...
|
|
\~\param light
|
|
\~english Light, 1 for on, 0 for off
|
|
\~french Lumière, 1 pour allumé, 0 pour éteint
|
|
*/
|
|
static inline void PA_SetScreenLight(u8 screen, u8 light){
|
|
// Beware of the nested one-line IF blocks!
|
|
if(screen)
|
|
if(light)
|
|
powerOn(PM_BACKLIGHT_TOP);
|
|
else
|
|
powerOff(PM_BACKLIGHT_TOP);
|
|
else
|
|
if(light)
|
|
powerOn(PM_BACKLIGHT_BOTTOM);
|
|
else
|
|
powerOff(PM_BACKLIGHT_BOTTOM);
|
|
}
|
|
|
|
|
|
/*! \fn static inline void PA_SetLedBlink(u8 blink, u8 speed)
|
|
\brief
|
|
\~english Set teh DS Led blinking
|
|
\~french Régler le clignotement de la led
|
|
\~\param blink
|
|
\~english 1 for blinking, 0 for always on
|
|
\~french 1 pour clignoter, 0 pour toujours allumé
|
|
\~\param speed
|
|
\~english Speed : 0 for slow, 1 for fast
|
|
\~french Vitesse : 0 pour lent, 1 pour rapide
|
|
*/
|
|
static inline void PA_SetLedBlink(u8 blink, u8 speed){
|
|
ledBlink(((blink&1) | ((speed&1) << 1)) << 4);
|
|
}
|
|
|
|
/*! \def PA_WaitFor(something)
|
|
\brief
|
|
\~english Wait for a specific thing to happen...
|
|
\~french Attendre un événement précis...
|
|
\~\param something
|
|
\~english Thing to wait for, like Pad.Newpress.A, or Stylus.Newpress, etc...
|
|
\~french Evénement à attendre, comme Pad.Newpress.A, ou Stylus.Newpress, etc...
|
|
*/
|
|
|
|
#define PA_WaitFor(something) do{while(!(something)) PA_WaitForVBL();}while(0)
|
|
|
|
/*! \fn static inline void PA_SetDSLBrightness(u8 level)
|
|
\brief
|
|
\~english Set the DS Lite Light level...
|
|
\~french Régler le niveau de lumière de la DS Lite !
|
|
\~\param level
|
|
\~english Light level (0-3)
|
|
\~french Niveau de la lumière (0-3)
|
|
*/
|
|
static inline void PA_SetDSLBrightness(u8 level){
|
|
PA_FifoMsg msg;
|
|
msg.type = PA_MSG_DSLBRIGHT;
|
|
msg.DSLBrightMsg.brightness = level;
|
|
PA_SendFifoMsg(msg);
|
|
}
|
|
|
|
/*! \fn bool PA_Locate(char *start, char *target, bool isDir, int depth, char *result)
|
|
\brief
|
|
Find a directory in the file system within a given depth
|
|
\param start
|
|
from which directory to start, use "/" to search from the root
|
|
\param target
|
|
what to look for: the name of a file or directory
|
|
\param isDir
|
|
look for a directory or a file?
|
|
\param depth
|
|
how much depth level (in number of directories) to traverse; limiting this speeds up the search on crowded cards. A reasonable value is, for example, 3.
|
|
\param result
|
|
pointer to a buffer where the result will be stored
|
|
\return
|
|
true if the target was found
|
|
*/
|
|
bool PA_Locate(char* start, char* target, bool isDir, int depth, char* result);
|
|
|
|
/// Displays an error message.
|
|
void PA_Error(const char* text);
|
|
|
|
/** @} */ // end of General
|
|
|
|
void PA_Nothing(void);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
#endif
|