Merge pull request #2018 from vgturtle127/beautification-4
Beautification 4 - the Source/Android directory
This commit is contained in:
commit
538318ea5c
|
@ -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.
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ public:
|
||||||
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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -22,5 +22,4 @@ void SyncBridge::SwapWindow()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -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"));
|
||||||
|
|
|
@ -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,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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,7 +641,8 @@ 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 Java VM. 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
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,4 +27,3 @@ void CJniBridegSettings::RefreshSettings(void *)
|
||||||
{
|
{
|
||||||
m_bCPURunning = g_Settings->LoadBool(GameRunning_CPU_Running);
|
m_bCPURunning = g_Settings->LoadBool(GameRunning_CPU_Running);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
@ -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);
|
|
@ -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*/ )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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];
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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] = {
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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:
|
||||||
|
@ -229,19 +235,19 @@ bool CHle::try_fast_audio_dispatching(void)
|
||||||
Hydro Thunder, Tarzan, Gauntlet Legend, Rush 2049 */
|
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
|
||||||
}
|
}
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue