Merge pull request #2018 from vgturtle127/beautification-4

Beautification 4 - the Source/Android directory
This commit is contained in:
zilmar 2021-03-18 12:57:13 +10:30 committed by GitHub
commit 538318ea5c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
38 changed files with 665 additions and 598 deletions

View File

@ -50,12 +50,12 @@ Please read [CONTRIBUTING.md](https://gist.github.com/PurpleBooth/b24679402957c6
We use semantic versioning for Project64. For the versions available, see the [tags on this repository](https://github.com/project64/project64/tags) We use semantic versioning for Project64. For the versions available, see the [tags on this repository](https://github.com/project64/project64/tags)
## Authors ## Author / Contributors
* **Zilmar** - *Current maintainer* - [Zilmar](https://github.com/project64) * **Zilmar** - *Current maintainer* - [Zilmar](https://github.com/project64)
* **Jabo** - *Previous member* - Jabo * **Jabo** - *Previous contributor* - Jabo
* **Smiff** - *Previous member* - Smiff * **Smiff** - *Previous contributor* - Smiff
* **Gent** - *Previous member* - Gent * **Gent** - *Previous contributor* - Gent
See also the list of [contributors](https://github.com/your/project/contributors) who participated in this project. See also the list of [contributors](https://github.com/your/project/contributors) who participated in this project.

View File

@ -11,18 +11,18 @@ class JavaBridge :
public: public:
JavaBridge(JavaVM* vm); JavaBridge(JavaVM* vm);
//Render window functions // Render window functions
void GfxThreadInit(); void GfxThreadInit();
void GfxThreadDone(); void GfxThreadDone();
void SwapWindow(); void SwapWindow();
//Rom List // ROM List
void RomListReset(void); void RomListReset(void);
void RomListAddItem(const char * FullFileName, const char * FileName, const char * GoodName, uint32_t TextColor); void RomListAddItem(const char * FullFileName, const char * FileName, const char * GoodName, uint32_t TextColor);
void RomListLoaded(void); void RomListLoaded(void);
void RecentRomsUpdated(void); void RecentRomsUpdated(void);
//Notification // Notification
void DisplayError(const char * Message); void DisplayError(const char * Message);
void DisplayMessage(const char * Message, int DisplayTime); void DisplayMessage(const char * Message, int DisplayTime);
void DisplayMessage2(const char * Message); void DisplayMessage2(const char * Message);

View File

@ -32,7 +32,7 @@ void CNotificationImp::DisplayError(const char * Message) const
#ifdef ANDROID #ifdef ANDROID
g_JavaBridge->DisplayError(Message); g_JavaBridge->DisplayError(Message);
#else #else
Message = NULL; // not used Message = NULL; // Not used
#endif #endif
} }
@ -67,7 +67,7 @@ void CNotificationImp::DisplayWarning(const char * Message) const
#ifdef ANDROID #ifdef ANDROID
g_JavaBridge->DisplayError(Message); g_JavaBridge->DisplayError(Message);
#else #else
Message = NULL; // not used Message = NULL; // Not used
#endif #endif
} }
@ -84,14 +84,14 @@ void CNotificationImp::DisplayMessage(int DisplayTime, LanguageStringID StringID
DisplayMessage(DisplayTime, g_Lang->GetString(StringID).c_str()); DisplayMessage(DisplayTime, g_Lang->GetString(StringID).c_str());
} }
//User Feedback // User feedback
void CNotificationImp::DisplayMessage(int DisplayTime, const char * Message) const void CNotificationImp::DisplayMessage(int DisplayTime, const char * Message) const
{ {
#ifdef ANDROID #ifdef ANDROID
if (g_JavaBridge == NULL) { return; } if (g_JavaBridge == NULL) { return; }
g_JavaBridge->DisplayMessage(Message, DisplayTime); g_JavaBridge->DisplayMessage(Message, DisplayTime);
#else #else
// ignore warning usage // Ignore warning usage
DisplayTime = DisplayTime; DisplayTime = DisplayTime;
Message = Message; Message = Message;
#endif #endif
@ -104,12 +104,12 @@ void CNotificationImp::DisplayMessage2(const char * Message) const
g_JavaBridge->DisplayMessage2(Message); g_JavaBridge->DisplayMessage2(Message);
#else #else
// ignore warning usage // Ignore warning usage
Message = Message; Message = Message;
#endif #endif
} }
// Ask a Yes/No Question to the user, yes = true, no = false // Ask a yes/no question to the user, yes = true, no = false
bool CNotificationImp::AskYesNoQuestion(const char * /*Question*/) const bool CNotificationImp::AskYesNoQuestion(const char * /*Question*/) const
{ {
return false; return false;

View File

@ -9,14 +9,14 @@ public:
CNotificationImp(void); CNotificationImp(void);
virtual ~CNotificationImp(); virtual ~CNotificationImp();
//Error Messages // Error messages
void DisplayError(const char * Message) const; void DisplayError(const char * Message) const;
void DisplayError(LanguageStringID StringID) const; void DisplayError(LanguageStringID StringID) const;
void FatalError(const char * Message) const; void FatalError(const char * Message) const;
void FatalError(LanguageStringID StringID) const; void FatalError(LanguageStringID StringID) const;
//User Feedback // User feedback
void DisplayWarning(const char * Message) const; void DisplayWarning(const char * Message) const;
void DisplayWarning(LanguageStringID StringID) const; void DisplayWarning(LanguageStringID StringID) const;
@ -25,7 +25,7 @@ public:
void DisplayMessage2(const char * Message) const; void DisplayMessage2(const char * Message) const;
// Ask a Yes/No Question to the user, yes = true, no = false // Ask a yes/no question to the user, yes = true, no = false
bool AskYesNoQuestion(const char * Question) const; bool AskYesNoQuestion(const char * Question) const;
void BreakPoint(const char * FileName, int32_t LineNumber); void BreakPoint(const char * FileName, int32_t LineNumber);

View File

@ -22,5 +22,4 @@ void SyncBridge::SwapWindow()
} }
} }
#endif #endif

View File

@ -10,7 +10,7 @@ class SyncBridge :
public: public:
SyncBridge (JavaBridge * javaBridge); SyncBridge (JavaBridge * javaBridge);
//Render window functions // Render window functions
void GfxThreadInit(); void GfxThreadInit();
void GfxThreadDone(); void GfxThreadDone();
void SwapWindow(); void SwapWindow();

View File

@ -9,8 +9,8 @@ void RegisterUISettings(void)
{ {
g_Settings->AddHandler((SettingID)(FirstUISettings + Asserts_Version), new CSettingTypeApplication("Settings", "Asserts Version", (uint32_t)0)); g_Settings->AddHandler((SettingID)(FirstUISettings + Asserts_Version), new CSettingTypeApplication("Settings", "Asserts Version", (uint32_t)0));
g_Settings->AddHandler((SettingID)(FirstUISettings + Screen_Orientation), new CSettingTypeApplication("Settings", "Screen Orientation", (uint32_t)0)); g_Settings->AddHandler((SettingID)(FirstUISettings + Screen_Orientation), new CSettingTypeApplication("Settings", "Screen Orientation", (uint32_t)0));
g_Settings->AddHandler((SettingID)(FirstUISettings + File_RecentGameFileCount), new CSettingTypeApplication("Settings", "Remembered Rom Files", (uint32_t)10)); g_Settings->AddHandler((SettingID)(FirstUISettings + File_RecentGameFileCount), new CSettingTypeApplication("Settings", "Remembered ROM Files", (uint32_t)10));
g_Settings->AddHandler((SettingID)(FirstUISettings + File_RecentGameFileIndex), new CSettingTypeApplicationIndex("Recent File", "Recent Rom", Default_None)); g_Settings->AddHandler((SettingID)(FirstUISettings + File_RecentGameFileIndex), new CSettingTypeApplicationIndex("Recent File", "Recent ROM", Default_None));
g_Settings->AddHandler((SettingID)(FirstUISettings + TouchScreen_ButtonScale), new CSettingTypeApplication("Touch Screen", "Button Scale", (uint32_t)100)); g_Settings->AddHandler((SettingID)(FirstUISettings + TouchScreen_ButtonScale), new CSettingTypeApplication("Touch Screen", "Button Scale", (uint32_t)100));
g_Settings->AddHandler((SettingID)(FirstUISettings + TouchScreen_Layout), new CSettingTypeApplication("Touch Screen", "Layout", "Analog")); g_Settings->AddHandler((SettingID)(FirstUISettings + TouchScreen_Layout), new CSettingTypeApplication("Touch Screen", "Layout", "Analog"));
g_Settings->AddHandler((SettingID)(FirstUISettings + Controller_ConfigFile), new CSettingTypeRelativePath("Config", "Controller.cfg")); g_Settings->AddHandler((SettingID)(FirstUISettings + Controller_ConfigFile), new CSettingTypeRelativePath("Config", "Controller.cfg"));

View File

@ -7,27 +7,27 @@ enum UISettingID
Asserts_Version, Asserts_Version,
Screen_Orientation, Screen_Orientation,
//Recent Game // Recent game
File_RecentGameFileCount, File_RecentGameFileCount,
File_RecentGameFileIndex, File_RecentGameFileIndex,
//Touch Screen // Touch screen
TouchScreen_ButtonScale, TouchScreen_ButtonScale,
TouchScreen_Layout, TouchScreen_Layout,
//Controller Config // Controller config
Controller_ConfigFile, Controller_ConfigFile,
Controller_CurrentProfile, Controller_CurrentProfile,
Controller_Deadzone, Controller_Deadzone,
Controller_Sensitivity, Controller_Sensitivity,
//Support Window // Support window
SupportWindow_FirstRun, SupportWindow_FirstRun,
SupportWindow_AlwaysShow, SupportWindow_AlwaysShow,
SupportWindow_ShowingSupportWindow, SupportWindow_ShowingSupportWindow,
SupportWindow_RunCount, SupportWindow_RunCount,
//Game Settings // Game settings
Game_RunCount, Game_RunCount,
}; };

View File

@ -116,7 +116,7 @@ static void watch_uninstall(const char *baseDir)
inotify_rm_watch(fileDescriptor, IN_DELETE); inotify_rm_watch(fileDescriptor, IN_DELETE);
__android_log_print(ANDROID_LOG_INFO, "watch_uninstall", "closing the INOTIFY instance"); __android_log_print(ANDROID_LOG_INFO, "watch_uninstall", "closing the INOTIFY instance");
close(fileDescriptor); close(fileDescriptor);
__android_log_print(ANDROID_LOG_INFO, "watch_uninstall", "Waiting to test if dir removed"); __android_log_print(ANDROID_LOG_INFO, "watch_uninstall", "Waiting to test if directory removed");
pjutil::Sleep(2000); pjutil::Sleep(2000);
__android_log_print(ANDROID_LOG_INFO, "watch_uninstall", "Sleep Done"); __android_log_print(ANDROID_LOG_INFO, "watch_uninstall", "Sleep Done");
@ -144,10 +144,10 @@ EXPORT jint CALL JNI_OnLoad(JavaVM* vm, void* reserved)
__android_log_print(ANDROID_LOG_ERROR, "jniBridge", "Failed to get the environment using GetEnv()"); __android_log_print(ANDROID_LOG_ERROR, "jniBridge", "Failed to get the environment using GetEnv()");
return -1; return -1;
} }
/*
* Create mThreadKey so we can keep track of the JNIEnv assigned to each thread // Create mThreadKey so we can keep track of the JNIEnv assigned to each thread
* Refer to http://developer.android.com/guide/practices/design/jni.html for the rationale behind this // Refer to http://developer.android.com/guide/practices/design/jni.html for the rationale behind this
*/
if (pthread_key_create(&g_ThreadKey, Android_JNI_ThreadDestroyed) != 0) if (pthread_key_create(&g_ThreadKey, Android_JNI_ThreadDestroyed) != 0)
{ {
__android_log_print(ANDROID_LOG_ERROR, "jniBridge", "Error initializing pthread key"); __android_log_print(ANDROID_LOG_ERROR, "jniBridge", "Error initializing pthread key");
@ -172,7 +172,7 @@ void AddRecentRom(const char * ImagePath)
if (ImagePath == NULL) { return; } if (ImagePath == NULL) { return; }
WriteTrace(TraceUserInterface, TraceDebug, "Start (ImagePath: %s)", ImagePath); WriteTrace(TraceUserInterface, TraceDebug, "Start (ImagePath: %s)", ImagePath);
//Get Information about the stored rom list // Get information about the stored ROM list
size_t MaxRememberedFiles = UISettingsLoadDword(File_RecentGameFileCount); size_t MaxRememberedFiles = UISettingsLoadDword(File_RecentGameFileCount);
strlist RecentGames; strlist RecentGames;
size_t i; size_t i;
@ -186,7 +186,7 @@ void AddRecentRom(const char * ImagePath)
RecentGames.push_back(RecentGame); RecentGames.push_back(RecentGame);
} }
//See if the game is already in the list if so then move it to the top of the list // See if the game is already in the list, and if so then move it to the top of the list
strlist::iterator iter; strlist::iterator iter;
for (iter = RecentGames.begin(); iter != RecentGames.end(); iter++) for (iter = RecentGames.begin(); iter != RecentGames.end(); iter++)
{ {
@ -238,7 +238,7 @@ void GameCpuRunning(void * /*NotUsed*/)
{ {
if (g_JavaBridge) if (g_JavaBridge)
{ {
WriteTrace(TraceUserInterface, TraceDebug, "Notify java emulation stopped"); WriteTrace(TraceUserInterface, TraceDebug, "Notify Java emulation stopped");
g_JavaBridge->EmulationStarted(); g_JavaBridge->EmulationStarted();
} }
else else
@ -248,7 +248,7 @@ void GameCpuRunning(void * /*NotUsed*/)
} }
else else
{ {
WriteTrace(TraceUserInterface, TraceError, "Failed to get java environment"); WriteTrace(TraceUserInterface, TraceError, "Failed to get Java environment");
} }
} }
else else
@ -257,7 +257,7 @@ void GameCpuRunning(void * /*NotUsed*/)
{ {
if (g_JavaBridge) if (g_JavaBridge)
{ {
WriteTrace(TraceUserInterface, TraceDebug, "Notify java emulation stopped"); WriteTrace(TraceUserInterface, TraceDebug, "Notify Java emulation stopped");
g_JavaBridge->EmulationStopped(); g_JavaBridge->EmulationStopped();
} }
else else
@ -266,11 +266,11 @@ void GameCpuRunning(void * /*NotUsed*/)
} }
// call in to java that emulation done // call in to java that emulation done
WriteTrace(TraceUserInterface, TraceDebug, "clean up global activity"); WriteTrace(TraceUserInterface, TraceDebug, "Clean up global activity");
env->DeleteGlobalRef(g_Activity); env->DeleteGlobalRef(g_Activity);
g_Activity = NULL; g_Activity = NULL;
WriteTrace(TraceUserInterface, TraceDebug, "clean up global gl thread"); WriteTrace(TraceUserInterface, TraceDebug, "Clean up global gl thread");
if (g_JavaBridge) if (g_JavaBridge)
{ {
g_JavaBridge->GfxThreadDone(); g_JavaBridge->GfxThreadDone();
@ -306,7 +306,7 @@ EXPORT jboolean CALL Java_emu_project64_jni_NativeExports_appInit(JNIEnv* env, j
if (g_JavaVM == NULL) if (g_JavaVM == NULL)
{ {
Notify().DisplayError("No java VM"); Notify().DisplayError("No Java VM");
return false; return false;
} }
@ -392,7 +392,7 @@ EXPORT jboolean CALL Java_emu_project64_jni_NativeExports_IsSettingSet(JNIEnv* e
EXPORT void CALL Java_emu_project64_jni_NativeExports_LoadRomList(JNIEnv* env, jclass cls) EXPORT void CALL Java_emu_project64_jni_NativeExports_LoadRomList(JNIEnv* env, jclass cls)
{ {
WriteTrace(TraceUserInterface, TraceDebug, "start"); WriteTrace(TraceUserInterface, TraceDebug, "Start");
if (g_JavaRomList == NULL) if (g_JavaRomList == NULL)
{ {
g_JavaRomList = new CJavaRomList; g_JavaRomList = new CJavaRomList;
@ -451,14 +451,14 @@ EXPORT void CALL Java_emu_project64_jni_NativeExports_ExternalEvent(JNIEnv* env,
EXPORT void CALL Java_emu_project64_jni_NativeExports_ResetApplicationSettings(JNIEnv* env, jclass cls) EXPORT void CALL Java_emu_project64_jni_NativeExports_ResetApplicationSettings(JNIEnv* env, jclass cls)
{ {
WriteTrace(TraceUserInterface, TraceDebug, "start"); WriteTrace(TraceUserInterface, TraceDebug, "Start");
CSettingTypeApplication::ResetAll(); CSettingTypeApplication::ResetAll();
WriteTrace(TraceUserInterface, TraceDebug, "Done"); WriteTrace(TraceUserInterface, TraceDebug, "Done");
} }
EXPORT jbyteArray CALL Java_emu_project64_jni_NativeExports_GetString(JNIEnv* env, jclass cls, int StringID) EXPORT jbyteArray CALL Java_emu_project64_jni_NativeExports_GetString(JNIEnv* env, jclass cls, int StringID)
{ {
WriteTrace(TraceUserInterface, TraceDebug, "start (StringID: %d)", StringID); WriteTrace(TraceUserInterface, TraceDebug, "Start (StringID: %d)", StringID);
jbyteArray result = NULL; jbyteArray result = NULL;
if (g_Lang) if (g_Lang)
{ {
@ -479,7 +479,7 @@ EXPORT jbyteArray CALL Java_emu_project64_jni_NativeExports_GetString(JNIEnv* en
EXPORT void CALL Java_emu_project64_jni_NativeExports_SetSpeed(JNIEnv* env, jclass cls, int Speed) EXPORT void CALL Java_emu_project64_jni_NativeExports_SetSpeed(JNIEnv* env, jclass cls, int Speed)
{ {
WriteTrace(TraceUserInterface, TraceDebug, "start (Speed: %d)", Speed); WriteTrace(TraceUserInterface, TraceDebug, "Start (Speed: %d)", Speed);
if (g_BaseSystem) if (g_BaseSystem)
{ {
g_BaseSystem->SetSpeed(Speed); g_BaseSystem->SetSpeed(Speed);
@ -490,7 +490,7 @@ EXPORT void CALL Java_emu_project64_jni_NativeExports_SetSpeed(JNIEnv* env, jcla
EXPORT int CALL Java_emu_project64_jni_NativeExports_GetSpeed(JNIEnv* env, jclass cls) EXPORT int CALL Java_emu_project64_jni_NativeExports_GetSpeed(JNIEnv* env, jclass cls)
{ {
int speed = 0; int speed = 0;
WriteTrace(TraceUserInterface, TraceDebug, "start"); WriteTrace(TraceUserInterface, TraceDebug, "Start");
if (g_BaseSystem) if (g_BaseSystem)
{ {
speed = g_BaseSystem->GetSpeed(); speed = g_BaseSystem->GetSpeed();
@ -502,7 +502,7 @@ EXPORT int CALL Java_emu_project64_jni_NativeExports_GetSpeed(JNIEnv* env, jclas
EXPORT int CALL Java_emu_project64_jni_NativeExports_GetBaseSpeed(JNIEnv* env, jclass cls) EXPORT int CALL Java_emu_project64_jni_NativeExports_GetBaseSpeed(JNIEnv* env, jclass cls)
{ {
int speed = 0; int speed = 0;
WriteTrace(TraceUserInterface, TraceDebug, "start"); WriteTrace(TraceUserInterface, TraceDebug, "Start");
if (g_BaseSystem) if (g_BaseSystem)
{ {
speed = g_BaseSystem->GetBaseSpeed(); speed = g_BaseSystem->GetBaseSpeed();
@ -629,7 +629,7 @@ static void Android_JNI_ThreadDestroyed(void* value)
{ {
__android_log_print(ANDROID_LOG_ERROR, "Android_JNI_ThreadDestroyed", "start"); __android_log_print(ANDROID_LOG_ERROR, "Android_JNI_ThreadDestroyed", "start");
/* The thread is being destroyed, detach it from the Java VM and set the mThreadKey value to NULL as required */ // The thread is being destroyed, detach it from the Java VM and set the mThreadKey value to NULL as required
JNIEnv *env = (JNIEnv*)value; JNIEnv *env = (JNIEnv*)value;
if (env != NULL) if (env != NULL)
{ {
@ -641,10 +641,11 @@ static void Android_JNI_ThreadDestroyed(void* value)
JNIEnv* Android_JNI_GetEnv(void) JNIEnv* Android_JNI_GetEnv(void)
{ {
/* From http://developer.android.com/guide/practices/jni.html /*
* From http://developer.android.com/guide/practices/jni.html
* All threads are Linux threads, scheduled by the kernel. * All threads are Linux threads, scheduled by the kernel.
* They're usually started from managed code (using Thread.start), but they can also be created elsewhere and then * They're usually started from managed code (using Thread.start), but they can also be created elsewhere and then
* attached to the JavaVM. For example, a thread started with pthread_create can be attached with the * attached to the Java VM. For example, a thread started with pthread_create can be attached with the
* JNI AttachCurrentThread or AttachCurrentThreadAsDaemon functions. Until a thread is attached, it has no JNIEnv, * JNI AttachCurrentThread or AttachCurrentThreadAsDaemon functions. Until a thread is attached, it has no JNIEnv,
* and cannot make JNI calls. * and cannot make JNI calls.
* Attaching a natively-created thread causes a java.lang.Thread object to be constructed and added to the "main" * Attaching a natively-created thread causes a java.lang.Thread object to be constructed and added to the "main"
@ -657,7 +658,7 @@ JNIEnv* Android_JNI_GetEnv(void)
int status = g_JavaVM->AttachCurrentThread(&env, NULL); int status = g_JavaVM->AttachCurrentThread(&env, NULL);
if (status < 0) if (status < 0)
{ {
__android_log_print(ANDROID_LOG_ERROR, "jniBridge", "failed to attach current thread"); __android_log_print(ANDROID_LOG_ERROR, "jniBridge", "Failed to attach current thread");
return 0; return 0;
} }

View File

@ -27,4 +27,3 @@ void CJniBridegSettings::RefreshSettings(void *)
{ {
m_bCPURunning = g_Settings->LoadBool(GameRunning_CPU_Running); m_bCPURunning = g_Settings->LoadBool(GameRunning_CPU_Running);
} }

View File

@ -1,13 +1,13 @@
/********************************************************************************** // Common controller plugin specification, version 1.1
Common Controller plugin spec, version #1.1
**********************************************************************************/
#pragma once #pragma once
#include <Common/stdtypes.h> #include <Common/stdtypes.h>
enum { PLUGIN_TYPE_CONTROLLER = 4 }; enum { PLUGIN_TYPE_CONTROLLER = 4 };
/*** Conteroller plugin's ****/ // Controller plugins
enum enum
{ {
PLUGIN_NONE = 1, PLUGIN_NONE = 1,
@ -25,12 +25,13 @@ enum
#define CALL #define CALL
#endif #endif
/***** Structures *****/ // Structures
typedef struct typedef struct
{ {
uint16_t Version; /* Should be set to 0x0101 */ uint16_t Version; // Should be set to 0x0101
uint16_t Type; /* Set to PLUGIN_TYPE_CONTROLLER */ uint16_t Type; // Set to PLUGIN_TYPE_CONTROLLER
char Name[100]; /* Name of the DLL */ char Name[100]; // Name of the DLL
int32_t Reserved1; int32_t Reserved1;
int32_t Reserved2; int32_t Reserved2;
} PLUGIN_INFO; } PLUGIN_INFO;
@ -43,7 +44,7 @@ typedef struct
} CONTROL; } CONTROL;
#pragma warning(push) #pragma warning(push)
#pragma warning(disable : 4201) // warning C4201: nonstandard extension used : nameless struct/union #pragma warning(disable : 4201) // warning C4201: nonstandard extension used: nameless struct/union
typedef union typedef union
{ {
@ -80,26 +81,27 @@ typedef struct
void * hMainWindow; void * hMainWindow;
void * hinst; void * hinst;
int32_t MemoryBswaped; // memory in client- or server-native endian int32_t MemoryBswaped; // Memory in client or server-native endian
uint8_t * HEADER; // the ROM header (first 40h bytes of the ROM) uint8_t * HEADER; // The ROM header (first 40h bytes of the ROM)
CONTROL * Controls; // pointer to array of 4 controllers, i.e.: CONTROL Controls[4]; CONTROL * Controls; // Pointer to array of 4 controllers, i.e.: CONTROL Controls[4];
} CONTROL_INFO; } CONTROL_INFO;
/****************************************************************** /*
Function: CloseDLL Function: CloseDLL
Purpose: This function is called when the emulator is closing Purpose: This function is called when the emulator is closing
down allowing the dll to de-initialise. down allowing the DLL to de-initialize.
input: none input: none
output: none output: none
*******************************************************************/ */
EXPORT void CALL CloseDLL(void); EXPORT void CALL CloseDLL(void);
/****************************************************************** /*
Function: ControllerCommand Function: ControllerCommand
Purpose: To process the raw data that has just been sent to a Purpose: To process the raw data that has just been sent to a
specific controller. specific controller.
input: - Controller Number (0 to 3) and -1 signalling end of input: - Controller Number (0 to 3) and -1 signaling end of
processing the pif ram. processing the PIF RAM.
- Pointer of data to be processed. - Pointer of data to be processed.
output: none output: none
@ -107,113 +109,125 @@ note: This function is only needed if the DLL is allowing raw
data, or the plugin is set to raw data, or the plugin is set to raw
the data that is being processed looks like this: the data that is being processed looks like this:
initilize controller: 01 03 00 FF FF FF initialize controller: 01 03 00 FF FF FF
read controller: 01 04 01 FF FF FF FF read controller: 01 04 01 FF FF FF FF
*******************************************************************/ */
EXPORT void CALL ControllerCommand(int Control, uint8_t * Command); EXPORT void CALL ControllerCommand(int Control, uint8_t * Command);
/****************************************************************** /*
Function: DllAbout Function: DllAbout
Purpose: This function is optional function that is provided Purpose: This function is optional function that is provided
to give further information about the DLL. to give further information about the DLL.
input: a handle to the window that calls this function input: a handle to the window that calls this function
output: none output: none
*******************************************************************/ */
EXPORT void CALL DllAbout(void * hParent); EXPORT void CALL DllAbout(void * hParent);
/****************************************************************** /*
Function: DllConfig Function: DllConfig
Purpose: This function is optional function that is provided Purpose: This function is optional function that is provided
to allow the user to configure the dll to allow the user to configure the DLL
input: a handle to the window that calls this function input: a handle to the window that calls this function
output: none output: none
*******************************************************************/ */
EXPORT void CALL DllConfig(void * hParent); EXPORT void CALL DllConfig(void * hParent);
/****************************************************************** /*
Function: DllTest Function: DllTest
Purpose: This function is optional function that is provided Purpose: This function is optional function that is provided
to allow the user to test the dll to allow the user to test the DLL
input: a handle to the window that calls this function input: a handle to the window that calls this function
output: none output: none
*******************************************************************/ */
EXPORT void CALL DllTest(void * hParent); EXPORT void CALL DllTest(void * hParent);
/****************************************************************** /*
Function: GetDllInfo Function: GetDllInfo
Purpose: This function allows the emulator to gather information Purpose: This function allows the emulator to gather information
about the dll by filling in the PluginInfo structure. about the DLL by filling in the PluginInfo structure.
input: a pointer to a PLUGIN_INFO stucture that needs to be input: a pointer to a PLUGIN_INFO structure that needs to be
filled by the function. (see def above) filled by the function. (see def above)
output: none output: none
*******************************************************************/ */
EXPORT void CALL GetDllInfo(PLUGIN_INFO * PluginInfo); EXPORT void CALL GetDllInfo(PLUGIN_INFO * PluginInfo);
/****************************************************************** /*
Function: GetKeys Function: GetKeys
Purpose: To get the current state of the controllers buttons. Purpose: To get the current state of the controllers buttons.
input: - Controller Number (0 to 3) input: - Controller Number (0 to 3)
- A pointer to a BUTTONS structure to be filled with - A pointer to a BUTTONS structure to be filled with
the controller state. the controller state.
output: none output: none
*******************************************************************/ */
EXPORT void CALL GetKeys(int32_t Control, BUTTONS * Keys); EXPORT void CALL GetKeys(int32_t Control, BUTTONS * Keys);
/****************************************************************** /*
Function: InitiateControllers Function: InitiateControllers
Purpose: This function initialises how each of the controllers Purpose: This function initializes how each of the controllers
should be handled. should be handled.
input: - The handle to the main window. input: - The handle to the main window.
- A controller structure that needs to be filled for - A controller structure that needs to be filled for
the emulator to know how to handle each controller. the emulator to know how to handle each controller.
output: none output: none
*******************************************************************/ */
EXPORT void CALL InitiateControllers(CONTROL_INFO ControlInfo); EXPORT void CALL InitiateControllers(CONTROL_INFO ControlInfo);
/****************************************************************** /*
Function: ReadController Function: ReadController
Purpose: To process the raw data in the pif ram that is about to Purpose: To process the raw data in the PIF RAM that is about to
be read. be read.
input: - Controller Number (0 to 3) and -1 signalling end of input: - Controller Number (0 to 3) and -1 signaling end of
processing the pif ram. processing the PIF RAM.
- Pointer of data to be processed. - Pointer of data to be processed.
output: none output: none
note: This function is only needed if the DLL is allowing raw note: This function is only needed if the DLL is allowing raw
data. data.
*******************************************************************/ */
EXPORT void CALL ReadController(int Control, uint8_t * Command); EXPORT void CALL ReadController(int Control, uint8_t * Command);
/****************************************************************** /*
Function: RomClosed Function: RomClosed
Purpose: This function is called when a rom is closed. Purpose: This function is called when a ROM is closed.
input: none input: none
output: none output: none
*******************************************************************/ */
EXPORT void CALL RomClosed(void); EXPORT void CALL RomClosed(void);
/****************************************************************** /*
Function: RomOpen Function: RomOpen
Purpose: This function is called when a rom is open. (from the Purpose: This function is called when a ROM is open. (from the
emulation thread) emulation thread)
input: none input: none
output: none output: none
*******************************************************************/ */
EXPORT void CALL RomOpen(void); EXPORT void CALL RomOpen(void);
/****************************************************************** /*
Function: WM_KeyDown Function: WM_KeyDown
Purpose: To pass the WM_KeyDown message from the emulator to the Purpose: To pass the WM_KeyDown message from the emulator to the
plugin. plugin.
input: wParam and lParam of the WM_KEYDOWN message. input: wParam and lParam of the WM_KEYDOWN message.
output: none output: none
*******************************************************************/ */
EXPORT void CALL WM_KeyDown(uint32_t wParam, uint32_t lParam); EXPORT void CALL WM_KeyDown(uint32_t wParam, uint32_t lParam);
/****************************************************************** /*
Function: WM_KeyUp Function: WM_KeyUp
Purpose: To pass the WM_KEYUP message from the emulator to the Purpose: To pass the WM_KEYUP message from the emulator to the
plugin. plugin.
input: wParam and lParam of the WM_KEYDOWN message. input: wParam and lParam of the WM_KEYDOWN message.
output: none output: none
*******************************************************************/ */
EXPORT void CALL WM_KeyUp(uint32_t wParam, uint32_t lParam); EXPORT void CALL WM_KeyUp(uint32_t wParam, uint32_t lParam);

View File

@ -15,10 +15,11 @@ void ShowAboutWindow (void * hParent);
/****************************************************************** /******************************************************************
Function: CloseDLL Function: CloseDLL
Purpose: This function is called when the emulator is closing Purpose: This function is called when the emulator is closing
down allowing the dll to de-initialise. down allowing the DLL to de-initialize.
input: none input: none
output: none output: none
*******************************************************************/ *******************************************************************/
EXPORT void CALL CloseDLL (void) EXPORT void CALL CloseDLL (void)
{ {
} }
@ -27,8 +28,8 @@ EXPORT void CALL CloseDLL (void)
Function: ControllerCommand Function: ControllerCommand
Purpose: To process the raw data that has just been sent to a Purpose: To process the raw data that has just been sent to a
specific controller. specific controller.
input: - Controller Number (0 to 3) and -1 signalling end of input: - Controller Number (0 to 3) and -1 signaling end of
processing the pif ram. processing the PIF RAM.
- Pointer of data to be processed. - Pointer of data to be processed.
output: none output: none
@ -36,9 +37,10 @@ note: This function is only needed if the DLL is allowing raw
data, or the plugin is set to raw data, or the plugin is set to raw
the data that is being processed looks like this: the data that is being processed looks like this:
initilize controller: 01 03 00 FF FF FF initialize controller: 01 03 00 FF FF FF
read controller: 01 04 01 FF FF FF FF read controller: 01 04 01 FF FF FF FF
*******************************************************************/ *******************************************************************/
EXPORT void CALL ControllerCommand ( int /*Control*/, uint8_t * /*Command*/) EXPORT void CALL ControllerCommand ( int /*Control*/, uint8_t * /*Command*/)
{ {
} }
@ -50,6 +52,7 @@ to give further information about the DLL.
input: a handle to the window that calls this function input: a handle to the window that calls this function
output: none output: none
*******************************************************************/ *******************************************************************/
EXPORT void CALL DllAbout ( void * hParent ) EXPORT void CALL DllAbout ( void * hParent )
{ {
#ifdef _WIN32 #ifdef _WIN32
@ -60,10 +63,11 @@ EXPORT void CALL DllAbout ( void * hParent )
/****************************************************************** /******************************************************************
Function: DllConfig Function: DllConfig
Purpose: This function is optional function that is provided Purpose: This function is optional function that is provided
to allow the user to configure the dll to allow the user to configure the DLL
input: a handle to the window that calls this function input: a handle to the window that calls this function
output: none output: none
*******************************************************************/ *******************************************************************/
EXPORT void CALL DllConfig ( void * /*hParent*/ ) EXPORT void CALL DllConfig ( void * /*hParent*/ )
{ {
} }
@ -71,10 +75,11 @@ EXPORT void CALL DllConfig ( void * /*hParent*/ )
/****************************************************************** /******************************************************************
Function: DllTest Function: DllTest
Purpose: This function is optional function that is provided Purpose: This function is optional function that is provided
to allow the user to test the dll to allow the user to test the DLL
input: a handle to the window that calls this function input: a handle to the window that calls this function
output: none output: none
*******************************************************************/ *******************************************************************/
EXPORT void CALL DllTest ( void * /*hParent*/ ) EXPORT void CALL DllTest ( void * /*hParent*/ )
{ {
} }
@ -82,19 +87,20 @@ EXPORT void CALL DllTest ( void * /*hParent*/ )
/****************************************************************** /******************************************************************
Function: GetDllInfo Function: GetDllInfo
Purpose: This function allows the emulator to gather information Purpose: This function allows the emulator to gather information
about the dll by filling in the PluginInfo structure. about the DLL by filling in the PluginInfo structure.
input: a pointer to a PLUGIN_INFO stucture that needs to be input: a pointer to a PLUGIN_INFO structure that needs to be
filled by the function. (see def above) filled by the function. (see def above)
output: none output: none
*******************************************************************/ *******************************************************************/
EXPORT void CALL GetDllInfo ( PLUGIN_INFO * PluginInfo ) EXPORT void CALL GetDllInfo ( PLUGIN_INFO * PluginInfo )
{ {
PluginInfo->Version = 0x0101; PluginInfo->Version = 0x0101;
PluginInfo->Type = PLUGIN_TYPE_CONTROLLER; PluginInfo->Type = PLUGIN_TYPE_CONTROLLER;
#ifdef _DEBUG #ifdef _DEBUG
sprintf(PluginInfo->Name, "Android Input Debug Plugin %s", VER_FILE_VERSION_STR); sprintf(PluginInfo->Name, "Android input debug plugin %s", VER_FILE_VERSION_STR);
#else #else
sprintf(PluginInfo->Name, "Android Input Plugin %s", VER_FILE_VERSION_STR); sprintf(PluginInfo->Name, "Android input plugin %s", VER_FILE_VERSION_STR);
#endif #endif
} }
@ -106,6 +112,7 @@ input: - Controller Number (0 to 3)
the controller state. the controller state.
output: none output: none
*******************************************************************/ *******************************************************************/
EXPORT void CALL GetKeys(int Control, BUTTONS * Keys ) EXPORT void CALL GetKeys(int Control, BUTTONS * Keys )
{ {
if (Control == 0) if (Control == 0)
@ -116,13 +123,14 @@ EXPORT void CALL GetKeys(int Control, BUTTONS * Keys )
/****************************************************************** /******************************************************************
Function: InitiateControllers Function: InitiateControllers
Purpose: This function initialises how each of the controllers Purpose: This function initializes how each of the controllers
should be handled. should be handled.
input: - The handle to the main window. input: - The handle to the main window.
- A controller structure that needs to be filled for - A controller structure that needs to be filled for
the emulator to know how to handle each controller. the emulator to know how to handle each controller.
output: none output: none
*******************************************************************/ *******************************************************************/
EXPORT void CALL InitiateControllers (CONTROL_INFO ControlInfo) EXPORT void CALL InitiateControllers (CONTROL_INFO ControlInfo)
{ {
g_control_info = ControlInfo; g_control_info = ControlInfo;
@ -132,36 +140,39 @@ EXPORT void CALL InitiateControllers (CONTROL_INFO ControlInfo)
/****************************************************************** /******************************************************************
Function: ReadController Function: ReadController
Purpose: To process the raw data in the pif ram that is about to Purpose: To process the raw data in the PIF RAM that is about to
be read. be read.
input: - Controller Number (0 to 3) and -1 signalling end of input: - Controller Number (0 to 3) and -1 signaling end of
processing the pif ram. processing the PIF RAM.
- Pointer of data to be processed. - Pointer of data to be processed.
output: none output: none
note: This function is only needed if the DLL is allowing raw note: This function is only needed if the DLL is allowing raw
data. data.
*******************************************************************/ *******************************************************************/
EXPORT void CALL ReadController ( int /*Control*/, uint8_t * /*Command*/ ) EXPORT void CALL ReadController ( int /*Control*/, uint8_t * /*Command*/ )
{ {
} }
/****************************************************************** /******************************************************************
Function: RomClosed Function: RomClosed
Purpose: This function is called when a rom is closed. Purpose: This function is called when a ROM is closed.
input: none input: none
output: none output: none
*******************************************************************/ *******************************************************************/
EXPORT void CALL RomClosed (void) EXPORT void CALL RomClosed (void)
{ {
} }
/****************************************************************** /******************************************************************
Function: RomOpen Function: RomOpen
Purpose: This function is called when a rom is open. (from the Purpose: This function is called when a ROM is open. (from the
emulation thread) emulation thread)
input: none input: none
output: none output: none
*******************************************************************/ *******************************************************************/
EXPORT void CALL RomOpen (void) EXPORT void CALL RomOpen (void)
{ {
memset(&g_buttons, 0, sizeof(g_buttons)); memset(&g_buttons, 0, sizeof(g_buttons));
@ -174,6 +185,7 @@ plugin.
input: wParam and lParam of the WM_KEYDOWN message. input: wParam and lParam of the WM_KEYDOWN message.
output: none output: none
*******************************************************************/ *******************************************************************/
EXPORT void CALL WM_KeyDown( uint32_t /*wParam*/, uint32_t /*lParam*/ ) EXPORT void CALL WM_KeyDown( uint32_t /*wParam*/, uint32_t /*lParam*/ )
{ {
} }
@ -185,6 +197,7 @@ plugin.
input: wParam and lParam of the WM_KEYDOWN message. input: wParam and lParam of the WM_KEYDOWN message.
output: none output: none
*******************************************************************/ *******************************************************************/
EXPORT void CALL WM_KeyUp( uint32_t /*wParam*/, uint32_t /*lParam*/ ) EXPORT void CALL WM_KeyUp( uint32_t /*wParam*/, uint32_t /*lParam*/ )
{ {
} }

View File

@ -5,8 +5,7 @@
typedef struct typedef struct
{ {
void * hInst; void * hInst;
int32_t MemoryBswaped; /* If this is set to TRUE, then the memory has been pre int32_t MemoryBswaped; // If this is set to TRUE, then the memory has been pre-bswap'd on a DWORD (32-bits) boundary
bswap on a dword (32 bits) boundry */
uint8_t * RDRAM; uint8_t * RDRAM;
uint8_t * DMEM; uint8_t * DMEM;
uint8_t * IMEM; uint8_t * IMEM;

View File

@ -5,6 +5,7 @@
// Copyright(C) 2009 Richard Goedeken // Copyright(C) 2009 Richard Goedeken
// Copyright(C) 2002 Hacktarux // Copyright(C) 2002 Hacktarux
// GNU/GPLv2 licensed: https://gnu.org/licenses/gpl-2.0.html // GNU/GPLv2 licensed: https://gnu.org/licenses/gpl-2.0.html
#include "stdafx.h" #include "stdafx.h"
#include <memory.h> #include <memory.h>
#include "alist.h" #include "alist.h"
@ -19,7 +20,8 @@ struct ramp_t
int64_t target; int64_t target;
}; };
/* local functions */ // Local functions
static void swap(int16_t **a, int16_t **b) static void swap(int16_t **a, int16_t **b)
{ {
int16_t* tmp = *b; int16_t* tmp = *b;
@ -74,7 +76,8 @@ static int16_t ramp_step(struct ramp_t* ramp)
return (int16_t)(ramp->value >> 16); return (int16_t)(ramp->value >> 16);
} }
/* global functions */ // Global functions
void alist_process(CHle * hle, const acmd_callback_t abi[], unsigned int abi_size) void alist_process(CHle * hle, const acmd_callback_t abi[], unsigned int abi_size)
{ {
uint32_t w1, w2; uint32_t w1, w2;
@ -140,7 +143,7 @@ void alist_clear(CHle * hle, uint16_t dmem, uint16_t count)
void alist_load(CHle * hle, uint16_t dmem, uint32_t address, uint16_t count) void alist_load(CHle * hle, uint16_t dmem, uint32_t address, uint16_t count)
{ {
/* enforce DMA alignment constraints */ // Enforce DMA alignment constraints
dmem &= ~3; dmem &= ~3;
address &= ~7; address &= ~7;
count = align(count, 8); count = align(count, 8);
@ -149,7 +152,7 @@ void alist_load(CHle * hle, uint16_t dmem, uint32_t address, uint16_t count)
void alist_save(CHle * hle, uint16_t dmem, uint32_t address, uint16_t count) void alist_save(CHle * hle, uint16_t dmem, uint32_t address, uint16_t count)
{ {
/* enforce DMA alignment constraints */ // Enforce DMA alignment constraints
dmem &= ~3; dmem &= ~3;
address &= ~7; address &= ~7;
count = align(count, 8); count = align(count, 8);
@ -271,19 +274,19 @@ void alist_envmix_exp( CHle * hle, bool init, bool aux, uint16_t dmem_dl, uint16
} }
else else
{ {
wet = *(int16_t *)(save_buffer + 0); /* 0-1 */ wet = *(int16_t *)(save_buffer + 0); // 0-1
dry = *(int16_t *)(save_buffer + 2); /* 2-3 */ dry = *(int16_t *)(save_buffer + 2); // 2-3
ramps[0].target = *(int32_t *)(save_buffer + 4); /* 4-5 */ ramps[0].target = *(int32_t *)(save_buffer + 4); // 4-5
ramps[1].target = *(int32_t *)(save_buffer + 6); /* 6-7 */ ramps[1].target = *(int32_t *)(save_buffer + 6); // 6-7
exp_rates[0] = *(int32_t *)(save_buffer + 8); /* 8-9 (save_buffer is a 16bit pointer) */ exp_rates[0] = *(int32_t *)(save_buffer + 8); // 8-9 (save_buffer is a 16-bit pointer)
exp_rates[1] = *(int32_t *)(save_buffer + 10); /* 10-11 */ exp_rates[1] = *(int32_t *)(save_buffer + 10); // 10-11
exp_seq[0] = *(int32_t *)(save_buffer + 12); /* 12-13 */ exp_seq[0] = *(int32_t *)(save_buffer + 12); // 12-13
exp_seq[1] = *(int32_t *)(save_buffer + 14); /* 14-15 */ exp_seq[1] = *(int32_t *)(save_buffer + 14); // 14-15
ramps[0].value = *(int32_t *)(save_buffer + 16); /* 12-13 */ ramps[0].value = *(int32_t *)(save_buffer + 16); // 12-13
ramps[1].value = *(int32_t *)(save_buffer + 18); /* 14-15 */ ramps[1].value = *(int32_t *)(save_buffer + 18); // 14-15
} }
/* init which ensure ramp.step != 0 iff ramp.value == ramp.target */ // init which ensure ramp.step != 0 iff ramp.value == ramp.target
ramps[0].step = ramps[0].target - ramps[0].value; ramps[0].step = ramps[0].target - ramps[0].value;
ramps[1].step = ramps[1].target - ramps[1].value; ramps[1].step = ramps[1].target - ramps[1].value;
@ -323,16 +326,16 @@ void alist_envmix_exp( CHle * hle, bool init, bool aux, uint16_t dmem_dl, uint16
} }
} }
*(int16_t *)(save_buffer + 0) = wet; /* 0-1 */ *(int16_t *)(save_buffer + 0) = wet; // 0-1
*(int16_t *)(save_buffer + 2) = dry; /* 2-3 */ *(int16_t *)(save_buffer + 2) = dry; // 2-3
*(int32_t *)(save_buffer + 4) = (int32_t)ramps[0].target; /* 4-5 */ *(int32_t *)(save_buffer + 4) = (int32_t)ramps[0].target; // 4-5
*(int32_t *)(save_buffer + 6) = (int32_t)ramps[1].target; /* 6-7 */ *(int32_t *)(save_buffer + 6) = (int32_t)ramps[1].target; // 6-7
*(int32_t *)(save_buffer + 8) = exp_rates[0]; /* 8-9 (save_buffer is a 16bit pointer) */ *(int32_t *)(save_buffer + 8) = exp_rates[0]; // 8-9 (save_buffer is a 16-bit pointer)
*(int32_t *)(save_buffer + 10) = exp_rates[1]; /* 10-11 */ *(int32_t *)(save_buffer + 10) = exp_rates[1]; // 10-11
*(int32_t *)(save_buffer + 12) = exp_seq[0]; /* 12-13 */ *(int32_t *)(save_buffer + 12) = exp_seq[0]; // 12-13
*(int32_t *)(save_buffer + 14) = exp_seq[1]; /* 14-15 */ *(int32_t *)(save_buffer + 14) = exp_seq[1]; // 14-15
*(int32_t *)(save_buffer + 16) = (int32_t)ramps[0].value; /* 12-13 */ *(int32_t *)(save_buffer + 16) = (int32_t)ramps[0].value; // 12-13
*(int32_t *)(save_buffer + 18) = (int32_t)ramps[1].value; /* 14-15 */ *(int32_t *)(save_buffer + 18) = (int32_t)ramps[1].value; // 14-15
memcpy(hle->dram() + address, (uint8_t *)save_buffer, sizeof(save_buffer)); memcpy(hle->dram() + address, (uint8_t *)save_buffer, sizeof(save_buffer));
} }
@ -362,16 +365,16 @@ void alist_envmix_ge( CHle * hle, bool init, bool aux, uint16_t dmem_dl, uint16_
} }
else else
{ {
wet = *(int16_t *)(save_buffer + 0); /* 0-1 */ wet = *(int16_t *)(save_buffer + 0); // 0-1
dry = *(int16_t *)(save_buffer + 2); /* 2-3 */ dry = *(int16_t *)(save_buffer + 2); // 2-3
ramps[0].target = *(int32_t *)(save_buffer + 4); /* 4-5 */ ramps[0].target = *(int32_t *)(save_buffer + 4); // 4-5
ramps[1].target = *(int32_t *)(save_buffer + 6); /* 6-7 */ ramps[1].target = *(int32_t *)(save_buffer + 6); // 6-7
ramps[0].step = *(int32_t *)(save_buffer + 8); /* 8-9 (save_buffer is a 16bit pointer) */ ramps[0].step = *(int32_t *)(save_buffer + 8); // 8-9 (save_buffer is a 16-bit pointer)
ramps[1].step = *(int32_t *)(save_buffer + 10); /* 10-11 */ ramps[1].step = *(int32_t *)(save_buffer + 10); // 10-11
/* *(int32_t *)(save_buffer + 12);*/ /* 12-13 */ /* *(int32_t *)(save_buffer + 12);*/ // 12-13
/* *(int32_t *)(save_buffer + 14);*/ /* 14-15 */ /* *(int32_t *)(save_buffer + 14);*/ // 14-15
ramps[0].value = *(int32_t *)(save_buffer + 16); /* 12-13 */ ramps[0].value = *(int32_t *)(save_buffer + 16); // 12-13
ramps[1].value = *(int32_t *)(save_buffer + 18); /* 14-15 */ ramps[1].value = *(int32_t *)(save_buffer + 18); // 14-15
} }
count >>= 1; count >>= 1;
@ -395,16 +398,16 @@ void alist_envmix_ge( CHle * hle, bool init, bool aux, uint16_t dmem_dl, uint16_
alist_envmix_mix(n, buffers, gains, in[k^S]); alist_envmix_mix(n, buffers, gains, in[k^S]);
} }
*(int16_t *)(save_buffer + 0) = wet; /* 0-1 */ *(int16_t *)(save_buffer + 0) = wet; // 0-1
*(int16_t *)(save_buffer + 2) = dry; /* 2-3 */ *(int16_t *)(save_buffer + 2) = dry; // 2-3
*(int32_t *)(save_buffer + 4) = (int32_t)ramps[0].target; /* 4-5 */ *(int32_t *)(save_buffer + 4) = (int32_t)ramps[0].target; // 4-5
*(int32_t *)(save_buffer + 6) = (int32_t)ramps[1].target; /* 6-7 */ *(int32_t *)(save_buffer + 6) = (int32_t)ramps[1].target; // 6-7
*(int32_t *)(save_buffer + 8) = (int32_t)ramps[0].step; /* 8-9 (save_buffer is a 16bit pointer) */ *(int32_t *)(save_buffer + 8) = (int32_t)ramps[0].step; // 8-9 (save_buffer is a 16-bit pointer)
*(int32_t *)(save_buffer + 10) = (int32_t)ramps[1].step; /* 10-11 */ *(int32_t *)(save_buffer + 10) = (int32_t)ramps[1].step; // 10-11
/**(int32_t *)(save_buffer + 12);*/ /* 12-13 */ /**(int32_t *)(save_buffer + 12);*/ // 12-13
/**(int32_t *)(save_buffer + 14);*/ /* 14-15 */ /**(int32_t *)(save_buffer + 14);*/ // 14-15
*(int32_t *)(save_buffer + 16) = (int32_t)ramps[0].value; /* 12-13 */ *(int32_t *)(save_buffer + 16) = (int32_t)ramps[0].value; // 12-13
*(int32_t *)(save_buffer + 18) = (int32_t)ramps[1].value; /* 14-15 */ *(int32_t *)(save_buffer + 18) = (int32_t)ramps[1].value; // 14-15
memcpy(hle->dram() + address, (uint8_t *)save_buffer, 80); memcpy(hle->dram() + address, (uint8_t *)save_buffer, 80);
} }
@ -432,14 +435,14 @@ void alist_envmix_lin(CHle * hle, bool init, uint16_t dmem_dl, uint16_t dmem_dr,
} }
else else
{ {
wet = *(int16_t *)(save_buffer + 0); /* 0-1 */ wet = *(int16_t *)(save_buffer + 0); // 0-1
dry = *(int16_t *)(save_buffer + 2); /* 2-3 */ dry = *(int16_t *)(save_buffer + 2); // 2-3
ramps[0].target = *(int16_t *)(save_buffer + 4) << 16; /* 4-5 */ ramps[0].target = *(int16_t *)(save_buffer + 4) << 16; // 4-5
ramps[1].target = *(int16_t *)(save_buffer + 6) << 16; /* 6-7 */ ramps[1].target = *(int16_t *)(save_buffer + 6) << 16; // 6-7
ramps[0].step = *(int32_t *)(save_buffer + 8); /* 8-9 (save_buffer is a 16bit pointer) */ ramps[0].step = *(int32_t *)(save_buffer + 8); // 8-9 (save_buffer is a 16-bit pointer)
ramps[1].step = *(int32_t *)(save_buffer + 10); /* 10-11 */ ramps[1].step = *(int32_t *)(save_buffer + 10); // 10-11
ramps[0].value = *(int32_t *)(save_buffer + 16); /* 16-17 */ ramps[0].value = *(int32_t *)(save_buffer + 16); // 16-17
ramps[1].value = *(int32_t *)(save_buffer + 18); /* 16-17 */ ramps[1].value = *(int32_t *)(save_buffer + 18); // 16-17
} }
count >>= 1; count >>= 1;
@ -463,14 +466,14 @@ void alist_envmix_lin(CHle * hle, bool init, uint16_t dmem_dl, uint16_t dmem_dr,
alist_envmix_mix(4, buffers, gains, in[k^S]); alist_envmix_mix(4, buffers, gains, in[k^S]);
} }
*(int16_t *)(save_buffer + 0) = wet; /* 0-1 */ *(int16_t *)(save_buffer + 0) = wet; // 0-1
*(int16_t *)(save_buffer + 2) = dry; /* 2-3 */ *(int16_t *)(save_buffer + 2) = dry; // 2-3
*(int16_t *)(save_buffer + 4) = (int16_t)(ramps[0].target >> 16); /* 4-5 */ *(int16_t *)(save_buffer + 4) = (int16_t)(ramps[0].target >> 16); // 4-5
*(int16_t *)(save_buffer + 6) = (int16_t)(ramps[1].target >> 16); /* 6-7 */ *(int16_t *)(save_buffer + 6) = (int16_t)(ramps[1].target >> 16); // 6-7
*(int32_t *)(save_buffer + 8) = (int32_t)ramps[0].step; /* 8-9 (save_buffer is a 16bit pointer) */ *(int32_t *)(save_buffer + 8) = (int32_t)ramps[0].step; // 8-9 (save_buffer is a 16-bit pointer)
*(int32_t *)(save_buffer + 10) = (int32_t)ramps[1].step; /* 10-11 */ *(int32_t *)(save_buffer + 10) = (int32_t)ramps[1].step; // 10-11
*(int32_t *)(save_buffer + 16) = (int32_t)ramps[0].value; /* 16-17 */ *(int32_t *)(save_buffer + 16) = (int32_t)ramps[0].value; // 16-17
*(int32_t *)(save_buffer + 18) = (int32_t)ramps[1].value; /* 18-19 */ *(int32_t *)(save_buffer + 18) = (int32_t)ramps[1].value; // 18-19
memcpy(hle->dram() + address, (uint8_t *)save_buffer, 80); memcpy(hle->dram() + address, (uint8_t *)save_buffer, 80);
} }
@ -499,7 +502,7 @@ void alist_envmix_nead( CHle * hle, bool swap_wet_LR, uint16_t dmem_dl, uint16_t
int16_t *wl = (int16_t*)(hle->alist_buffer() + dmem_wl); int16_t *wl = (int16_t*)(hle->alist_buffer() + dmem_wl);
int16_t *wr = (int16_t*)(hle->alist_buffer() + dmem_wr); int16_t *wr = (int16_t*)(hle->alist_buffer() + dmem_wr);
/* make sure count is a multiple of 8 */ // Make sure count is a multiple of 8
count = align(count, 8); count = align(count, 8);
if (swap_wet_LR) if (swap_wet_LR)
@ -769,7 +772,7 @@ void alist_filter( CHle * hle, uint16_t dmem,uint16_t count, uint32_t address, c
v[1] += in1[4] * lutt6[2]; v[1] += in1[4] * lutt6[2];
v[1] += in1[7] * lutt6[3]; v[1] += in1[7] * lutt6[3];
v[1] += in1[6] * lutt6[0]; v[1] += in1[6] * lutt6[0];
v[1] += in2[1] * lutt6[1]; /* 1 */ v[1] += in2[1] * lutt6[1]; // 1
v[0] = in1[3] * lutt6[6]; v[0] = in1[3] * lutt6[6];
v[0] += in1[2] * lutt6[7]; v[0] += in1[2] * lutt6[7];

View File

@ -3,6 +3,7 @@
// Copyright(C) 2001-2021 Project64 // Copyright(C) 2001-2021 Project64
// Copyright(C) 2014 Bobby Smiles // Copyright(C) 2014 Bobby Smiles
// GNU/GPLv2 licensed: https://gnu.org/licenses/gpl-2.0.html // GNU/GPLv2 licensed: https://gnu.org/licenses/gpl-2.0.html
#pragma once #pragma once
class CHle; class CHle;
@ -33,9 +34,7 @@ void alist_iirf( CHle * hle, bool init, uint16_t dmemo, uint16_t dmemi, uint16_t
void alist_resample_zoh( CHle * hle, uint16_t dmemo, uint16_t dmemi, uint16_t count, uint32_t pitch, uint32_t pitch_accu); void alist_resample_zoh( CHle * hle, uint16_t dmemo, uint16_t dmemi, uint16_t count, uint32_t pitch, uint32_t pitch_accu);
void alist_filter( CHle * hle, uint16_t dmem, uint16_t count, uint32_t address, const uint32_t* lut_address); void alist_filter( CHle * hle, uint16_t dmem, uint16_t count, uint32_t address, const uint32_t* lut_address);
/* // Audio flags
* Audio flags
*/
#define A_INIT 0x01 #define A_INIT 0x01
#define A_CONTINUE 0x00 #define A_CONTINUE 0x00

View File

@ -5,6 +5,7 @@
// Copyright(C) 2009 Richard Goedeken // Copyright(C) 2009 Richard Goedeken
// Copyright(C) 2002 Hacktarux // Copyright(C) 2002 Hacktarux
// GNU/GPLv2 licensed: https://gnu.org/licenses/gpl-2.0.html // GNU/GPLv2 licensed: https://gnu.org/licenses/gpl-2.0.html
#include "stdafx.h" #include "stdafx.h"
#include <string.h> #include <string.h>
@ -16,7 +17,8 @@
enum { DMEM_BASE = 0x5c0 }; enum { DMEM_BASE = 0x5c0 };
/* helper functions */ // Helper functions
static uint32_t get_address(CHle * hle, uint32_t so) static uint32_t get_address(CHle * hle, uint32_t so)
{ {
return alist_get_address(hle, so, hle->alist_audio().segments, N_SEGMENTS); return alist_get_address(hle, so, hle->alist_audio().segments, N_SEGMENTS);
@ -32,7 +34,8 @@ static void clear_segments(CHle * hle)
memset(hle->alist_audio().segments, 0, N_SEGMENTS*sizeof(hle->alist_audio().segments[0])); memset(hle->alist_audio().segments, 0, N_SEGMENTS*sizeof(hle->alist_audio().segments[0]));
} }
/* audio commands definition */ // Audio commands definition
static void SPNOOP(CHle * UNUSED(hle), uint32_t UNUSED(w1), uint32_t UNUSED(w2)) static void SPNOOP(CHle * UNUSED(hle), uint32_t UNUSED(w1), uint32_t UNUSED(w2))
{ {
} }
@ -142,7 +145,7 @@ static void ADPCM(CHle * hle, uint32_t w1, uint32_t w2)
hle, hle,
flags & 0x1, flags & 0x1,
flags & 0x2, flags & 0x2,
false, /* unsupported in this ucode */ false, // Unsupported in this microcode
hle->alist_audio().out, hle->alist_audio().out,
hle->alist_audio().in, hle->alist_audio().in,
align(hle->alist_audio().count, 32), align(hle->alist_audio().count, 32),
@ -260,7 +263,8 @@ static void POLEF(CHle * hle, uint32_t w1, uint32_t w2)
address); address);
} }
/* global functions */ // Global functions
void alist_process_audio(CHle * hle) void alist_process_audio(CHle * hle)
{ {
static const acmd_callback_t ABI[0x10] = { static const acmd_callback_t ABI[0x10] = {

View File

@ -5,12 +5,13 @@
// Copyright(C) 2009 Richard Goedeken // Copyright(C) 2009 Richard Goedeken
// Copyright(C) 2002 Hacktarux // Copyright(C) 2002 Hacktarux
// GNU/GPLv2 licensed: https://gnu.org/licenses/gpl-2.0.html // GNU/GPLv2 licensed: https://gnu.org/licenses/gpl-2.0.html
#include "stdafx.h" #include "stdafx.h"
#include "alist.h" #include "alist.h"
#include "mem.h" #include "mem.h"
enum { NAUDIO_COUNT = 0x170 }; /* ie 184 samples */ enum { NAUDIO_COUNT = 0x170 }; // i.e. 184 samples
enum { enum {
NAUDIO_MAIN = 0x4f0, NAUDIO_MAIN = 0x4f0,
NAUDIO_MAIN2 = 0x660, NAUDIO_MAIN2 = 0x660,
@ -20,7 +21,8 @@ enum {
NAUDIO_WET_RIGHT = 0xe20 NAUDIO_WET_RIGHT = 0xe20
}; };
/* audio commands definition */ // Audio commands definition
static void UNKNOWN(CHle * hle, uint32_t w1, uint32_t w2) static void UNKNOWN(CHle * hle, uint32_t w1, uint32_t w2)
{ {
uint8_t acmd = (w1 >> 24); uint8_t acmd = (w1 >> 24);
@ -40,7 +42,7 @@ static void NAUDIO_0000(CHle * hle, uint32_t w1, uint32_t w2)
static void NAUDIO_02B0(CHle * hle, uint32_t UNUSED(w1), uint32_t w2) static void NAUDIO_02B0(CHle * hle, uint32_t UNUSED(w1), uint32_t w2)
{ {
/* emulate code at 0x12b0 (inside SETVOL), because PC always execute in IMEM */ // Emulate code at 0x12b0 (inside SETVOL), because PC always execute in IMEM
hle->alist_naudio().rate[1] &= ~0xffff; hle->alist_naudio().rate[1] &= ~0xffff;
hle->alist_naudio().rate[1] |= (w2 & 0xffff); hle->alist_naudio().rate[1] |= (w2 & 0xffff);
} }
@ -179,7 +181,7 @@ static void ADPCM(CHle * hle, uint32_t w1, uint32_t w2)
hle, hle,
flags & 0x1, flags & 0x1,
flags & 0x2, flags & 0x2,
false, /* unsuported by this ucode */ false, // Unsupported by this microcode
dmemo, dmemo,
dmemi, dmemi,
(count + 0x1f) & ~0x1f, (count + 0x1f) & ~0x1f,
@ -199,7 +201,7 @@ static void RESAMPLE(CHle * hle, uint32_t w1, uint32_t w2)
alist_resample( alist_resample(
hle, hle,
flags & 0x1, flags & 0x1,
false, /* TODO: check which ABI supports it */ false, // TODO: check which ABI supports it
dmemo, dmemo,
dmemi, dmemi,
NAUDIO_COUNT, NAUDIO_COUNT,
@ -224,7 +226,8 @@ static void MP3(CHle * hle, uint32_t w1, uint32_t w2)
mp3_task(hle, index, address); mp3_task(hle, index, address);
} }
/* global functions */ // Global functions
void alist_process_naudio(CHle * hle) void alist_process_naudio(CHle * hle)
{ {
static const acmd_callback_t ABI[0x10] = static const acmd_callback_t ABI[0x10] =
@ -240,7 +243,8 @@ void alist_process_naudio(CHle * hle)
void alist_process_naudio_bk(CHle * hle) void alist_process_naudio_bk(CHle * hle)
{ {
/* TODO: see what differs from alist_process_naudio */ // TODO: see what differs from alist_process_naudio
static const acmd_callback_t ABI[0x10] = { static const acmd_callback_t ABI[0x10] = {
SPNOOP, ADPCM, CLEARBUFF, ENVMIXER, SPNOOP, ADPCM, CLEARBUFF, ENVMIXER,
LOADBUFF, RESAMPLE, SAVEBUFF, NAUDIO_0000, LOADBUFF, RESAMPLE, SAVEBUFF, NAUDIO_0000,
@ -253,7 +257,8 @@ void alist_process_naudio_bk(CHle * hle)
void alist_process_naudio_dk(CHle * hle) void alist_process_naudio_dk(CHle * hle)
{ {
/* TODO: see what differs from alist_process_naudio */ // TODO: see what differs from alist_process_naudio
static const acmd_callback_t ABI[0x10] = { static const acmd_callback_t ABI[0x10] = {
SPNOOP, ADPCM, CLEARBUFF, ENVMIXER, SPNOOP, ADPCM, CLEARBUFF, ENVMIXER,
LOADBUFF, RESAMPLE, SAVEBUFF, MIXER, LOADBUFF, RESAMPLE, SAVEBUFF, MIXER,
@ -278,7 +283,8 @@ void alist_process_naudio_mp3(CHle * hle)
void alist_process_naudio_cbfd(CHle * hle) void alist_process_naudio_cbfd(CHle * hle)
{ {
/* TODO: see what differs from alist_process_naudio_mp3 */ // TODO: see what differs from alist_process_naudio_mp3
static const acmd_callback_t ABI[0x10] = { static const acmd_callback_t ABI[0x10] = {
UNKNOWN, ADPCM, CLEARBUFF, ENVMIXER, UNKNOWN, ADPCM, CLEARBUFF, ENVMIXER,
LOADBUFF, RESAMPLE, SAVEBUFF, MP3, LOADBUFF, RESAMPLE, SAVEBUFF, MP3,

View File

@ -5,12 +5,14 @@
// Copyright(C) 2009 Richard Goedeken // Copyright(C) 2009 Richard Goedeken
// Copyright(C) 2002 Hacktarux // Copyright(C) 2002 Hacktarux
// GNU/GPLv2 licensed: https://gnu.org/licenses/gpl-2.0.html // GNU/GPLv2 licensed: https://gnu.org/licenses/gpl-2.0.html
#include "stdafx.h" #include "stdafx.h"
#include "alist.h" #include "alist.h"
#include "mem.h" #include "mem.h"
/* audio commands definition */ // Audio commands definition
static void UNKNOWN(CHle * hle, uint32_t w1, uint32_t w2) static void UNKNOWN(CHle * hle, uint32_t w1, uint32_t w2)
{ {
uint8_t acmd = (w1 >> 24); uint8_t acmd = (w1 >> 24);
@ -107,7 +109,7 @@ static void RESAMPLE(CHle * hle, uint32_t w1, uint32_t w2)
alist_resample( alist_resample(
hle, hle,
flags & 0x1, flags & 0x1,
false, /* TODO: check which ABI supports it */ false, // TODO: check which ABI supports it
hle->alist_nead().out, hle->alist_nead().out,
hle->alist_nead().in, hle->alist_nead().in,
(hle->alist_nead().count + 0xf) & ~0xf, (hle->alist_nead().count + 0xf) & ~0xf,
@ -174,14 +176,14 @@ static void ENVMIXER_MK(CHle * hle, uint32_t w1, uint32_t w2)
uint16_t dmem_wl = (w2 >> 4) & 0xff0; uint16_t dmem_wl = (w2 >> 4) & 0xff0;
uint16_t dmem_wr = (w2 << 4) & 0xff0; uint16_t dmem_wr = (w2 << 4) & 0xff0;
xors[2] = 0; /* unsupported by this ucode */ xors[2] = 0; // Unsupported by this microcode
xors[3] = 0; /* unsupported by this ucode */ xors[3] = 0; // Unsupported by this microcode
xors[0] = 0 - (int16_t)((w1 & 0x2) >> 1); xors[0] = 0 - (int16_t)((w1 & 0x2) >> 1);
xors[1] = 0 - (int16_t)((w1 & 0x1) ); xors[1] = 0 - (int16_t)((w1 & 0x1) );
alist_envmix_nead( alist_envmix_nead(
hle, hle,
false, /* unsupported by this ucode */ false, // Unsupported by this microcode
dmem_dl, dmem_dr, dmem_dl, dmem_dr,
dmem_wl, dmem_wr, dmem_wl, dmem_wr,
dmemi, count, dmemi, count,
@ -268,7 +270,7 @@ static void ADDMIXER(CHle * hle, uint32_t w1, uint32_t w2)
static void HILOGAIN(CHle * hle, uint32_t w1, uint32_t w2) static void HILOGAIN(CHle * hle, uint32_t w1, uint32_t w2)
{ {
int8_t gain = (w1 >> 16); /* Q4.4 signed */ int8_t gain = (w1 >> 16); // Q4.4 signed
uint16_t count = w1; uint16_t count = w1;
uint16_t dmem = (w2 >> 16); uint16_t dmem = (w2 >> 16);
@ -282,12 +284,12 @@ static void FILTER(CHle * hle, uint32_t w1, uint32_t w2)
if (flags > 1) { if (flags > 1) {
hle->alist_nead().filter_count = w1; hle->alist_nead().filter_count = w1;
hle->alist_nead().filter_lut_address[0] = address; /* t6 */ hle->alist_nead().filter_lut_address[0] = address; // t6
} }
else { else {
uint16_t dmem = w1; uint16_t dmem = w1;
hle->alist_nead().filter_lut_address[1] = address + 0x10; /* t5 */ hle->alist_nead().filter_lut_address[1] = address + 0x10; // t5
alist_filter(hle, dmem, hle->alist_nead().filter_count, address, hle->alist_nead().filter_lut_address); alist_filter(hle, dmem, hle->alist_nead().filter_count, address, hle->alist_nead().filter_lut_address);
} }
} }

View File

@ -3,6 +3,7 @@
// Copyright(C) 2001-2021 Project64 // Copyright(C) 2001-2021 Project64
// Copyright(C) 2014 Bobby Smiles // Copyright(C) 2014 Bobby Smiles
// GNU/GPLv2 licensed: https://gnu.org/licenses/gpl-2.0.html // GNU/GPLv2 licensed: https://gnu.org/licenses/gpl-2.0.html
#pragma once #pragma once
static inline int16_t clamp_s16(int_fast32_t x) static inline int16_t clamp_s16(int_fast32_t x)

View File

@ -3,6 +3,7 @@
// Copyright(C) 2001-2021 Project64 // Copyright(C) 2001-2021 Project64
// Copyright(C) 2014 Bobby Smiles // Copyright(C) 2014 Bobby Smiles
// GNU/GPLv2 licensed: https://gnu.org/licenses/gpl-2.0.html // GNU/GPLv2 licensed: https://gnu.org/licenses/gpl-2.0.html
#include "stdafx.h" #include "stdafx.h"
#include <assert.h> #include <assert.h>
#include "audio.h" #include "audio.h"

View File

@ -3,6 +3,7 @@
// Copyright(C) 2001-2021 Project64 // Copyright(C) 2001-2021 Project64
// Copyright(C) 2014 Bobby Smiles // Copyright(C) 2014 Bobby Smiles
// GNU/GPLv2 licensed: https://gnu.org/licenses/gpl-2.0.html // GNU/GPLv2 licensed: https://gnu.org/licenses/gpl-2.0.html
#pragma once #pragma once
extern const int16_t RESAMPLE_LUT[64 * 4]; extern const int16_t RESAMPLE_LUT[64 * 4];
@ -13,7 +14,7 @@ static inline int16_t adpcm_predict_sample(uint8_t byte, uint8_t mask,
unsigned lshift, unsigned rshift) unsigned lshift, unsigned rshift)
{ {
int16_t sample = (uint16_t)(byte & mask) << lshift; int16_t sample = (uint16_t)(byte & mask) << lshift;
sample >>= rshift; /* signed */ sample >>= rshift; // signed
return sample; return sample;
} }

View File

@ -5,28 +5,30 @@
// Copyright(C) 2009 Richard Goedeken // Copyright(C) 2009 Richard Goedeken
// Copyright(C) 2002 Hacktarux // Copyright(C) 2002 Hacktarux
// GNU/GPLv2 licensed: https://gnu.org/licenses/gpl-2.0.html // GNU/GPLv2 licensed: https://gnu.org/licenses/gpl-2.0.html
#include "stdafx.h" #include "stdafx.h"
#include <string.h> #include <string.h>
/** /*
* During IPL3 stage of CIC x105 games, the RSP performs some checks and transactions During IPL3 stage of CIC x105 games, the RSP performs some checks and transactions
* necessary for booting the game. necessary for booting the game.
*
* We only implement the needed DMA transactions for booting. We only implement the needed DMA transactions for booting.
*
* Found in Banjo-Tooie, Zelda, Perfect Dark, ...) Found in Banjo-Tooie, Zelda, Perfect Dark, ...)
**/ */
void cicx105_ucode(CHle * hle) void cicx105_ucode(CHle * hle)
{ {
/* memcpy is okay to use because access constrains are met (alignment, size) */ // memcpy is okay to use because access constraints are met (alignment, size)
unsigned int i; unsigned int i;
unsigned char *dst = hle->dram() + 0x2fb1f0; unsigned char *dst = hle->dram() + 0x2fb1f0;
unsigned char *src = hle->imem() + 0x120; unsigned char *src = hle->imem() + 0x120;
/* dma_read(0x1120, 0x1e8, 0x1e8) */ // dma_read(0x1120, 0x1e8, 0x1e8)
memcpy(hle->imem() + 0x120, hle->dram() + 0x1e8, 0x1f0); memcpy(hle->imem() + 0x120, hle->dram() + 0x1e8, 0x1f0);
/* dma_write(0x1120, 0x2fb1f0, 0xfe817000) */ // dma_write(0x1120, 0x2fb1f0, 0xfe817000)
for (i = 0; i < 24; ++i) for (i = 0; i < 24; ++i)
{ {
memcpy(dst, src, 8); memcpy(dst, src, 8);

View File

@ -5,21 +5,22 @@
// Copyright(C) 2009 Richard Goedeken // Copyright(C) 2009 Richard Goedeken
// Copyright(C) 2002 Hacktarux // Copyright(C) 2002 Hacktarux
// GNU/GPLv2 licensed: https://gnu.org/licenses/gpl-2.0.html // GNU/GPLv2 licensed: https://gnu.org/licenses/gpl-2.0.html
#pragma once #pragma once
/* macro for unused variable warning suppression */ // Macro for unused variable warning suppression
#ifdef __GNUC__ #ifdef __GNUC__
# define UNUSED(x) UNUSED_ ## x __attribute__((__unused__)) # define UNUSED(x) UNUSED_ ## x __attribute__((__unused__))
#else #else
# define UNUSED(x) /* x */ # define UNUSED(x) /* x */
#endif #endif
/* macro for inline keyword */ // Macro for inline keyword
#ifdef _MSC_VER #ifdef _MSC_VER
#define inline __inline #define inline __inline
#endif #endif
/* Dll function linking */ // DLL function linking
#if defined(_WIN32) #if defined(_WIN32)
#define EXPORT extern "C" __declspec(dllexport) #define EXPORT extern "C" __declspec(dllexport)
#define CALL __cdecl #define CALL __cdecl
@ -28,7 +29,7 @@
#define CALL #define CALL
#endif #endif
/* Plugin types */ // Plugin types
enum enum
{ {
PLUGIN_TYPE_RSP = 1, PLUGIN_TYPE_RSP = 1,
@ -37,17 +38,14 @@ enum
PLUGIN_TYPE_CONTROLLER = 4, PLUGIN_TYPE_CONTROLLER = 4,
}; };
/***** Structures *****/ // Structures
typedef struct typedef struct
{ {
uint16_t Version; /* Should be set to 0x0101 */ uint16_t Version; // Should be set to 0x0101
uint16_t Type; /* Set to PLUGIN_TYPE_RSP */ uint16_t Type; // Set to PLUGIN_TYPE_RSP
char Name[100]; /* Name of the DLL */ char Name[100]; // Name of the DLL
/* If DLL supports memory these memory options then set them to TRUE or FALSE // If DLL supports memory, these memory options then set them to TRUE or FALSE if it does not support it
if it does not support it */ int NormalMemory; // A normal BYTE array
int NormalMemory; /* a normal BYTE array */ int MemoryBswaped; // A normal BYTE array where the memory has been pre-bswap'd on a DWORD (32-bits) boundary
int MemoryBswaped; /* a normal BYTE array where the memory has been pre
bswap on a dword (32 bits) boundry */
} PLUGIN_INFO; } PLUGIN_INFO;

View File

@ -5,6 +5,7 @@
// Copyright(C) 2009 Richard Goedeken // Copyright(C) 2009 Richard Goedeken
// Copyright(C) 2002 Hacktarux // Copyright(C) 2002 Hacktarux
// GNU/GPLv2 licensed: https://gnu.org/licenses/gpl-2.0.html // GNU/GPLv2 licensed: https://gnu.org/licenses/gpl-2.0.html
#include "stdafx.h" #include "stdafx.h"
#include "mem.h" #include "mem.h"
#include "ucodes.h" #include "ucodes.h"
@ -12,7 +13,8 @@
#define min(a,b) (((a) < (b)) ? (a) : (b)) #define min(a,b) (((a) < (b)) ? (a) : (b))
/* helper functions prototypes */ // Helper functions prototypes
static unsigned int sum_bytes(const uint8_t *bytes, uint32_t size); static unsigned int sum_bytes(const uint8_t *bytes, uint32_t size);
CHle::CHle(const RSP_INFO & Rsp_Info) : CHle::CHle(const RSP_INFO & Rsp_Info) :
@ -88,7 +90,8 @@ void CHle::hle_execute(void)
} }
} }
/* local functions */ // Local functions
static unsigned int sum_bytes(const uint8_t * bytes, unsigned int size) static unsigned int sum_bytes(const uint8_t * bytes, unsigned int size)
{ {
unsigned int sum = 0; unsigned int sum = 0;
@ -101,16 +104,19 @@ static unsigned int sum_bytes(const uint8_t * bytes, unsigned int size)
return sum; return sum;
} }
/** /*
* Try to figure if the RSP was launched using osSpTask* functions TODO:
* and not run directly (in which case DMEM[0xfc0-0xfff] is meaningless).
* Try to figure if the RSP was launched using osSpTask* functions
* Previously, the ucode_size field was used to determine this, and not run directly (in which case DMEM[0xfc0-0xfff] is meaningless).
* but it is not robust enough (hi Pokemon Stadium !) because games could write anything
* in this field : most ucode_boot discard the value and just use 0xf7f anyway. Previously, the ucode_size field was used to determine this,
* but it is not robust enough (hi Pokémon Stadium!) because games could write anything
* Using ucode_boot_size should be more robust in this regard. in this field: most ucode_boot discard the value and just use 0xf7f anyway.
**/
Using ucode_boot_size should be more robust in this regard.
*/
bool CHle::is_task(void) bool CHle::is_task(void)
{ {
return (*dmem_u32(this, TASK_UCODE_BOOT_SIZE) <= 0x1000); return (*dmem_u32(this, TASK_UCODE_BOOT_SIZE) <= 0x1000);
@ -118,7 +124,7 @@ bool CHle::is_task(void)
bool CHle::try_fast_task_dispatching(void) bool CHle::try_fast_task_dispatching(void)
{ {
/* identify task ucode by its type */ // Identify task microcode by its type
switch (*dmem_u32(this, TASK_TYPE)) switch (*dmem_u32(this, TASK_TYPE))
{ {
case 1: case 1:
@ -148,7 +154,7 @@ bool CHle::try_fast_task_dispatching(void)
bool CHle::try_fast_audio_dispatching(void) bool CHle::try_fast_audio_dispatching(void)
{ {
/* identify audio ucode by using the content of ucode_data */ // Identify audio microcode by using the content of ucode_data
uint32_t ucode_data = *dmem_u32(this, TASK_UCODE_DATA); uint32_t ucode_data = *dmem_u32(this, TASK_UCODE_DATA);
uint32_t v; uint32_t v;
@ -159,13 +165,13 @@ bool CHle::try_fast_audio_dispatching(void)
v = *dram_u32(this, ucode_data + 0x28); v = *dram_u32(this, ucode_data + 0x28);
switch (v) switch (v)
{ {
case 0x1e24138c: /* audio ABI (most common) */ case 0x1e24138c: // Audio ABI (most common)
alist_process_audio(this); alist_process_audio(this);
return true; return true;
case 0x1dc8138c: /* GoldenEye */ case 0x1dc8138c: // GoldenEye 007
alist_process_audio_ge(this); alist_process_audio_ge(this);
return true; return true;
case 0x1e3c1390: /* BlastCorp, DiddyKongRacing */ case 0x1e3c1390: // Blast Corp, Diddy Kong Racing
alist_process_audio_bc(this); alist_process_audio_bc(this);
return true; return true;
default: default:
@ -177,40 +183,40 @@ bool CHle::try_fast_audio_dispatching(void)
v = *dram_u32(this, ucode_data + 0x10); v = *dram_u32(this, ucode_data + 0x10);
switch (v) switch (v)
{ {
case 0x11181350: /* MarioKart, WaveRace (E) */ case 0x11181350: // Mario Kart, Wave Race (E)
alist_process_nead_mk(this); alist_process_nead_mk(this);
return true; return true;
case 0x111812e0: /* StarFox (J) */ case 0x111812e0: // StarFox 64 (J)
alist_process_nead_sfj(this); alist_process_nead_sfj(this);
return true; return true;
case 0x110412ac: /* WaveRace (J RevB) */ case 0x110412ac: // Wave Race (J Rev B)
alist_process_nead_wrjb(this); alist_process_nead_wrjb(this);
return true; return true;
case 0x110412cc: /* StarFox/LylatWars (except J) */ case 0x110412cc: // StarFox/LylatWars (except J)
alist_process_nead_sf(this); alist_process_nead_sf(this);
return true; return true;
case 0x1cd01250: /* FZeroX */ case 0x1cd01250: // F-Zero X
alist_process_nead_fz(this); alist_process_nead_fz(this);
return true; return true;
case 0x1f08122c: /* YoshisStory */ case 0x1f08122c: // Yoshi's Story
alist_process_nead_ys(this); alist_process_nead_ys(this);
return true; return true;
case 0x1f38122c: /* 1080° Snowboarding */ case 0x1f38122c: // 1080° Snowboarding
alist_process_nead_1080(this); alist_process_nead_1080(this);
return true; return true;
case 0x1f681230: /* Zelda OoT / Zelda MM (J, J RevA) */ case 0x1f681230: // Zelda Ocarina of Time / Zelda Majora's Mask (J, J Rev A)
alist_process_nead_oot(this); alist_process_nead_oot(this);
return true; return true;
case 0x1f801250: /* Zelda MM (except J, J RevA, E Beta), PokemonStadium 2 */ case 0x1f801250: // Zelda Majora's Mask (except J, J Rev A, E Beta), Pokémon Stadium 2
alist_process_nead_mm(this); alist_process_nead_mm(this);
return true; return true;
case 0x109411f8: /* Zelda MM (E Beta) */ case 0x109411f8: // Zelda Majora's Mask (E Beta)
alist_process_nead_mmb(this); alist_process_nead_mmb(this);
return true; return true;
case 0x1eac11b8: /* AnimalCrossing */ case 0x1eac11b8: // Animal Crossing
alist_process_nead_ac(this); alist_process_nead_ac(this);
return true; return true;
case 0x00010010: /* MusyX v2 (IndianaJones, BattleForNaboo) */ case 0x00010010: // MusyX v2 (Indiana Jones, Battle For Naboo)
musyx_v2_task(this); musyx_v2_task(this);
return true; return true;
default: default:
@ -224,24 +230,24 @@ bool CHle::try_fast_audio_dispatching(void)
switch (v) switch (v)
{ {
case 0x00000001: /* MusyX v1 case 0x00000001: /* MusyX v1
RogueSquadron, ResidentEvil2, PolarisSnoCross, Rogue Squadron, Resident Evil 2, Polaris Sno Cross,
TheWorldIsNotEnough, RugratsInParis, NBAShowTime, The World Is Not Enough, Rugrats In Paris, NBA Show Time,
HydroThunder, Tarzan, GauntletLegend, Rush2049 */ Hydro Thunder, Tarzan, Gauntlet Legend, Rush 2049 */
musyx_v1_task(this); musyx_v1_task(this);
return true; return true;
case 0x0000127c: /* naudio (many games) */ case 0x0000127c: // naudio (many games)
alist_process_naudio(this); alist_process_naudio(this);
return true; return true;
case 0x00001280: /* BanjoKazooie */ case 0x00001280: // Banjo Kazooie
alist_process_naudio_bk(this); alist_process_naudio_bk(this);
return true; return true;
case 0x1c58126c: /* DonkeyKong */ case 0x1c58126c: // Donkey Kong
alist_process_naudio_dk(this); alist_process_naudio_dk(this);
return true; return true;
case 0x1ae8143c: /* BanjoTooie, JetForceGemini, MickeySpeedWayUSA, PerfectDark */ case 0x1ae8143c: // Banjo Tooie, Jet Force Gemini, Mickey SpeedWay USA, Perfect Dark
alist_process_naudio_mp3(this); alist_process_naudio_mp3(this);
return true; return true;
case 0x1ab0140c: /* ConkerBadFurDay */ case 0x1ab0140c: // Conker's Bad Fur Day
alist_process_naudio_cbfd(this); alist_process_naudio_cbfd(this);
return true; return true;
default: default:
@ -257,12 +263,12 @@ void CHle::normal_task_dispatching(void)
sum_bytes((const uint8_t *)dram_u32(this, *dmem_u32(this, TASK_UCODE)), min(*dmem_u32(this, TASK_UCODE_SIZE), 0xf80) >> 1); sum_bytes((const uint8_t *)dram_u32(this, *dmem_u32(this, TASK_UCODE)), min(*dmem_u32(this, TASK_UCODE_SIZE), 0xf80) >> 1);
switch (sum) { switch (sum) {
/* StoreVe12: found in Zelda Ocarina of Time [misleading task->type == 4] */ // StoreVe12: found in Zelda Ocarina of Time [misleading task->type == 4]
case 0x278: case 0x278:
/* Nothing to emulate */ // Nothing to emulate
return; return;
/* GFX: Twintris [misleading task->type == 0] */ // GFX: Twintris [misleading task->type == 0]
case 0x212ee: case 0x212ee:
if (m_ForwardGFX) if (m_ForwardGFX)
{ {
@ -271,17 +277,17 @@ void CHle::normal_task_dispatching(void)
} }
break; break;
/* JPEG: found in Pokemon Stadium J */ // JPEG: found in Pokémon Stadium J
case 0x2c85a: case 0x2c85a:
jpeg_decode_PS0(this); jpeg_decode_PS0(this);
return; return;
/* JPEG: found in Zelda Ocarina of Time, Pokemon Stadium 1, Pokemon Stadium 2 */ // JPEG: found in Zelda Ocarina of Time, Pokémon Stadium 1, Pokémon Stadium 2
case 0x2caa6: case 0x2caa6:
jpeg_decode_PS(this); jpeg_decode_PS(this);
return; return;
/* JPEG: found in Ogre Battle, Bottom of the 9th */ // JPEG: found in Ogre Battle, Bottom of the 9th
case 0x130de: case 0x130de:
case 0x278b0: case 0x278b0:
jpeg_decode_OB(this); jpeg_decode_OB(this);
@ -300,7 +306,7 @@ void CHle::non_task_dispatching(void)
if (sum == 0x9e2) if (sum == 0x9e2)
{ {
/* CIC x105 ucode (used during boot of CIC x105 games) */ // CIC x105 microcode (used during boot of CIC x105 games)
cicx105_ucode(this); cicx105_ucode(this);
return; return;
} }
@ -320,7 +326,7 @@ void CHle::VerboseMessage(const char *message, ...)
#if defined(_WIN32) && defined(_DEBUG) #if defined(_WIN32) && defined(_DEBUG)
// These can get annoying. // These can get annoying.
#if 0 #if 0
MessageBox(NULL, message, "HLE Verbose Message", MB_OK); MessageBox(NULL, message, "HLE verbose message", MB_OK);
#endif #endif
#endif #endif
} }
@ -328,6 +334,6 @@ void CHle::VerboseMessage(const char *message, ...)
void CHle::WarnMessage(const char *message, ...) void CHle::WarnMessage(const char *message, ...)
{ {
#if defined(_WIN32) && defined(_DEBUG) #if defined(_WIN32) && defined(_DEBUG)
MessageBoxA(NULL, message, "HLE Warning Message", MB_OK); MessageBoxA(NULL, message, "HLE warning message", MB_OK);
#endif #endif
} }

View File

@ -9,61 +9,63 @@
#include "Rsp.h" #include "Rsp.h"
#include "ucodes.h" #include "ucodes.h"
//Signal Processor interface flags // Signal processor interface flags
enum enum
{ {
SP_CLR_HALT = 0x00001, /* Bit 0: clear halt */ SP_CLR_HALT = 0x00001, /* Bit 0: Clear halt */
SP_SET_HALT = 0x00002, /* Bit 1: set halt */ SP_SET_HALT = 0x00002, /* Bit 1: Set halt */
SP_CLR_BROKE = 0x00004, /* Bit 2: clear broke */ SP_CLR_BROKE = 0x00004, /* Bit 2: Clear broke */
SP_CLR_INTR = 0x00008, /* Bit 3: clear intr */ SP_CLR_INTR = 0x00008, /* Bit 3: Clear INTR */
SP_SET_INTR = 0x00010, /* Bit 4: set intr */ SP_SET_INTR = 0x00010, /* Bit 4: Set INTR */
SP_CLR_SSTEP = 0x00020, /* Bit 5: clear sstep */ SP_CLR_SSTEP = 0x00020, /* Bit 5: Clear SSTEP */
SP_SET_SSTEP = 0x00040, /* Bit 6: set sstep */ SP_SET_SSTEP = 0x00040, /* Bit 6: Set SSTEP */
SP_CLR_INTR_BREAK = 0x00080, /* Bit 7: clear intr on break */ SP_CLR_INTR_BREAK = 0x00080, /* Bit 7: Clear INTR on break */
SP_SET_INTR_BREAK = 0x00100, /* Bit 8: set intr on break */ SP_SET_INTR_BREAK = 0x00100, /* Bit 8: Set INTR on break */
SP_CLR_SIG0 = 0x00200, /* Bit 9: clear signal 0 */ SP_CLR_SIG0 = 0x00200, /* Bit 9: Clear signal 0 */
SP_SET_SIG0 = 0x00400, /* Bit 10: set signal 0 */ SP_SET_SIG0 = 0x00400, /* Bit 10: Set signal 0 */
SP_CLR_SIG1 = 0x00800, /* Bit 11: clear signal 1 */ SP_CLR_SIG1 = 0x00800, /* Bit 11: Clear signal 1 */
SP_SET_SIG1 = 0x01000, /* Bit 12: set signal 1 */ SP_SET_SIG1 = 0x01000, /* Bit 12: Set signal 1 */
SP_CLR_SIG2 = 0x02000, /* Bit 13: clear signal 2 */ SP_CLR_SIG2 = 0x02000, /* Bit 13: Clear signal 2 */
SP_SET_SIG2 = 0x04000, /* Bit 14: set signal 2 */ SP_SET_SIG2 = 0x04000, /* Bit 14: Set signal 2 */
SP_CLR_SIG3 = 0x08000, /* Bit 15: clear signal 3 */ SP_CLR_SIG3 = 0x08000, /* Bit 15: Clear signal 3 */
SP_SET_SIG3 = 0x10000, /* Bit 16: set signal 3 */ SP_SET_SIG3 = 0x10000, /* Bit 16: Set signal 3 */
SP_CLR_SIG4 = 0x20000, /* Bit 17: clear signal 4 */ SP_CLR_SIG4 = 0x20000, /* Bit 17: Clear signal 4 */
SP_SET_SIG4 = 0x40000, /* Bit 18: set signal 4 */ SP_SET_SIG4 = 0x40000, /* Bit 18: Set signal 4 */
SP_CLR_SIG5 = 0x80000, /* Bit 19: clear signal 5 */ SP_CLR_SIG5 = 0x80000, /* Bit 19: Clear signal 5 */
SP_SET_SIG5 = 0x100000, /* Bit 20: set signal 5 */ SP_SET_SIG5 = 0x100000, /* Bit 20: Set signal 5 */
SP_CLR_SIG6 = 0x200000, /* Bit 21: clear signal 6 */ SP_CLR_SIG6 = 0x200000, /* Bit 21: Clear signal 6 */
SP_SET_SIG6 = 0x400000, /* Bit 22: set signal 6 */ SP_SET_SIG6 = 0x400000, /* Bit 22: Set signal 6 */
SP_CLR_SIG7 = 0x800000, /* Bit 23: clear signal 7 */ SP_CLR_SIG7 = 0x800000, /* Bit 23: Clear signal 7 */
SP_SET_SIG7 = 0x1000000, /* Bit 24: set signal 7 */ SP_SET_SIG7 = 0x1000000, /* Bit 24: Set signal 7 */
SP_STATUS_HALT = 0x001, /* Bit 0: halt */ SP_STATUS_HALT = 0x001, /* Bit 0: Halt */
SP_STATUS_BROKE = 0x002, /* Bit 1: broke */ SP_STATUS_BROKE = 0x002, /* Bit 1: Broke */
SP_STATUS_DMA_BUSY = 0x004, /* Bit 2: dma busy */ SP_STATUS_DMA_BUSY = 0x004, /* Bit 2: DMA busy */
SP_STATUS_DMA_FULL = 0x008, /* Bit 3: dma full */ SP_STATUS_DMA_FULL = 0x008, /* Bit 3: DMA full */
SP_STATUS_IO_FULL = 0x010, /* Bit 4: io full */ SP_STATUS_IO_FULL = 0x010, /* Bit 4: IO full */
SP_STATUS_SSTEP = 0x020, /* Bit 5: single step */ SP_STATUS_SSTEP = 0x020, /* Bit 5: Single step */
SP_STATUS_INTR_BREAK = 0x040, /* Bit 6: interrupt on break */ SP_STATUS_INTR_BREAK = 0x040, /* Bit 6: Interrupt on break */
SP_STATUS_SIG0 = 0x080, /* Bit 7: signal 0 set */ SP_STATUS_SIG0 = 0x080, /* Bit 7: Signal 0 set */
SP_STATUS_SIG1 = 0x100, /* Bit 8: signal 1 set */ SP_STATUS_SIG1 = 0x100, /* Bit 8: Signal 1 set */
SP_STATUS_SIG2 = 0x200, /* Bit 9: signal 2 set */ SP_STATUS_SIG2 = 0x200, /* Bit 9: Signal 2 set */
SP_STATUS_SIG3 = 0x400, /* Bit 10: signal 3 set */ SP_STATUS_SIG3 = 0x400, /* Bit 10: Signal 3 set */
SP_STATUS_SIG4 = 0x800, /* Bit 11: signal 4 set */ SP_STATUS_SIG4 = 0x800, /* Bit 11: Signal 4 set */
SP_STATUS_SIG5 = 0x1000, /* Bit 12: signal 5 set */ SP_STATUS_SIG5 = 0x1000, /* Bit 12: Signal 5 set */
SP_STATUS_SIG6 = 0x2000, /* Bit 13: signal 6 set */ SP_STATUS_SIG6 = 0x2000, /* Bit 13: Signal 6 set */
SP_STATUS_SIG7 = 0x4000, /* Bit 14: signal 7 set */ SP_STATUS_SIG7 = 0x4000, /* Bit 14: Signal 7 set */
}; };
//Mips interface flags // MIPS interface flags
enum enum
{ {
MI_INTR_SP = 0x01, /* Bit 0: SP intr */ MI_INTR_SP = 0x01, /* Bit 0: SP INTR */
MI_INTR_SI = 0x02, /* Bit 1: SI intr */ MI_INTR_SI = 0x02, /* Bit 1: SI INTR */
MI_INTR_AI = 0x04, /* Bit 2: AI intr */ MI_INTR_AI = 0x04, /* Bit 2: AI INTR */
MI_INTR_VI = 0x08, /* Bit 3: VI intr */ MI_INTR_VI = 0x08, /* Bit 3: VI INTR */
MI_INTR_PI = 0x10, /* Bit 4: PI intr */ MI_INTR_PI = 0x10, /* Bit 4: PI INTR */
MI_INTR_DP = 0x20, /* Bit 5: DP intr */ MI_INTR_DP = 0x20, /* Bit 5: DP INTR */
}; };
class CHle class CHle
@ -134,19 +136,19 @@ private:
void(*m_ProcessRdpList)(void); void(*m_ProcessRdpList)(void);
void(*m_ShowCFB)(void); void(*m_ShowCFB)(void);
/* alist.cpp */ // alist.cpp
uint8_t m_alist_buffer[0x1000]; uint8_t m_alist_buffer[0x1000];
/* alist_audio.cpp */ // alist_audio.cpp
struct alist_audio_t m_alist_audio; struct alist_audio_t m_alist_audio;
/* alist_naudio.cpp */ // alist_naudio.cpp
struct alist_naudio_t m_alist_naudio; struct alist_naudio_t m_alist_naudio;
/* alist_nead.cpp */ // alist_nead.cpp
struct alist_nead_t m_alist_nead; struct alist_nead_t m_alist_nead;
/* mp3.cpp */ // mp3.cpp
uint8_t m_mp3_buffer[0x1000]; uint8_t m_mp3_buffer[0x1000];
bool m_AudioHle; bool m_AudioHle;

View File

@ -17,27 +17,27 @@
typedef void(*tile_line_emitter_t)(CHle * hle, const int16_t *y, const int16_t *u, uint32_t address); typedef void(*tile_line_emitter_t)(CHle * hle, const int16_t *y, const int16_t *u, uint32_t address);
typedef void(*subblock_transform_t)(int16_t *dst, const int16_t *src); typedef void(*subblock_transform_t)(int16_t *dst, const int16_t *src);
/* standard jpeg ucode decoder */ // Standard JPEG microcode decoder
static void jpeg_decode_std(CHle * hle, static void jpeg_decode_std(CHle * hle,
const char *const version, const char *const version,
const subblock_transform_t transform_luma, const subblock_transform_t transform_luma,
const subblock_transform_t transform_chroma, const subblock_transform_t transform_chroma,
const tile_line_emitter_t emit_line); const tile_line_emitter_t emit_line);
/* helper functions */ // Helper functions
static uint8_t clamp_u8(int16_t x); static uint8_t clamp_u8(int16_t x);
static int16_t clamp_s12(int16_t x); static int16_t clamp_s12(int16_t x);
static uint16_t clamp_RGBA_component(int16_t x); static uint16_t clamp_RGBA_component(int16_t x);
/* pixel conversion & formatting */ // Pixel conversion and formatting
static uint32_t GetUYVY(int16_t y1, int16_t y2, int16_t u, int16_t v); static uint32_t GetUYVY(int16_t y1, int16_t y2, int16_t u, int16_t v);
static uint16_t GetRGBA(int16_t y, int16_t u, int16_t v); static uint16_t GetRGBA(int16_t y, int16_t u, int16_t v);
/* tile line emitters */ // Tile line emitters
static void EmitYUVTileLine(CHle * hle, const int16_t *y, const int16_t *u, uint32_t address); static void EmitYUVTileLine(CHle * hle, const int16_t *y, const int16_t *u, uint32_t address);
static void EmitRGBATileLine(CHle * hle, const int16_t *y, const int16_t *u, uint32_t address); static void EmitRGBATileLine(CHle * hle, const int16_t *y, const int16_t *u, uint32_t address);
/* macroblocks operations */ // Macroblocks operations
static void decode_macroblock_ob(int16_t *macroblock, int32_t *y_dc, int32_t *u_dc, int32_t *v_dc, const int16_t *qtable); static void decode_macroblock_ob(int16_t *macroblock, int32_t *y_dc, int32_t *u_dc, int32_t *v_dc, const int16_t *qtable);
static void decode_macroblock_std(const subblock_transform_t transform_luma, static void decode_macroblock_std(const subblock_transform_t transform_luma,
const subblock_transform_t transform_chroma, const subblock_transform_t transform_chroma,
@ -47,7 +47,7 @@ static void decode_macroblock_std(const subblock_transform_t transform_luma,
static void EmitTilesMode0(CHle * hle, const tile_line_emitter_t emit_line, const int16_t *macroblock, uint32_t address); static void EmitTilesMode0(CHle * hle, const tile_line_emitter_t emit_line, const int16_t *macroblock, uint32_t address);
static void EmitTilesMode2(CHle * hle, const tile_line_emitter_t emit_line, const int16_t *macroblock, uint32_t address); static void EmitTilesMode2(CHle * hle, const tile_line_emitter_t emit_line, const int16_t *macroblock, uint32_t address);
/* subblocks operations */ // Sub blocks operations
static void TransposeSubBlock(int16_t *dst, const int16_t *src); static void TransposeSubBlock(int16_t *dst, const int16_t *src);
static void ZigZagSubBlock(int16_t *dst, const int16_t *src); static void ZigZagSubBlock(int16_t *dst, const int16_t *src);
static void ReorderSubBlock(int16_t *dst, const int16_t *src, const unsigned int *table); static void ReorderSubBlock(int16_t *dst, const int16_t *src, const unsigned int *table);
@ -59,7 +59,7 @@ static void InverseDCTSubBlock(int16_t *dst, const int16_t *src);
static void RescaleYSubBlock(int16_t *dst, const int16_t *src); static void RescaleYSubBlock(int16_t *dst, const int16_t *src);
static void RescaleUVSubBlock(int16_t *dst, const int16_t *src); static void RescaleUVSubBlock(int16_t *dst, const int16_t *src);
/* transposed dequantization table */ // Transposed dequantization table
static const int16_t DEFAULT_QTABLE[SUBBLOCK_SIZE] = { static const int16_t DEFAULT_QTABLE[SUBBLOCK_SIZE] = {
16, 12, 14, 14, 18, 24, 49, 72, 16, 12, 14, 14, 18, 24, 49, 72,
11, 12, 13, 17, 22, 35, 64, 92, 11, 12, 13, 17, 22, 35, 64, 92,
@ -71,7 +71,7 @@ static const int16_t DEFAULT_QTABLE[SUBBLOCK_SIZE] = {
61, 55, 56, 62, 77, 92, 101, 99 61, 55, 56, 62, 77, 92, 101, 99
}; };
/* zig-zag indices */ // Zig-zag indices
static const unsigned int ZIGZAG_TABLE[SUBBLOCK_SIZE] = { static const unsigned int ZIGZAG_TABLE[SUBBLOCK_SIZE] = {
0, 1, 5, 6, 14, 15, 27, 28, 0, 1, 5, 6, 14, 15, 27, 28,
2, 4, 7, 13, 16, 26, 29, 42, 2, 4, 7, 13, 16, 26, 29, 42,
@ -83,7 +83,7 @@ static const unsigned int ZIGZAG_TABLE[SUBBLOCK_SIZE] = {
35, 36, 48, 49, 57, 58, 62, 63 35, 36, 48, 49, 57, 58, 62, 63
}; };
/* transposition indices */ // Transposition indices
static const unsigned int TRANSPOSE_TABLE[SUBBLOCK_SIZE] = { static const unsigned int TRANSPOSE_TABLE[SUBBLOCK_SIZE] = {
0, 8, 16, 24, 32, 40, 48, 56, 0, 8, 16, 24, 32, 40, 48, 56,
1, 9, 17, 25, 33, 41, 49, 57, 1, 9, 17, 25, 33, 41, 49, 57,
@ -100,40 +100,37 @@ static const unsigned int TRANSPOSE_TABLE[SUBBLOCK_SIZE] = {
static const float IDCT_C3 = 1.175875602f; static const float IDCT_C3 = 1.175875602f;
static const float IDCT_C6 = 0.541196100f; static const float IDCT_C6 = 0.541196100f;
static const float IDCT_K[10] = { static const float IDCT_K[10] = {
0.765366865f, /* C2-C6 */ 0.765366865f, // C2-C6
-1.847759065f, /* -C2-C6 */ -1.847759065f, // -C2-C6
-0.390180644f, /* C5-C3 */ -0.390180644f, // C5-C3
-1.961570561f, /* -C5-C3 */ -1.961570561f, // -C5-C3
1.501321110f, /* C1+C3-C5-C7 */ 1.501321110f, // C1+C3-C5-C7
2.053119869f, /* C1+C3-C5+C7 */ 2.053119869f, // C1+C3-C5+C7
3.072711027f, /* C1+C3+C5-C7 */ 3.072711027f, // C1+C3+C5-C7
0.298631336f, /* -C1+C3+C5-C7 */ 0.298631336f, // -C1+C3+C5-C7
-0.899976223f, /* C7-C3 */ -0.899976223f, // C7-C3
-2.562915448f /* -C1-C3 */ -2.562915448f // -C1-C3
}; };
/* global functions */ // Global functions
// JPEG decoding microcode found in Japanese-exclusive version of Pokémon Stadium
/***************************************************************************
* JPEG decoding ucode found in Japanese exclusive version of Pokemon Stadium.
**************************************************************************/
void jpeg_decode_PS0(CHle * hle) void jpeg_decode_PS0(CHle * hle)
{ {
jpeg_decode_std(hle, "PS0", RescaleYSubBlock, RescaleUVSubBlock, EmitYUVTileLine); jpeg_decode_std(hle, "PS0", RescaleYSubBlock, RescaleUVSubBlock, EmitYUVTileLine);
} }
/*************************************************************************** // JPEG decoding microcode found in Ocarina of Time, Pokémon Stadium 1, and Pokémon Stadium 2
* JPEG decoding ucode found in Ocarina of Time, Pokemon Stadium 1 and
* Pokemon Stadium 2.
**************************************************************************/
void jpeg_decode_PS(CHle * hle) void jpeg_decode_PS(CHle * hle)
{ {
jpeg_decode_std(hle, "PS", NULL, NULL, EmitRGBATileLine); jpeg_decode_std(hle, "PS", NULL, NULL, EmitRGBATileLine);
} }
/***************************************************************************
* JPEG decoding ucode found in Ogre Battle and Bottom of the 9th. // JPEG decoding microcode found in Ogre Battle and Bottom of the 9th
**************************************************************************/
void jpeg_decode_OB(CHle * hle) void jpeg_decode_OB(CHle * hle)
{ {
int16_t qtable[SUBBLOCK_SIZE]; int16_t qtable[SUBBLOCK_SIZE];
@ -173,7 +170,8 @@ void jpeg_decode_OB(CHle * hle)
} }
} }
/* local functions */ // Local functions
static void jpeg_decode_std(CHle * hle, const char *const version, const subblock_transform_t transform_luma, const subblock_transform_t transform_chroma, const tile_line_emitter_t emit_line) static void jpeg_decode_std(CHle * hle, const char *const version, const subblock_transform_t transform_luma, const subblock_transform_t transform_chroma, const tile_line_emitter_t emit_line)
{ {
int16_t qtables[3][SUBBLOCK_SIZE]; int16_t qtables[3][SUBBLOCK_SIZE];
@ -186,7 +184,7 @@ static void jpeg_decode_std(CHle * hle, const char *const version, const subbloc
uint32_t qtableV_ptr; uint32_t qtableV_ptr;
unsigned int subblock_count; unsigned int subblock_count;
unsigned int macroblock_size; unsigned int macroblock_size;
/* macroblock contains at most 6 subblocks */ // Macroblock contains at most 6 sub blocks
int16_t macroblock[6 * SUBBLOCK_SIZE]; int16_t macroblock[6 * SUBBLOCK_SIZE];
uint32_t data_ptr; uint32_t data_ptr;
@ -375,7 +373,7 @@ static void decode_macroblock_ob(int16_t *macroblock, int32_t *y_dc, int32_t *u_
for (sb = 0; sb < 6; ++sb) { for (sb = 0; sb < 6; ++sb) {
int16_t tmp_sb[SUBBLOCK_SIZE]; int16_t tmp_sb[SUBBLOCK_SIZE];
/* update DC */ // Update DC
int32_t dc = (int32_t)macroblock[0]; int32_t dc = (int32_t)macroblock[0];
switch (sb) { switch (sb) {
case 0: case 0:
@ -462,7 +460,7 @@ static void ReorderSubBlock(int16_t *dst, const int16_t *src, const unsigned int
{ {
unsigned int i; unsigned int i;
/* source and destination sublocks cannot overlap */ // Source and destination sub blocks cannot overlap
assert(abs(dst - src) > SUBBLOCK_SIZE); assert(abs(dst - src) > SUBBLOCK_SIZE);
for (i = 0; i < SUBBLOCK_SIZE; ++i) for (i = 0; i < SUBBLOCK_SIZE; ++i)
@ -498,12 +496,14 @@ static void RShiftSubBlock(int16_t *dst, const int16_t *src, unsigned int shift)
dst[i] = src[i] >> shift; dst[i] = src[i] >> shift;
} }
/*************************************************************************** /*
* Fast 2D IDCT using separable formulation and normalization TODO: find a better, more general resource for this
* Computations use single precision floats Fast 2D IDCT using separable formulation and normalization
* Implementation based on Wikipedia : Computations use single precision floats
* http://fr.wikipedia.org/wiki/Transform%C3%A9e_en_cosinus_discr%C3%A8te Implementation based on Wikipedia:
**************************************************************************/ https://fr.wikipedia.org/wiki/Transform%C3%A9e_en_cosinus_discr%C3%A8te
*/
static void InverseDCT1D(const float *const x, float *dst, unsigned int stride) static void InverseDCT1D(const float *const x, float *dst, unsigned int stride)
{ {
float e[4]; float e[4];
@ -550,7 +550,7 @@ static void InverseDCTSubBlock(int16_t *dst, const int16_t *src)
float block[SUBBLOCK_SIZE]; float block[SUBBLOCK_SIZE];
unsigned int i, j; unsigned int i, j;
/* idct 1d on rows (+transposition) */ // IDCT 1D on rows (+transposition)
for (i = 0; i < 8; ++i) for (i = 0; i < 8; ++i)
{ {
for (j = 0; j < 8; ++j) for (j = 0; j < 8; ++j)
@ -560,12 +560,12 @@ static void InverseDCTSubBlock(int16_t *dst, const int16_t *src)
InverseDCT1D(x, &block[i], 8); InverseDCT1D(x, &block[i], 8);
} }
/* idct 1d on columns (thanks to previous transposition) */ // IDCT 1D on columns (thanks to previous transposition)
for (i = 0; i < 8; ++i) for (i = 0; i < 8; ++i)
{ {
InverseDCT1D(&block[i * 8], x, 1); InverseDCT1D(&block[i * 8], x, 1);
/* C4 = 1 normalization implies a division by 8 */ // C4 = 1 normalization implies a division by 8
for (j = 0; j < 8; ++j) for (j = 0; j < 8; ++j)
{ {
dst[i + j * 8] = (int16_t)x[j] >> 3; dst[i + j * 8] = (int16_t)x[j] >> 3;

View File

@ -15,13 +15,14 @@ BOOL WINAPI DllMain(void * hinst, DWORD /*fdwReason*/, LPVOID /*lpvReserved*/)
} }
#endif #endif
/****************************************************************** /*
Function: CloseDLL Function: CloseDLL
Purpose: This function is called when the emulator is closing Purpose: This function is called when the emulator is closing
down allowing the dll to de-initialise. down allowing the DLL to de-initialize.
input: none input: none
output: none output: none
*******************************************************************/ */
void CloseDLL(void) void CloseDLL(void)
{ {
if (g_hle) if (g_hle)
@ -31,13 +32,14 @@ void CloseDLL(void)
} }
} }
/****************************************************************** /*
Function: DllAbout Function: DllAbout
Purpose: This function is optional function that is provided Purpose: This function is optional function that is provided
to give further information about the DLL. to give further information about the DLL.
input: a handle to the window that calls this function input: a handle to the window that calls this function
output: none output: none
*******************************************************************/ */
void DllAbout(void * hParent) void DllAbout(void * hParent)
{ {
#ifdef _WIN32 #ifdef _WIN32
@ -45,17 +47,18 @@ void DllAbout(void * hParent)
#endif #endif
} }
/****************************************************************** /*
Function: DoRspCycles Function: DoRspCycles
Purpose: This function is to allow the RSP to run in parrel with Purpose: This function is to allow the RSP to run in parallel with
the r4300 switching control back to the r4300 once the the r4300 switching control back to the r4300 once the
function ends. function ends.
input: The number of cylces that is meant to be executed input: The number of cycles that is meant to be executed
output: The number of cycles that was executed. This value can output: The number of cycles that was executed. This value can
be greater than the number of cycles that the RSP be greater than the number of cycles that the RSP
should have performed. should have performed.
(this value is ignored if the RSP is stoped) (this value is ignored if the RSP is stopped)
*******************************************************************/ */
uint32_t DoRspCycles(uint32_t Cycles) uint32_t DoRspCycles(uint32_t Cycles)
{ {
if (g_hle) if (g_hle)
@ -65,38 +68,40 @@ uint32_t DoRspCycles(uint32_t Cycles)
return Cycles; return Cycles;
} }
/****************************************************************** /*
Function: GetDllInfo Function: GetDllInfo
Purpose: This function allows the emulator to gather information Purpose: This function allows the emulator to gather information
about the dll by filling in the PluginInfo structure. about the DLL by filling in the PluginInfo structure.
input: a pointer to a PLUGIN_INFO stucture that needs to be input: a pointer to a PLUGIN_INFO structure that needs to be
filled by the function. (see def above) filled by the function. (see def above)
output: none output: none
*******************************************************************/ */
void GetDllInfo(PLUGIN_INFO * PluginInfo) void GetDllInfo(PLUGIN_INFO * PluginInfo)
{ {
PluginInfo->Version = 0x0102; PluginInfo->Version = 0x0102;
PluginInfo->Type = PLUGIN_TYPE_RSP; PluginInfo->Type = PLUGIN_TYPE_RSP;
#ifdef _DEBUG #ifdef _DEBUG
sprintf(PluginInfo->Name, "RSP HLE Debug Plugin %s", VER_FILE_VERSION_STR); sprintf(PluginInfo->Name, "RSP HLE debug plugin %s", VER_FILE_VERSION_STR);
#else #else
sprintf(PluginInfo->Name, "RSP HLE Plugin %s", VER_FILE_VERSION_STR); sprintf(PluginInfo->Name, "RSP HLE plugin %s", VER_FILE_VERSION_STR);
#endif #endif
PluginInfo->NormalMemory = false; PluginInfo->NormalMemory = false;
PluginInfo->MemoryBswaped = true; PluginInfo->MemoryBswaped = true;
} }
/****************************************************************** /*
Function: InitiateRSP Function: InitiateRSP
Purpose: This function is called when the DLL is started to give Purpose: This function is called when the DLL is started to give
information from the emulator that the n64 RSP information from the emulator that the N64 RSP
interface needs interface needs
input: Rsp_Info is passed to this function which is defined input: Rsp_Info is passed to this function which is defined
above. above.
CycleCount is the number of cycles between switching CycleCount is the number of cycles between switching
control between teh RSP and r4300i core. control between the RSP and r4300i core.
output: none output: none
*******************************************************************/ */
void InitiateRSP(RSP_INFO Rsp_Info, uint32_t * /*CycleCount*/) void InitiateRSP(RSP_INFO Rsp_Info, uint32_t * /*CycleCount*/)
{ {
if (g_hle) if (g_hle)
@ -107,22 +112,24 @@ void InitiateRSP(RSP_INFO Rsp_Info, uint32_t * /*CycleCount*/)
g_hle = new CHle(Rsp_Info); g_hle = new CHle(Rsp_Info);
} }
/****************************************************************** /*
Function: RomOpen Function: RomOpen
Purpose: This function is called when a rom is opened. Purpose: This function is called when a ROM is opened.
input: none input: none
output: none output: none
*******************************************************************/ */
void RomOpen(void) void RomOpen(void)
{ {
} }
/****************************************************************** /*
Function: RomClosed Function: RomClosed
Purpose: This function is called when a rom is closed. Purpose: This function is called when a ROM is closed.
input: none input: none
output: none output: none
*******************************************************************/ */
void RomClosed(void) void RomClosed(void)
{ {
} }

View File

@ -3,12 +3,13 @@
// Copyright(C) 2001-2021 Project64 // Copyright(C) 2001-2021 Project64
// Copyright(C) 2012 Bobby Smiles // Copyright(C) 2012 Bobby Smiles
// GNU/GPLv2 licensed: https://gnu.org/licenses/gpl-2.0.html // GNU/GPLv2 licensed: https://gnu.org/licenses/gpl-2.0.html
#include "stdafx.h" #include "stdafx.h"
#include <string.h> #include <string.h>
#include "mem.h" #include "mem.h"
/* Global functions */ // Global functions
void load_u8(uint8_t* dst, const unsigned char* buffer, unsigned address, size_t count) void load_u8(uint8_t* dst, const unsigned char* buffer, unsigned address, size_t count)
{ {
while (count != 0) while (count != 0)
@ -31,7 +32,7 @@ void store_u16(unsigned char* buffer, unsigned address, const uint16_t* src, siz
void load_u32(uint32_t* dst, const unsigned char* buffer, unsigned address, size_t count) void load_u32(uint32_t* dst, const unsigned char* buffer, unsigned address, size_t count)
{ {
/* Optimization for uint32_t */ // Optimization for uint32_t
memcpy(dst, u32(buffer, address), count * sizeof(uint32_t)); memcpy(dst, u32(buffer, address), count * sizeof(uint32_t));
} }
@ -47,6 +48,6 @@ void load_u16(uint16_t* dst, const unsigned char* buffer, unsigned address, size
void store_u32(unsigned char* buffer, unsigned address, const uint32_t* src, size_t count) void store_u32(unsigned char* buffer, unsigned address, const uint32_t* src, size_t count)
{ {
/* Optimization for uint32_t */ // Optimization for uint32_t
memcpy(u32(buffer, address), src, count * sizeof(uint32_t)); memcpy(u32(buffer, address), src, count * sizeof(uint32_t));
} }

View File

@ -3,6 +3,7 @@
// Copyright(C) 2001-2021 Project64 // Copyright(C) 2001-2021 Project64
// Copyright(C) 2014 Bobby Smiles // Copyright(C) 2014 Bobby Smiles
// GNU/GPLv2 licensed: https://gnu.org/licenses/gpl-2.0.html // GNU/GPLv2 licensed: https://gnu.org/licenses/gpl-2.0.html
#pragma once #pragma once
#include <assert.h> #include <assert.h>
@ -69,7 +70,7 @@ static inline void dmem_store_u32(CHle * hle, const uint32_t* src, uint16_t addr
store_u32(hle->dmem(), address & 0xfff, src, count); store_u32(hle->dmem(), address & 0xfff, src, count);
} }
/* convenient functions DRAM access */ // Convenient functions DRAM access
static inline uint8_t* dram_u8(CHle * hle, uint32_t address) static inline uint8_t* dram_u8(CHle * hle, uint32_t address)
{ {
return u8(hle->dram(), address & 0xffffff); return u8(hle->dram(), address & 0xffffff);

View File

@ -151,7 +151,7 @@ static const uint16_t DeWindowLUT [0x420] = {
static void MP3AB0(int32_t* v) static void MP3AB0(int32_t* v)
{ {
/* Part 2 - 100% Accurate */ // Part 2 - 100% accurate
static const uint16_t LUT2[8] = static const uint16_t LUT2[8] =
{ {
0xFEC4, 0xF4FA, 0xC5E4, 0xE1C4, 0xFEC4, 0xF4FA, 0xC5E4, 0xE1C4,
@ -166,7 +166,7 @@ static void MP3AB0(int32_t* v)
v[24 + i] = ((v[0 + i] - v[8 + i]) * LUT2[i]) >> 0x10; v[24 + i] = ((v[0 + i] - v[8 + i]) * LUT2[i]) >> 0x10;
} }
/* Part 3: 4-wide butterflies */ // Part 3: 4-wide butterflies
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
{ {
@ -177,7 +177,7 @@ static void MP3AB0(int32_t* v)
v[12 + i] = ((v[24 + i] - v[28 + i]) * LUT3[i]) >> 0x10; v[12 + i] = ((v[24 + i] - v[28 + i]) * LUT3[i]) >> 0x10;
} }
/* Part 4: 2-wide butterflies - 100% Accurate */ // Part 4: 2-wide butterflies - 100% accurate
for (i = 0; i < 16; i += 4) for (i = 0; i < 16; i += 4)
{ {
@ -192,34 +192,34 @@ static void MP3AB0(int32_t* v)
void mp3_task(CHle * hle, unsigned int index, uint32_t address) void mp3_task(CHle * hle, unsigned int index, uint32_t address)
{ {
uint32_t inPtr, outPtr; uint32_t inPtr, outPtr;
uint32_t t6;/* = 0x08A0; - I think these are temporary storage buffers */ uint32_t t6;// = 0x08A0; - I think these are temporary storage buffers
uint32_t t5;/* = 0x0AC0; */ uint32_t t5;// = 0x0AC0;
uint32_t t4;/* = (w1 & 0x1E); */ uint32_t t4;// = (w1 & 0x1E);
/* Initialization Code */ // Initialization code
uint32_t readPtr; /* s5 */ uint32_t readPtr; // s5
uint32_t writePtr; /* s6 */ uint32_t writePtr; // s6
uint32_t tmp; uint32_t tmp;
int cnt, cnt2; int cnt, cnt2;
/* I think these are temporary storage buffers */ // I think these are temporary storage buffers
t6 = 0x08A0; t6 = 0x08A0;
t5 = 0x0AC0; t5 = 0x0AC0;
t4 = index; t4 = index;
writePtr = readPtr = address; writePtr = readPtr = address;
/* Just do that for efficiency... may remove and use directly later anyway */ // TODO: Just do that for efficiency...may remove and use directly later anyway
memcpy(hle->mp3_buffer() + 0xCE8, hle->dram() + readPtr, 8); memcpy(hle->mp3_buffer() + 0xCE8, hle->dram() + readPtr, 8);
/* This must be a header byte or whatnot */ // This must be a header byte or whatnot
readPtr += 8; readPtr += 8;
for (cnt = 0; cnt < 0x480; cnt += 0x180) for (cnt = 0; cnt < 0x480; cnt += 0x180)
{ {
/* DMA: 0xCF0 <- RDRAM[s5] : 0x180 */ // DMA: 0xCF0 <- RDRAM[s5] : 0x180
memcpy(hle->mp3_buffer() + 0xCF0, hle->dram() + readPtr, 0x180); memcpy(hle->mp3_buffer() + 0xCF0, hle->dram() + readPtr, 0x180);
inPtr = 0xCF0; /* s7 */ inPtr = 0xCF0; // s7
outPtr = 0xE70; /* s3 */ outPtr = 0xE70; // s3
/* --------------- Inner Loop Start -------------------- */ // --------------- Inner Loop Start --------------------
for (cnt2 = 0; cnt2 < 0x180; cnt2 += 0x40) for (cnt2 = 0; cnt2 < 0x180; cnt2 += 0x40)
{ {
t6 &= 0xFFE0; t6 &= 0xFFE0;
@ -234,7 +234,7 @@ void mp3_task(CHle * hle, unsigned int index, uint32_t address)
inPtr += 0x40; inPtr += 0x40;
outPtr += 0x40; outPtr += 0x40;
} }
/* --------------- Inner Loop End -------------------- */ // --------------- Inner Loop End --------------------
memcpy(hle->dram() + writePtr, hle->mp3_buffer() + 0xe70, 0x180); memcpy(hle->dram() + writePtr, hle->mp3_buffer() + 0xe70, 0x180);
writePtr += 0x180; writePtr += 0x180;
readPtr += 0x180; readPtr += 0x180;
@ -243,9 +243,9 @@ void mp3_task(CHle * hle, unsigned int index, uint32_t address)
static void InnerLoop(CHle * hle, uint32_t outPtr, uint32_t inPtr, uint32_t t6, uint32_t t5, uint32_t t4) static void InnerLoop(CHle * hle, uint32_t outPtr, uint32_t inPtr, uint32_t t6, uint32_t t5, uint32_t t4)
{ {
/* Part 1: 100% Accurate */ // Part 1: 100% accurate
/* 0, 1, 3, 2, 7, 6, 4, 5, 7, 6, 4, 5, 0, 1, 3, 2 */ // 0, 1, 3, 2, 7, 6, 4, 5, 7, 6, 4, 5, 0, 1, 3, 2
static const uint16_t LUT6[16] = static const uint16_t LUT6[16] =
{ {
0xFFB2, 0xFD3A, 0xF10A, 0xF854, 0xFFB2, 0xFD3A, 0xF10A, 0xF854,
@ -322,43 +322,43 @@ static void InnerLoop(CHle * hle, uint32_t outPtr, uint32_t inPtr, uint32_t t6,
v[21] = *(int16_t *)(hle->mp3_buffer() + inPtr + (0x2A ^ S16)); v[21] = *(int16_t *)(hle->mp3_buffer() + inPtr + (0x2A ^ S16));
v[15] += v[21]; v[15] += v[21];
/* Part 2-4 */ // Part 2-4
MP3AB0(v); MP3AB0(v);
/* Part 5 - 1-Wide Butterflies - 100% Accurate but need SSVs!!! */ // Part 5 - 1-Wide Butterflies - 100% accurate but need SSVs!
t0 = t6 + 0x100; t0 = t6 + 0x100;
t1 = t6 + 0x200; t1 = t6 + 0x200;
t2 = t5 + 0x100; t2 = t5 + 0x100;
t3 = t5 + 0x200; t3 = t5 + 0x200;
/* 0x13A8 */ // 0x13A8
v[1] = 0; v[1] = 0;
v[11] = ((v[16] - v[17]) * 0xB504) >> 0x10; v[11] = ((v[16] - v[17]) * 0xB504) >> 0x10;
v[16] = -v[16] - v[17]; v[16] = -v[16] - v[17];
v[2] = v[18] + v[19]; v[2] = v[18] + v[19];
/* ** Store v[11] -> (T6 + 0)** */ // ** Store v[11] -> (T6 + 0)**
*(int16_t *)(hle->mp3_buffer() + ((t6 + (short)0x0))) = (short)v[11]; *(int16_t *)(hle->mp3_buffer() + ((t6 + (short)0x0))) = (short)v[11];
v[11] = -v[11]; v[11] = -v[11];
/* ** Store v[16] -> (T3 + 0)** */ // ** Store v[16] -> (T3 + 0)**
*(int16_t *)(hle->mp3_buffer() + ((t3 + (short)0x0))) = (short)v[16]; *(int16_t *)(hle->mp3_buffer() + ((t3 + (short)0x0))) = (short)v[16];
/* ** Store v[11] -> (T5 + 0)** */ // ** Store v[11] -> (T5 + 0)**
*(int16_t *)(hle->mp3_buffer() + ((t5 + (short)0x0))) = (short)v[11]; *(int16_t *)(hle->mp3_buffer() + ((t5 + (short)0x0))) = (short)v[11];
/* 0x13E8 - Verified.... */ // 0x13E8 - Verified...
v[2] = -v[2]; v[2] = -v[2];
/* ** Store v[2] -> (T2 + 0)** */ // ** Store v[2] -> (T2 + 0)**
*(int16_t *)(hle->mp3_buffer() + ((t2 + (short)0x0))) = (short)v[2]; *(int16_t *)(hle->mp3_buffer() + ((t2 + (short)0x0))) = (short)v[2];
v[3] = (((v[18] - v[19]) * 0x16A09) >> 0x10) + v[2]; v[3] = (((v[18] - v[19]) * 0x16A09) >> 0x10) + v[2];
/* ** Store v[3] -> (T0 + 0)** */ // ** Store v[3] -> (T0 + 0)**
*(int16_t *)(hle->mp3_buffer() + ((t0 + (short)0x0))) = (short)v[3]; *(int16_t *)(hle->mp3_buffer() + ((t0 + (short)0x0))) = (short)v[3];
/* 0x1400 - Verified */ // 0x1400 - Verified...
v[4] = -v[20] - v[21]; v[4] = -v[20] - v[21];
v[6] = v[22] + v[23]; v[6] = v[22] + v[23];
v[5] = ((v[20] - v[21]) * 0x16A09) >> 0x10; v[5] = ((v[20] - v[21]) * 0x16A09) >> 0x10;
/* ** Store v[4] -> (T3 + 0xFF80) */ // ** Store v[4] -> (T3 + 0xFF80)
*(int16_t *)(hle->mp3_buffer() + ((t3 + (short)0xFF80))) = (short)v[4]; *(int16_t *)(hle->mp3_buffer() + ((t3 + (short)0xFF80))) = (short)v[4];
v[7] = ((v[22] - v[23]) * 0x2D413) >> 0x10; v[7] = ((v[22] - v[23]) * 0x2D413) >> 0x10;
v[5] = v[5] - v[4]; v[5] = v[5] - v[4];
@ -366,11 +366,11 @@ static void InnerLoop(CHle * hle, uint32_t outPtr, uint32_t inPtr, uint32_t t6,
v[6] = v[6] + v[6]; v[6] = v[6] + v[6];
v[5] = v[5] - v[6]; v[5] = v[5] - v[6];
v[4] = -v[4] - v[6]; v[4] = -v[4] - v[6];
/* *** Store v[7] -> (T1 + 0xFF80) */ // *** Store v[7] -> (T1 + 0xFF80)
*(int16_t *)(hle->mp3_buffer() + ((t1 + (short)0xFF80))) = (short)v[7]; *(int16_t *)(hle->mp3_buffer() + ((t1 + (short)0xFF80))) = (short)v[7];
/* *** Store v[4] -> (T2 + 0xFF80) */ // *** Store v[4] -> (T2 + 0xFF80)
*(int16_t *)(hle->mp3_buffer() + ((t2 + (short)0xFF80))) = (short)v[4]; *(int16_t *)(hle->mp3_buffer() + ((t2 + (short)0xFF80))) = (short)v[4];
/* *** Store v[5] -> (T0 + 0xFF80) */ // *** Store v[5] -> (T0 + 0xFF80)
*(int16_t *)(hle->mp3_buffer() + ((t0 + (short)0xFF80))) = (short)v[5]; *(int16_t *)(hle->mp3_buffer() + ((t0 + (short)0xFF80))) = (short)v[5];
v[8] = v[24] + v[25]; v[8] = v[24] + v[25];
@ -391,29 +391,29 @@ static void InnerLoop(CHle * hle, uint32_t outPtr, uint32_t inPtr, uint32_t t6,
v[14] = -(v[14] + v[14]) + v[3]; v[14] = -(v[14] + v[14]) + v[3];
v[17] = v[13] - v[10]; v[17] = v[13] - v[10];
v[9] = v[9] + v[14]; v[9] = v[9] + v[14];
/* ** Store v[9] -> (T6 + 0x40) */ // ** Store v[9] -> (T6 + 0x40)
*(int16_t *)(hle->mp3_buffer() + ((t6 + (short)0x40))) = (short)v[9]; *(int16_t *)(hle->mp3_buffer() + ((t6 + (short)0x40))) = (short)v[9];
v[11] = v[11] - v[13]; v[11] = v[11] - v[13];
/* ** Store v[17] -> (T0 + 0xFFC0) */ // ** Store v[17] -> (T0 + 0xFFC0)
*(int16_t *)(hle->mp3_buffer() + ((t0 + (short)0xFFC0))) = (short)v[17]; *(int16_t *)(hle->mp3_buffer() + ((t0 + (short)0xFFC0))) = (short)v[17];
v[12] = v[8] - v[12]; v[12] = v[8] - v[12];
/* ** Store v[11] -> (T0 + 0x40) */ // ** Store v[11] -> (T0 + 0x40)
*(int16_t *)(hle->mp3_buffer() + ((t0 + (short)0x40))) = (short)v[11]; *(int16_t *)(hle->mp3_buffer() + ((t0 + (short)0x40))) = (short)v[11];
v[8] = -v[8]; v[8] = -v[8];
/* ** Store v[15] -> (T1 + 0xFFC0) */ // ** Store v[15] -> (T1 + 0xFFC0)
*(int16_t *)(hle->mp3_buffer() + ((t1 + (short)0xFFC0))) = (short)v[15]; *(int16_t *)(hle->mp3_buffer() + ((t1 + (short)0xFFC0))) = (short)v[15];
v[10] = -v[10] - v[12]; v[10] = -v[10] - v[12];
/* ** Store v[12] -> (T2 + 0x40) */ // ** Store v[12] -> (T2 + 0x40)
*(int16_t *)(hle->mp3_buffer() + ((t2 + (short)0x40))) = (short)v[12]; *(int16_t *)(hle->mp3_buffer() + ((t2 + (short)0x40))) = (short)v[12];
/* ** Store v[8] -> (T3 + 0xFFC0) */ // ** Store v[8] -> (T3 + 0xFFC0)
*(int16_t *)(hle->mp3_buffer() + ((t3 + (short)0xFFC0))) = (short)v[8]; *(int16_t *)(hle->mp3_buffer() + ((t3 + (short)0xFFC0))) = (short)v[8];
/* ** Store v[14] -> (T5 + 0x40) */ // ** Store v[14] -> (T5 + 0x40)
*(int16_t *)(hle->mp3_buffer() + ((t5 + (short)0x40))) = (short)v[14]; *(int16_t *)(hle->mp3_buffer() + ((t5 + (short)0x40))) = (short)v[14];
/* ** Store v[10] -> (T2 + 0xFFC0) */ // ** Store v[10] -> (T2 + 0xFFC0)
*(int16_t *)(hle->mp3_buffer() + ((t2 + (short)0xFFC0))) = (short)v[10]; *(int16_t *)(hle->mp3_buffer() + ((t2 + (short)0xFFC0))) = (short)v[10];
/* 0x14FC - Verified... */ // 0x14FC - Verified...
/* Part 6 - 100% Accurate */ // Part 6 - 100% accurate
v[0] = *(int16_t *)(hle->mp3_buffer() + inPtr + (0x00 ^ S16)); v[0] = *(int16_t *)(hle->mp3_buffer() + inPtr + (0x00 ^ S16));
v[31] = *(int16_t *)(hle->mp3_buffer() + inPtr + (0x3E ^ S16)); v[31] = *(int16_t *)(hle->mp3_buffer() + inPtr + (0x3E ^ S16));
@ -485,7 +485,7 @@ static void InnerLoop(CHle * hle, uint32_t outPtr, uint32_t inPtr, uint32_t t6,
MP3AB0(v); MP3AB0(v);
/* Part 7: - 100% Accurate + SSV - Unoptimized */ // Part 7: - 100% accurate + SSV - Unoptimized
v[0] = (v[17] + v[16]) >> 1; v[0] = (v[17] + v[16]) >> 1;
v[1] = ((v[17] * (int)((short)0xA57E * 2)) + (v[16] * 0xB504)) >> 0x10; v[1] = ((v[17] * (int)((short)0xA57E * 2)) + (v[16] * 0xB504)) >> 0x10;
@ -495,15 +495,15 @@ static void InnerLoop(CHle * hle, uint32_t outPtr, uint32_t inPtr, uint32_t t6,
v[5] = (((v[20] - v[21]) * 0x16A09) >> 0x10) + v[1]; v[5] = (((v[20] - v[21]) * 0x16A09) >> 0x10) + v[1];
v[6] = (((v[22] + v[23]) << 1) + v[0]) - v[2]; v[6] = (((v[22] + v[23]) << 1) + v[0]) - v[2];
v[7] = (((v[22] - v[23]) * 0x2D413) >> 0x10) + v[0] + v[1] + v[3]; v[7] = (((v[22] - v[23]) * 0x2D413) >> 0x10) + v[0] + v[1] + v[3];
/* 0x16A8 */ // 0x16A8
/* Save v[0] -> (T3 + 0xFFE0) */ // Save v[0] -> (T3 + 0xFFE0)
*(int16_t *)(hle->mp3_buffer() + ((t3 + (short)0xFFE0))) = (short) - v[0]; *(int16_t *)(hle->mp3_buffer() + ((t3 + (short)0xFFE0))) = (short) - v[0];
v[8] = v[24] + v[25]; v[8] = v[24] + v[25];
v[9] = ((v[24] - v[25]) * 0x16A09) >> 0x10; v[9] = ((v[24] - v[25]) * 0x16A09) >> 0x10;
v[10] = ((v[26] + v[27]) << 1) + v[8]; v[10] = ((v[26] + v[27]) << 1) + v[8];
v[11] = (((v[26] - v[27]) * 0x2D413) >> 0x10) + v[8] + v[9]; v[11] = (((v[26] - v[27]) * 0x2D413) >> 0x10) + v[8] + v[9];
v[12] = v[4] - ((v[28] + v[29]) << 1); v[12] = v[4] - ((v[28] + v[29]) << 1);
/* ** Store v12 -> (T2 + 0x20) */ // ** Store v12 -> (T2 + 0x20)
*(int16_t *)(hle->mp3_buffer() + ((t2 + (short)0x20))) = (short)v[12]; *(int16_t *)(hle->mp3_buffer() + ((t2 + (short)0x20))) = (short)v[12];
v[13] = (((v[28] - v[29]) * 0x2D413) >> 0x10) - v[12] - v[5]; v[13] = (((v[28] - v[29]) * 0x2D413) >> 0x10) - v[12] - v[5];
v[14] = v[30] + v[31]; v[14] = v[30] + v[31];
@ -511,54 +511,54 @@ static void InnerLoop(CHle * hle, uint32_t outPtr, uint32_t inPtr, uint32_t t6,
v[14] = v[14] + v[14]; v[14] = v[14] + v[14];
v[14] = v[6] - v[14]; v[14] = v[6] - v[14];
v[15] = (((v[30] - v[31]) * 0x5A827) >> 0x10) - v[7]; v[15] = (((v[30] - v[31]) * 0x5A827) >> 0x10) - v[7];
/* Store v14 -> (T5 + 0x20) */ // Store v14 -> (T5 + 0x20)
*(int16_t *)(hle->mp3_buffer() + ((t5 + (short)0x20))) = (short)v[14]; *(int16_t *)(hle->mp3_buffer() + ((t5 + (short)0x20))) = (short)v[14];
v[14] = v[14] + v[1]; v[14] = v[14] + v[1];
/* Store v[14] -> (T6 + 0x20) */ // Store v[14] -> (T6 + 0x20)
*(int16_t *)(hle->mp3_buffer() + ((t6 + (short)0x20))) = (short)v[14]; *(int16_t *)(hle->mp3_buffer() + ((t6 + (short)0x20))) = (short)v[14];
/* Store v[15] -> (T1 + 0xFFE0) */ // Store v[15] -> (T1 + 0xFFE0)
*(int16_t *)(hle->mp3_buffer() + ((t1 + (short)0xFFE0))) = (short)v[15]; *(int16_t *)(hle->mp3_buffer() + ((t1 + (short)0xFFE0))) = (short)v[15];
v[9] = v[9] + v[10]; v[9] = v[9] + v[10];
v[1] = v[1] + v[6]; v[1] = v[1] + v[6];
v[6] = v[10] - v[6]; v[6] = v[10] - v[6];
v[1] = v[9] - v[1]; v[1] = v[9] - v[1];
/* Store v[6] -> (T5 + 0x60) */ // Store v[6] -> (T5 + 0x60)
*(int16_t *)(hle->mp3_buffer() + ((t5 + (short)0x60))) = (short)v[6]; *(int16_t *)(hle->mp3_buffer() + ((t5 + (short)0x60))) = (short)v[6];
v[10] = v[10] + v[2]; v[10] = v[10] + v[2];
v[10] = v[4] - v[10]; v[10] = v[4] - v[10];
/* Store v[10] -> (T2 + 0xFFA0) */ // Store v[10] -> (T2 + 0xFFA0)
*(int16_t *)(hle->mp3_buffer() + ((t2 + (short)0xFFA0))) = (short)v[10]; *(int16_t *)(hle->mp3_buffer() + ((t2 + (short)0xFFA0))) = (short)v[10];
v[12] = v[2] - v[12]; v[12] = v[2] - v[12];
/* Store v[12] -> (T2 + 0xFFE0) */ // Store v[12] -> (T2 + 0xFFE0)
*(int16_t *)(hle->mp3_buffer() + ((t2 + (short)0xFFE0))) = (short)v[12]; *(int16_t *)(hle->mp3_buffer() + ((t2 + (short)0xFFE0))) = (short)v[12];
v[5] = v[4] + v[5]; v[5] = v[4] + v[5];
v[4] = v[8] - v[4]; v[4] = v[8] - v[4];
/* Store v[4] -> (T2 + 0x60) */ // Store v[4] -> (T2 + 0x60)
*(int16_t *)(hle->mp3_buffer() + ((t2 + (short)0x60))) = (short)v[4]; *(int16_t *)(hle->mp3_buffer() + ((t2 + (short)0x60))) = (short)v[4];
v[0] = v[0] - v[8]; v[0] = v[0] - v[8];
/* Store v[0] -> (T3 + 0xFFA0) */ // Store v[0] -> (T3 + 0xFFA0)
*(int16_t *)(hle->mp3_buffer() + ((t3 + (short)0xFFA0))) = (short)v[0]; *(int16_t *)(hle->mp3_buffer() + ((t3 + (short)0xFFA0))) = (short)v[0];
v[7] = v[7] - v[11]; v[7] = v[7] - v[11];
/* Store v[7] -> (T1 + 0xFFA0) */ // Store v[7] -> (T1 + 0xFFA0)
*(int16_t *)(hle->mp3_buffer() + ((t1 + (short)0xFFA0))) = (short)v[7]; *(int16_t *)(hle->mp3_buffer() + ((t1 + (short)0xFFA0))) = (short)v[7];
v[11] = v[11] - v[3]; v[11] = v[11] - v[3];
/* Store v[1] -> (T6 + 0x60) */ // Store v[1] -> (T6 + 0x60)
*(int16_t *)(hle->mp3_buffer() + ((t6 + (short)0x60))) = (short)v[1]; *(int16_t *)(hle->mp3_buffer() + ((t6 + (short)0x60))) = (short)v[1];
v[11] = v[11] - v[5]; v[11] = v[11] - v[5];
/* Store v[11] -> (T0 + 0x60) */ // Store v[11] -> (T0 + 0x60)
*(int16_t *)(hle->mp3_buffer() + ((t0 + (short)0x60))) = (short)v[11]; *(int16_t *)(hle->mp3_buffer() + ((t0 + (short)0x60))) = (short)v[11];
v[3] = v[3] - v[13]; v[3] = v[3] - v[13];
/* Store v[3] -> (T0 + 0x20) */ // Store v[3] -> (T0 + 0x20)
*(int16_t *)(hle->mp3_buffer() + ((t0 + (short)0x20))) = (short)v[3]; *(int16_t *)(hle->mp3_buffer() + ((t0 + (short)0x20))) = (short)v[3];
v[13] = v[13] + v[2]; v[13] = v[13] + v[2];
/* Store v[13] -> (T0 + 0xFFE0) */ // Store v[13] -> (T0 + 0xFFE0)
*(int16_t *)(hle->mp3_buffer() + ((t0 + (short)0xFFE0))) = (short)v[13]; *(int16_t *)(hle->mp3_buffer() + ((t0 + (short)0xFFE0))) = (short)v[13];
v[2] = (v[5] - v[2]) - v[9]; v[2] = (v[5] - v[2]) - v[9];
/* Store v[2] -> (T0 + 0xFFA0) */ // Store v[2] -> (T0 + 0xFFA0)
*(int16_t *)(hle->mp3_buffer() + ((t0 + (short)0xFFA0))) = (short)v[2]; *(int16_t *)(hle->mp3_buffer() + ((t0 + (short)0xFFA0))) = (short)v[2];
/* 0x7A8 - Verified... */ // 0x7A8 - Verified...
/* Step 8 - Dewindowing */ // Step 8 - Dewindowing
addptr = t6 & 0xFFE0; addptr = t6 & 0xFFE0;
@ -580,9 +580,9 @@ static void InnerLoop(CHle * hle, uint32_t outPtr, uint32_t inPtr, uint32_t t6,
} }
v0 = v2 + v4; v0 = v2 + v4;
v18 = v6 + v8; v18 = v6 + v8;
/* Clamp(v0); */ // Clamp(v0);
/* Clamp(v18); */ // Clamp(v18);
/* clamp??? */ // clamp???
*(int16_t *)(hle->mp3_buffer() + (outPtr ^ S16)) = v0; *(int16_t *)(hle->mp3_buffer() + (outPtr ^ S16)) = v0;
*(int16_t *)(hle->mp3_buffer() + ((outPtr + 2)^S16)) = v18; *(int16_t *)(hle->mp3_buffer() + ((outPtr + 2)^S16)) = v18;
outPtr += 4; outPtr += 4;
@ -641,9 +641,9 @@ static void InnerLoop(CHle * hle, uint32_t outPtr, uint32_t inPtr, uint32_t t6,
} }
v0 = v2 + v4; v0 = v2 + v4;
v18 = v6 + v8; v18 = v6 + v8;
/* Clamp(v0); */ // Clamp(v0);
/* Clamp(v18); */ // Clamp(v18);
/* clamp??? */ // clamp???
*(int16_t *)(hle->mp3_buffer() + ((outPtr + 2)^S16)) = v0; *(int16_t *)(hle->mp3_buffer() + ((outPtr + 2)^S16)) = v0;
*(int16_t *)(hle->mp3_buffer() + ((outPtr + 4)^S16)) = v18; *(int16_t *)(hle->mp3_buffer() + ((outPtr + 4)^S16)) = v18;
outPtr += 4; outPtr += 4;
@ -658,19 +658,19 @@ static void InnerLoop(CHle * hle, uint32_t outPtr, uint32_t inPtr, uint32_t t6,
hi1 = (int)hi1 >> 0x10; hi1 = (int)hi1 >> 0x10;
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
{ {
/* v0 */ // v0
vt = (*(int16_t *)(hle->mp3_buffer() + ((tmp - 0x40)^S16)) * hi0); vt = (*(int16_t *)(hle->mp3_buffer() + ((tmp - 0x40)^S16)) * hi0);
*(int16_t *)((uint8_t *)hle->mp3_buffer() + ((tmp - 0x40)^S16)) = clamp_s16(vt); *(int16_t *)((uint8_t *)hle->mp3_buffer() + ((tmp - 0x40)^S16)) = clamp_s16(vt);
/* v17 */ // v17
vt = (*(int16_t *)(hle->mp3_buffer() + ((tmp - 0x30)^S16)) * hi0); vt = (*(int16_t *)(hle->mp3_buffer() + ((tmp - 0x30)^S16)) * hi0);
*(int16_t *)((uint8_t *)hle->mp3_buffer() + ((tmp - 0x30)^S16)) = clamp_s16(vt); *(int16_t *)((uint8_t *)hle->mp3_buffer() + ((tmp - 0x30)^S16)) = clamp_s16(vt);
/* v2 */ // v2
vt = (*(int16_t *)(hle->mp3_buffer() + ((tmp - 0x1E)^S16)) * hi1); vt = (*(int16_t *)(hle->mp3_buffer() + ((tmp - 0x1E)^S16)) * hi1);
*(int16_t *)((uint8_t *)hle->mp3_buffer() + ((tmp - 0x1E)^S16)) = clamp_s16(vt); *(int16_t *)((uint8_t *)hle->mp3_buffer() + ((tmp - 0x1E)^S16)) = clamp_s16(vt);
/* v4 */ // v4
vt = (*(int16_t *)(hle->mp3_buffer() + ((tmp - 0xE)^S16)) * hi1); vt = (*(int16_t *)(hle->mp3_buffer() + ((tmp - 0xE)^S16)) * hi1);
*(int16_t *)((uint8_t *)hle->mp3_buffer() + ((tmp - 0xE)^S16)) = clamp_s16(vt); *(int16_t *)((uint8_t *)hle->mp3_buffer() + ((tmp - 0xE)^S16)) = clamp_s16(vt);

View File

@ -3,6 +3,7 @@
// Copyright(C) 2001-2021 Project64 // Copyright(C) 2001-2021 Project64
// Copyright(C) 2013 Bobby Smiles // Copyright(C) 2013 Bobby Smiles
// GNU/GPLv2 licensed: https://gnu.org/licenses/gpl-2.0.html // GNU/GPLv2 licensed: https://gnu.org/licenses/gpl-2.0.html
#include "stdafx.h" #include "stdafx.h"
#include <string.h> #include <string.h>
@ -10,7 +11,8 @@
#include "audio.h" #include "audio.h"
#include "mem.h" #include "mem.h"
/* various constants */ // Various constants
enum { SUBFRAME_SIZE = 192 }; enum { SUBFRAME_SIZE = 192 };
enum { MAX_VOICES = 32 }; enum { MAX_VOICES = 32 };
@ -24,7 +26,7 @@ enum
SFD_SFX_PTR = 0xc, SFD_SFX_PTR = 0xc,
SFD_VOICES = 0x10, SFD_VOICES = 0x10,
/* v2 only */ // v2 only
SFD2_10_PTR = 0x10, SFD2_10_PTR = 0x10,
SFD2_14_BITMASK = 0x14, SFD2_14_BITMASK = 0x14,
SFD2_15_BITMASK = 0x15, SFD2_15_BITMASK = 0x15,
@ -47,11 +49,11 @@ enum
VOICE_ADPCM_FRAMES = 0x3c, VOICE_ADPCM_FRAMES = 0x3c,
VOICE_SKIP_SAMPLES = 0x3e, VOICE_SKIP_SAMPLES = 0x3e,
/* for PCM16 */ // For PCM16
VOICE_U16_40 = 0x40, VOICE_U16_40 = 0x40,
VOICE_U16_42 = 0x42, VOICE_U16_42 = 0x42,
/* for ADPCM */ // For ADPCM
VOICE_ADPCM_TABLE_PTR = 0x40, VOICE_ADPCM_TABLE_PTR = 0x40,
VOICE_INTERLEAVED_PTR = 0x44, VOICE_INTERLEAVED_PTR = 0x44,
@ -93,25 +95,27 @@ enum
SFX_FIR4_HCOEFFS = 0x40 SFX_FIR4_HCOEFFS = 0x40
}; };
/* struct definition */ // Struct definition
typedef struct typedef struct
{ {
/* internal subframes */ // Internal sub-frames
int16_t left[SUBFRAME_SIZE]; int16_t left[SUBFRAME_SIZE];
int16_t right[SUBFRAME_SIZE]; int16_t right[SUBFRAME_SIZE];
int16_t cc0[SUBFRAME_SIZE]; int16_t cc0[SUBFRAME_SIZE];
int16_t e50[SUBFRAME_SIZE]; int16_t e50[SUBFRAME_SIZE];
/* internal subframes base volumes */ // Internal sub-frames base volumes
int32_t base_vol[4]; int32_t base_vol[4];
/* */ // TODO: comment?
int16_t subframe_740_last4[4]; int16_t subframe_740_last4[4];
} musyx_t; } musyx_t;
typedef void (*mix_sfx_with_main_subframes_t)(musyx_t *musyx, const int16_t *subframe, const uint16_t* gains); typedef void (*mix_sfx_with_main_subframes_t)(musyx_t *musyx, const int16_t *subframe, const uint16_t* gains);
/* helper functions prototypes */ // Helper functions prototypes
static void load_base_vol(CHle * hle, int32_t *base_vol, uint32_t address); static void load_base_vol(CHle * hle, int32_t *base_vol, uint32_t address);
static void save_base_vol(CHle * hle, const int32_t *base_vol, uint32_t address); static void save_base_vol(CHle * hle, const int32_t *base_vol, uint32_t address);
static void update_base_vol(CHle * hle, int32_t *base_vol, uint32_t voice_mask, uint32_t last_sample_ptr, uint8_t mask_15, uint32_t ptr_24); static void update_base_vol(CHle * hle, int32_t *base_vol, uint32_t voice_mask, uint32_t last_sample_ptr, uint8_t mask_15, uint32_t ptr_24);
@ -150,9 +154,8 @@ static int32_t dot4(const int16_t *x, const int16_t *y)
return accu; return accu;
} }
/************************************************************************** // MusyX v1 audio microcode
* MusyX v1 audio ucode
**************************************************************************/
void musyx_v1_task(CHle * hle) void musyx_v1_task(CHle * hle)
{ {
uint32_t sfd_ptr = *dmem_u32(hle, TASK_DATA_PTR); uint32_t sfd_ptr = *dmem_u32(hle, TASK_DATA_PTR);
@ -164,14 +167,14 @@ void musyx_v1_task(CHle * hle)
state_ptr = *dram_u32(hle, sfd_ptr + SFD_STATE_PTR); state_ptr = *dram_u32(hle, sfd_ptr + SFD_STATE_PTR);
/* load initial state */ // Load initial state
load_base_vol(hle, musyx.base_vol, state_ptr + STATE_BASE_VOL); load_base_vol(hle, musyx.base_vol, state_ptr + STATE_BASE_VOL);
dram_load_u16(hle, (uint16_t *)musyx.cc0, state_ptr + STATE_CC0, SUBFRAME_SIZE); dram_load_u16(hle, (uint16_t *)musyx.cc0, state_ptr + STATE_CC0, SUBFRAME_SIZE);
dram_load_u16(hle, (uint16_t *)musyx.subframe_740_last4, state_ptr + STATE_740_LAST4_V1, 4); dram_load_u16(hle, (uint16_t *)musyx.subframe_740_last4, state_ptr + STATE_740_LAST4_V1, 4);
for (;;) for (;;)
{ {
/* parse SFD structure */ // Parse SFD structure
uint16_t sfx_index = *dram_u16(hle, sfd_ptr + SFD_SFX_INDEX); uint16_t sfx_index = *dram_u16(hle, sfd_ptr + SFD_SFX_INDEX);
uint32_t voice_mask = *dram_u32(hle, sfd_ptr + SFD_VOICE_BITMASK); uint32_t voice_mask = *dram_u32(hle, sfd_ptr + SFD_VOICE_BITMASK);
uint32_t sfx_ptr = *dram_u32(hle, sfd_ptr + SFD_SFX_PTR); uint32_t sfx_ptr = *dram_u32(hle, sfd_ptr + SFD_SFX_PTR);
@ -179,17 +182,17 @@ void musyx_v1_task(CHle * hle)
uint32_t last_sample_ptr = state_ptr + STATE_LAST_SAMPLE; uint32_t last_sample_ptr = state_ptr + STATE_LAST_SAMPLE;
uint32_t output_ptr; uint32_t output_ptr;
/* initialize internal subframes using updated base volumes */ // Initialize internal sub-frames using updated base volumes
update_base_vol(hle, musyx.base_vol, voice_mask, last_sample_ptr, 0, 0); update_base_vol(hle, musyx.base_vol, voice_mask, last_sample_ptr, 0, 0);
init_subframes_v1(&musyx); init_subframes_v1(&musyx);
/* active voices get mixed into L,R,cc0,e50 subframes (optional) */ // Active voices get mixed into L,R,cc0,e50 subframes (optional)
output_ptr = voice_stage(hle, &musyx, voice_ptr, last_sample_ptr); output_ptr = voice_stage(hle, &musyx, voice_ptr, last_sample_ptr);
/* apply delay-based effects (optional) */ // Apply delay-based effects (optional)
sfx_stage(hle, mix_sfx_with_main_subframes_v1, &musyx, sfx_ptr, sfx_index); sfx_stage(hle, mix_sfx_with_main_subframes_v1, &musyx, sfx_ptr, sfx_index);
/* emit interleaved L,R subframes */ // Emit interleaved L,R sub-frames
interleave_stage_v1(hle, &musyx, output_ptr); interleave_stage_v1(hle, &musyx, output_ptr);
--sfd_count; --sfd_count;
@ -202,15 +205,14 @@ void musyx_v1_task(CHle * hle)
state_ptr = *dram_u32(hle, sfd_ptr + SFD_STATE_PTR); state_ptr = *dram_u32(hle, sfd_ptr + SFD_STATE_PTR);
} }
/* writeback updated state */ // Writeback updated state
save_base_vol(hle, musyx.base_vol, state_ptr + STATE_BASE_VOL); save_base_vol(hle, musyx.base_vol, state_ptr + STATE_BASE_VOL);
dram_store_u16(hle, (uint16_t *)musyx.cc0, state_ptr + STATE_CC0, SUBFRAME_SIZE); dram_store_u16(hle, (uint16_t *)musyx.cc0, state_ptr + STATE_CC0, SUBFRAME_SIZE);
dram_store_u16(hle, (uint16_t *)musyx.subframe_740_last4, state_ptr + STATE_740_LAST4_V1, 4); dram_store_u16(hle, (uint16_t *)musyx.subframe_740_last4, state_ptr + STATE_740_LAST4_V1, 4);
} }
/************************************************************************** // MusyX v2 audio microcode
* MusyX v2 audio ucode
**************************************************************************/
void musyx_v2_task(CHle * hle) void musyx_v2_task(CHle * hle)
{ {
uint32_t sfd_ptr = *dmem_u32(hle, TASK_DATA_PTR); uint32_t sfd_ptr = *dmem_u32(hle, TASK_DATA_PTR);
@ -221,7 +223,7 @@ void musyx_v2_task(CHle * hle)
for (;;) for (;;)
{ {
/* parse SFD structure */ // Parse SFD structure
uint16_t sfx_index = *dram_u16(hle, sfd_ptr + SFD_SFX_INDEX); uint16_t sfx_index = *dram_u16(hle, sfd_ptr + SFD_SFX_INDEX);
uint32_t voice_mask = *dram_u32(hle, sfd_ptr + SFD_VOICE_BITMASK); uint32_t voice_mask = *dram_u32(hle, sfd_ptr + SFD_VOICE_BITMASK);
uint32_t state_ptr = *dram_u32(hle, sfd_ptr + SFD_STATE_PTR); uint32_t state_ptr = *dram_u32(hle, sfd_ptr + SFD_STATE_PTR);
@ -240,31 +242,31 @@ void musyx_v2_task(CHle * hle)
uint32_t last_sample_ptr = state_ptr + STATE_LAST_SAMPLE; uint32_t last_sample_ptr = state_ptr + STATE_LAST_SAMPLE;
uint32_t output_ptr; uint32_t output_ptr;
/* load state */ // Load state
load_base_vol(hle, musyx.base_vol, state_ptr + STATE_BASE_VOL); load_base_vol(hle, musyx.base_vol, state_ptr + STATE_BASE_VOL);
dram_load_u16(hle, (uint16_t *)musyx.subframe_740_last4, state_ptr + STATE_740_LAST4_V2, 4); dram_load_u16(hle, (uint16_t *)musyx.subframe_740_last4, state_ptr + STATE_740_LAST4_V2, 4);
/* initialize internal subframes using updated base volumes */ // Initialize internal sub-frames using updated base volumes
update_base_vol(hle, musyx.base_vol, voice_mask, last_sample_ptr, mask_15, ptr_24); update_base_vol(hle, musyx.base_vol, voice_mask, last_sample_ptr, mask_15, ptr_24);
init_subframes_v2(&musyx); init_subframes_v2(&musyx);
if (ptr_10) if (ptr_10)
{ {
/* TODO */ // TODO:
hle->WarnMessage("ptr_10=%08x mask_14=%02x ptr_24=%08x", ptr_10, mask_14, ptr_24); hle->WarnMessage("ptr_10=%08x mask_14=%02x ptr_24=%08x", ptr_10, mask_14, ptr_24);
} }
/* active voices get mixed into L,R,cc0,e50 subframes (optional) */ // Active voices get mixed into L,R,cc0,e50 sub-frames (optional)
output_ptr = voice_stage(hle, &musyx, voice_ptr, last_sample_ptr); output_ptr = voice_stage(hle, &musyx, voice_ptr, last_sample_ptr);
/* apply delay-based effects (optional) */ // Apply delay-based effects (optional)
sfx_stage(hle, mix_sfx_with_main_subframes_v2, &musyx, sfx_ptr, sfx_index); sfx_stage(hle, mix_sfx_with_main_subframes_v2, &musyx, sfx_ptr, sfx_index);
dram_store_u16(hle, (uint16_t*)musyx.left, output_ptr , SUBFRAME_SIZE); dram_store_u16(hle, (uint16_t*)musyx.left, output_ptr , SUBFRAME_SIZE);
dram_store_u16(hle, (uint16_t*)musyx.right, output_ptr + 2*SUBFRAME_SIZE, SUBFRAME_SIZE); dram_store_u16(hle, (uint16_t*)musyx.right, output_ptr + 2*SUBFRAME_SIZE, SUBFRAME_SIZE);
dram_store_u16(hle, (uint16_t*)musyx.cc0, output_ptr + 4*SUBFRAME_SIZE, SUBFRAME_SIZE); dram_store_u16(hle, (uint16_t*)musyx.cc0, output_ptr + 4*SUBFRAME_SIZE, SUBFRAME_SIZE);
/* store state */ // Store state
save_base_vol(hle, musyx.base_vol, state_ptr + STATE_BASE_VOL); save_base_vol(hle, musyx.base_vol, state_ptr + STATE_BASE_VOL);
dram_store_u16(hle, (uint16_t*)musyx.subframe_740_last4, state_ptr + STATE_740_LAST4_V2, 4); dram_store_u16(hle, (uint16_t*)musyx.subframe_740_last4, state_ptr + STATE_740_LAST4_V2, 4);
@ -318,7 +320,7 @@ static void update_base_vol(CHle * hle, int32_t *base_vol,
hle->VerboseMessage("base_vol voice_mask = %08x", voice_mask); hle->VerboseMessage("base_vol voice_mask = %08x", voice_mask);
hle->VerboseMessage("BEFORE: base_vol = %08x %08x %08x %08x", base_vol[0], base_vol[1], base_vol[2], base_vol[3]); hle->VerboseMessage("BEFORE: base_vol = %08x %08x %08x %08x", base_vol[0], base_vol[1], base_vol[2], base_vol[3]);
/* optim: skip voices contributions entirely if voice_mask is empty */ // optimization: skip voices contributions entirely if voice_mask is empty
if (voice_mask != 0) if (voice_mask != 0)
{ {
for (i = 0, mask = 1; i < MAX_VOICES; ++i, mask <<= 1, last_sample_ptr += 8) for (i = 0, mask = 1; i < MAX_VOICES; ++i, mask <<= 1, last_sample_ptr += 8)
@ -335,7 +337,7 @@ static void update_base_vol(CHle * hle, int32_t *base_vol,
} }
} }
/* optim: skip contributions entirely if mask_15 is empty */ // optimization: skip contributions entirely if mask_15 is empty
if (mask_15 != 0) if (mask_15 != 0)
{ {
for(i = 0, mask = 1; i < 4; ++i, mask <<= 1, ptr_24 += 8) for(i = 0, mask = 1; i < 4; ++i, mask <<= 1, ptr_24 += 8)
@ -352,7 +354,7 @@ static void update_base_vol(CHle * hle, int32_t *base_vol,
} }
} }
/* apply 3% decay */ // Apply 3% decay
for (k = 0; k < 4; ++k) for (k = 0; k < 4; ++k)
{ {
base_vol[k] = (base_vol[k] * 0x0000f850) >> 16; base_vol[k] = (base_vol[k] * 0x0000f850) >> 16;
@ -406,29 +408,30 @@ static void init_subframes_v2(musyx_t *musyx)
} }
} }
/* Process voices, and returns interleaved subframe destination address */ // Process voices, and returns interleaved sub-frame destination address
static uint32_t voice_stage(CHle * hle, musyx_t *musyx, uint32_t voice_ptr, uint32_t last_sample_ptr) static uint32_t voice_stage(CHle * hle, musyx_t *musyx, uint32_t voice_ptr, uint32_t last_sample_ptr)
{ {
uint32_t output_ptr; uint32_t output_ptr;
int i = 0; int i = 0;
/* voice stage can be skipped if first voice has no samples */ // Voice stage can be skipped if first voice has no samples
if (*dram_u16(hle, voice_ptr + VOICE_CATSRC_0 + CATSRC_SIZE1) == 0) if (*dram_u16(hle, voice_ptr + VOICE_CATSRC_0 + CATSRC_SIZE1) == 0)
{ {
hle->VerboseMessage("Skipping Voice stage"); hle->VerboseMessage("Skipping voice stage");
output_ptr = *dram_u32(hle, voice_ptr + VOICE_INTERLEAVED_PTR); output_ptr = *dram_u32(hle, voice_ptr + VOICE_INTERLEAVED_PTR);
} }
else else
{ {
/* otherwise process voices until a non null output_ptr is encountered */ // Otherwise process voices until a non null output_ptr is encountered
for (;;) for (;;)
{ {
/* load voice samples (PCM16 or APDCM) */ // Load voice samples (PCM16 or APDCM)
int16_t samples[SAMPLE_BUFFER_SIZE]; int16_t samples[SAMPLE_BUFFER_SIZE];
unsigned segbase; unsigned segbase;
unsigned offset; unsigned offset;
hle->VerboseMessage("Processing Voice #%d", i); hle->VerboseMessage("Processing voice #%d", i);
if (*dram_u8(hle, voice_ptr + VOICE_ADPCM_FRAMES) == 0) if (*dram_u8(hle, voice_ptr + VOICE_ADPCM_FRAMES) == 0)
{ {
@ -439,17 +442,17 @@ static uint32_t voice_stage(CHle * hle, musyx_t *musyx, uint32_t voice_ptr, uint
load_samples_ADPCM(hle, voice_ptr, samples, &segbase, &offset); load_samples_ADPCM(hle, voice_ptr, samples, &segbase, &offset);
} }
/* mix them with each internal subframes */ // Mix them with each internal sub-frame
mix_voice_samples(hle, musyx, voice_ptr, samples, segbase, offset, last_sample_ptr + i * 8); mix_voice_samples(hle, musyx, voice_ptr, samples, segbase, offset, last_sample_ptr + i * 8);
/* check break condition */ // Check break condition
output_ptr = *dram_u32(hle, voice_ptr + VOICE_INTERLEAVED_PTR); output_ptr = *dram_u32(hle, voice_ptr + VOICE_INTERLEAVED_PTR);
if (output_ptr != 0) if (output_ptr != 0)
{ {
break; break;
} }
/* next voice */ // Next voice
++i; ++i;
voice_ptr += VOICE_SIZE; voice_ptr += VOICE_SIZE;
} }
@ -524,8 +527,8 @@ static void load_samples_PCM16(CHle * hle, uint32_t voice_ptr, int16_t *samples,
static void load_samples_ADPCM(CHle * hle, uint32_t voice_ptr, int16_t *samples, unsigned *segbase, unsigned *offset) static void load_samples_ADPCM(CHle * hle, uint32_t voice_ptr, int16_t *samples, unsigned *segbase, unsigned *offset)
{ {
/* decompressed samples cannot exceed 0x400 bytes; // Decompressed samples cannot exceed 0x400 bytes
* ADPCM has a compression ratio of 5/16 */ // ADPCM has a compression ratio of 5/16
uint8_t buffer[SAMPLE_BUFFER_SIZE * 2 * 5 / 16]; uint8_t buffer[SAMPLE_BUFFER_SIZE * 2 * 5 / 16];
int16_t adpcm_table[128]; int16_t adpcm_table[128];
@ -620,16 +623,16 @@ static void mix_voice_samples(CHle * hle, musyx_t *musyx, uint32_t voice_ptr, co
{ {
int i, k; int i, k;
/* parse VOICE structure */ // Parse VOICE structure
const uint16_t pitch_q16 = *dram_u16(hle, voice_ptr + VOICE_PITCH_Q16); const uint16_t pitch_q16 = *dram_u16(hle, voice_ptr + VOICE_PITCH_Q16);
const uint16_t pitch_shift = *dram_u16(hle, voice_ptr + VOICE_PITCH_SHIFT); /* Q4.12 */ const uint16_t pitch_shift = *dram_u16(hle, voice_ptr + VOICE_PITCH_SHIFT); // Q4.12
const uint16_t end_point = *dram_u16(hle, voice_ptr + VOICE_END_POINT); const uint16_t end_point = *dram_u16(hle, voice_ptr + VOICE_END_POINT);
const uint16_t restart_point = *dram_u16(hle, voice_ptr + VOICE_RESTART_POINT); const uint16_t restart_point = *dram_u16(hle, voice_ptr + VOICE_RESTART_POINT);
const uint16_t u16_4e = *dram_u16(hle, voice_ptr + VOICE_U16_4E); const uint16_t u16_4e = *dram_u16(hle, voice_ptr + VOICE_U16_4E);
/* init values and pointers */ // Initialize values and pointers
const int16_t *sample = samples + segbase + offset + u16_4e; const int16_t *sample = samples + segbase + offset + u16_4e;
const int16_t *const sample_end = samples + segbase + end_point; const int16_t *const sample_end = samples + segbase + end_point;
const int16_t *const sample_restart = samples + (restart_point & 0x7fff) + const int16_t *const sample_restart = samples + (restart_point & 0x7fff) +
@ -655,7 +658,7 @@ static void mix_voice_samples(CHle * hle, musyx_t *musyx, uint32_t voice_ptr, co
for (i = 0; i < SUBFRAME_SIZE; ++i) for (i = 0; i < SUBFRAME_SIZE; ++i)
{ {
/* update sample and lut pointers and then pitch_accu */ // Update sample and LUT pointers and then pitch_accu
const int16_t *lut = (RESAMPLE_LUT + ((pitch_accu & 0xfc00) >> 8)); const int16_t *lut = (RESAMPLE_LUT + ((pitch_accu & 0xfc00) >> 8));
int dist; int dist;
int16_t v; int16_t v;
@ -664,30 +667,30 @@ static void mix_voice_samples(CHle * hle, musyx_t *musyx, uint32_t voice_ptr, co
pitch_accu &= 0xffff; pitch_accu &= 0xffff;
pitch_accu += pitch_step; pitch_accu += pitch_step;
/* handle end/restart points */ // Handle end/restart points
dist = sample - sample_end; dist = sample - sample_end;
if (dist >= 0) if (dist >= 0)
{ {
sample = sample_restart + dist; sample = sample_restart + dist;
} }
/* apply resample filter */ // Apply resample filter
v = clamp_s16(dot4(sample, lut)); v = clamp_s16(dot4(sample, lut));
for (k = 0; k < 4; ++k) for (k = 0; k < 4; ++k)
{ {
/* envmix */ // Envmix
int32_t accu = (v * (v4_env[k] >> 16)) >> 15; int32_t accu = (v * (v4_env[k] >> 16)) >> 15;
v4[k] = clamp_s16(accu); v4[k] = clamp_s16(accu);
*(v4_dst[k]) = clamp_s16(accu + *(v4_dst[k])); *(v4_dst[k]) = clamp_s16(accu + *(v4_dst[k]));
/* update envelopes and dst pointers */ // Update envelopes and DST pointers
++(v4_dst[k]); ++(v4_dst[k]);
v4_env[k] += v4_env_step[k]; v4_env[k] += v4_env_step[k];
} }
} }
/* save last resampled sample */ // Save last resampled sample
dram_store_u16(hle, (uint16_t *)v4, last_sample_ptr, 4); dram_store_u16(hle, (uint16_t *)v4, last_sample_ptr, 4);
hle->VerboseMessage("last_sample = %04x %04x %04x %04x", v4[0], v4[1], v4[2], v4[3]); hle->VerboseMessage("last_sample = %04x %04x %04x %04x", v4[0], v4[1], v4[2], v4[3]);
@ -722,7 +725,7 @@ static void sfx_stage(CHle * hle, mix_sfx_with_main_subframes_t mix_sfx_with_mai
return; return;
} }
/* load sfx parameters */ // Load SFX parameters
cbuffer_ptr = *dram_u32(hle, sfx_ptr + SFX_CBUFFER_PTR); cbuffer_ptr = *dram_u32(hle, sfx_ptr + SFX_CBUFFER_PTR);
cbuffer_length = *dram_u32(hle, sfx_ptr + SFX_CBUFFER_LENGTH); cbuffer_length = *dram_u32(hle, sfx_ptr + SFX_CBUFFER_LENGTH);
@ -742,7 +745,7 @@ static void sfx_stage(CHle * hle, mix_sfx_with_main_subframes_t mix_sfx_with_mai
hle->VerboseMessage("tap count=%d\n" "delays: %08x %08x %08x %08x %08x %08x %08x %08x\n" "gains: %04x %04x %04x %04x %04x %04x %04x %04x", tap_count, tap_delays[0], tap_delays[1], tap_delays[2], tap_delays[3], tap_delays[4], tap_delays[5], tap_delays[6], tap_delays[7], tap_gains[0], tap_gains[1], tap_gains[2], tap_gains[3], tap_gains[4], tap_gains[5], tap_gains[6], tap_gains[7]); hle->VerboseMessage("tap count=%d\n" "delays: %08x %08x %08x %08x %08x %08x %08x %08x\n" "gains: %04x %04x %04x %04x %04x %04x %04x %04x", tap_count, tap_delays[0], tap_delays[1], tap_delays[2], tap_delays[3], tap_delays[4], tap_delays[5], tap_delays[6], tap_delays[7], tap_gains[0], tap_gains[1], tap_gains[2], tap_gains[3], tap_gains[4], tap_gains[5], tap_gains[6], tap_gains[7]);
hle->VerboseMessage("sfx_gains=%04x %04x", sfx_gains[0], sfx_gains[1]); hle->VerboseMessage("sfx_gains=%04x %04x", sfx_gains[0], sfx_gains[1]);
/* mix up to 8 delayed subframes */ // Mix up to 8 delayed sub-frames
memset(subframe, 0, SUBFRAME_SIZE * sizeof(subframe[0])); memset(subframe, 0, SUBFRAME_SIZE * sizeof(subframe[0]));
for (i = 0; i < tap_count; ++i) for (i = 0; i < tap_count; ++i)
{ {
@ -764,10 +767,10 @@ static void sfx_stage(CHle * hle, mix_sfx_with_main_subframes_t mix_sfx_with_mai
mix_subframes(subframe, delayed, tap_gains[i]); mix_subframes(subframe, delayed, tap_gains[i]);
} }
/* add resulting subframe to main subframes */ // Add resulting sub-frame to main sub-frames
mix_sfx_with_main_subframes(musyx, subframe, sfx_gains); mix_sfx_with_main_subframes(musyx, subframe, sfx_gains);
/* apply FIR4 filter and writeback filtered result */ // Apply FIR4 filter and writeback filtered result
memcpy(buffer, musyx->subframe_740_last4, 4 * sizeof(int16_t)); memcpy(buffer, musyx->subframe_740_last4, 4 * sizeof(int16_t));
memcpy(musyx->subframe_740_last4, subframe + SUBFRAME_SIZE - 4, 4 * sizeof(int16_t)); memcpy(musyx->subframe_740_last4, subframe + SUBFRAME_SIZE - 4, 4 * sizeof(int16_t));
mix_fir4(musyx->e50, buffer + 1, fir4_hgain, fir4_hcoeffs); mix_fir4(musyx->e50, buffer + 1, fir4_hgain, fir4_hcoeffs);
@ -870,7 +873,7 @@ static void interleave_stage_v2(CHle * hle, musyx_t *musyx, uint16_t mask_16, ui
hle->VerboseMessage("mask_16=%04x ptr_18=%08x ptr_1c=%08x output_ptr=%08x", mask_16, ptr_18, ptr_1c, output_ptr); hle->VerboseMessage("mask_16=%04x ptr_18=%08x ptr_1c=%08x output_ptr=%08x", mask_16, ptr_18, ptr_1c, output_ptr);
/* compute L_total, R_total and update subframe @ptr_1c */ // Compute L_total, R_total and update sub-frame @ptr_1c
memset(subframe, 0, SUBFRAME_SIZE*sizeof(subframe[0])); memset(subframe, 0, SUBFRAME_SIZE*sizeof(subframe[0]));
for(i = 0; i < SUBFRAME_SIZE; ++i) for(i = 0; i < SUBFRAME_SIZE; ++i)
@ -901,7 +904,7 @@ static void interleave_stage_v2(CHle * hle, musyx_t *musyx, uint16_t mask_16, ui
} }
} }
/* interleave L_total and R_total */ // Interleave L_total and R_total
dst = dram_u32(hle, output_ptr); dst = dram_u32(hle, output_ptr);
for(i = 0; i < SUBFRAME_SIZE; ++i) for(i = 0; i < SUBFRAME_SIZE; ++i)
{ {
@ -910,6 +913,6 @@ static void interleave_stage_v2(CHle * hle, musyx_t *musyx, uint16_t mask_16, ui
*(dst++) = (l << 16) | r; *(dst++) = (l << 16) | r;
} }
/* writeback subframe @ptr_1c */ // Writeback sub-frame @ptr_1c
dram_store_u16(hle, (uint16_t*)subframe, ptr_1c, SUBFRAME_SIZE); dram_store_u16(hle, (uint16_t*)subframe, ptr_1c, SUBFRAME_SIZE);
} }

View File

@ -3,44 +3,47 @@
// Copyright(C) 2001-2021 Project64 // Copyright(C) 2001-2021 Project64
// Copyright(C) 2014 Bobby Smiles // Copyright(C) 2014 Bobby Smiles
// GNU/GPLv2 licensed: https://gnu.org/licenses/gpl-2.0.html // GNU/GPLv2 licensed: https://gnu.org/licenses/gpl-2.0.html
#pragma once #pragma once
class CHle; class CHle;
/* cic_x105 ucode */ // cic_x105 microcode
void cicx105_ucode(CHle * hle); void cicx105_ucode(CHle * hle);
/* audio list ucodes - audio */ // Audio list microcodes
enum { N_SEGMENTS = 16 }; enum { N_SEGMENTS = 16 };
struct alist_audio_t struct alist_audio_t
{ {
/* segments */ // Segments
uint32_t segments[N_SEGMENTS]; uint32_t segments[N_SEGMENTS];
/* main buffers */ // Main buffers
uint16_t in; uint16_t in;
uint16_t out; uint16_t out;
uint16_t count; uint16_t count;
/* auxiliary buffers */ // Auxiliary buffers
uint16_t dry_right; uint16_t dry_right;
uint16_t wet_left; uint16_t wet_left;
uint16_t wet_right; uint16_t wet_right;
/* gains */ // Gains
int16_t dry; int16_t dry;
int16_t wet; int16_t wet;
/* envelopes (0:left, 1:right) */ // Envelopes (0:left, 1:right)
int16_t vol[2]; int16_t vol[2];
int16_t target[2]; int16_t target[2];
int32_t rate[2]; int32_t rate[2];
/* ADPCM loop point address */ // ADPCM loop point address
uint32_t loop; uint32_t loop;
/* storage for ADPCM table and polef coefficients */ // Storage for ADPCM table and polef coefficients
int16_t table[16 * 8]; int16_t table[16 * 8];
}; };
@ -48,22 +51,23 @@ void alist_process_audio(CHle * hle);
void alist_process_audio_ge(CHle * hle); void alist_process_audio_ge(CHle * hle);
void alist_process_audio_bc(CHle * hle); void alist_process_audio_bc(CHle * hle);
/* audio list ucodes - naudio */ // Audio list microcodes - naudio
struct alist_naudio_t struct alist_naudio_t
{ {
/* gains */ // Gains
int16_t dry; int16_t dry;
int16_t wet; int16_t wet;
/* envelopes (0:left, 1:right) */ // Envelopes (0:left, 1:right)
int16_t vol[2]; int16_t vol[2];
int16_t target[2]; int16_t target[2];
int32_t rate[2]; int32_t rate[2];
/* ADPCM loop point address */ // ADPCM loop point address
uint32_t loop; uint32_t loop;
/* storage for ADPCM table and polef coefficients */ // Storage for ADPCM table and polef coefficients
int16_t table[16 * 8]; int16_t table[16 * 8];
}; };
@ -73,25 +77,26 @@ void alist_process_naudio_dk(CHle * hle);
void alist_process_naudio_mp3(CHle * hle); void alist_process_naudio_mp3(CHle * hle);
void alist_process_naudio_cbfd(CHle * hle); void alist_process_naudio_cbfd(CHle * hle);
/* audio list ucodes - nead */ // Audio list microcodes - nead
struct alist_nead_t struct alist_nead_t
{ {
/* main buffers */ // Main buffers
uint16_t in; uint16_t in;
uint16_t out; uint16_t out;
uint16_t count; uint16_t count;
/* envmixer ramps */ // Envmixer ramps
uint16_t env_values[3]; uint16_t env_values[3];
uint16_t env_steps[3]; uint16_t env_steps[3];
/* ADPCM loop point address */ // ADPCM loop point address
uint32_t loop; uint32_t loop;
/* storage for ADPCM table and polef coefficients */ // Storage for ADPCM table and polef coefficients
int16_t table[16 * 8]; int16_t table[16 * 8];
/* filter audio command state */ // Filter audio command state
uint16_t filter_count; uint16_t filter_count;
uint32_t filter_lut_address[2]; uint32_t filter_lut_address[2];
}; };
@ -108,14 +113,14 @@ void alist_process_nead_mm(CHle * hle);
void alist_process_nead_mmb(CHle * hle); void alist_process_nead_mmb(CHle * hle);
void alist_process_nead_ac(CHle * hle); void alist_process_nead_ac(CHle * hle);
/* mp3 ucode */ // MP3 microcode
void mp3_task(CHle * hle, unsigned int index, uint32_t address); void mp3_task(CHle * hle, unsigned int index, uint32_t address);
/* musyx ucodes */ // Musyx microcodes
void musyx_v1_task(CHle * hle); void musyx_v1_task(CHle * hle);
void musyx_v2_task(CHle * hle); void musyx_v2_task(CHle * hle);
/* jpeg ucodes */ // JPEG microcodes
void jpeg_decode_PS0(CHle * hle); void jpeg_decode_PS0(CHle * hle);
void jpeg_decode_PS(CHle * hle); void jpeg_decode_PS(CHle * hle);
void jpeg_decode_OB(CHle * hle); void jpeg_decode_OB(CHle * hle);