Android: Move hle audio code in to main rsp plugin

This commit is contained in:
zilmar 2023-11-02 20:06:58 +10:30
parent 924197ca9a
commit 6fbc5c0264
63 changed files with 1771 additions and 1613 deletions

View File

@ -32,7 +32,7 @@ xcopy "%base_dir%/Source/Android/PluginInput" "%base_dir%/Android/jni/Plugin-Inp
IF %ERRORLEVEL% NEQ 0 (exit /B 1)
echo copy PluginRSP
xcopy "%base_dir%/Source/Android/PluginRSP" "%base_dir%/Android/jni/Plugin-RspHle/" /D /I /F /Y /E
xcopy "%base_dir%/Source/Android/PluginRSP" "%base_dir%/Android/jni/Plugin-Rsp/" /D /I /F /Y /E
IF %ERRORLEVEL% NEQ 0 (exit /B 1)
echo copy Project64-bridge

View File

@ -44,5 +44,4 @@ dependencies {
implementation project(':jni:Project64-video')
implementation project(':jni:Project64-audio')
implementation project(':jni:Plugin-input')
implementation project(':jni:Plugin-RspHle')
}

View File

@ -1 +1 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="emu.project64.common" />
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="emu.project64.common" />

View File

@ -0,0 +1 @@
<manifest package="emu.project64.plugin_rsp" />

View File

@ -0,0 +1,14 @@
cmake_minimum_required(VERSION 2.8.12)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_C_STANDARD 99)
project("Project64-rsp")
include_directories(..)
add_library(Project64-rsp SHARED
main.cpp)
add_definitions(-DANDROID)
ADD_SUBDIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/../Settings ${CMAKE_CURRENT_BINARY_DIR}/Settings)
target_link_libraries(Project64-rsp settings)

View File

@ -1 +0,0 @@
<manifest package="emu.project64.plugin_rsphle" />

View File

@ -1,23 +0,0 @@
cmake_minimum_required(VERSION 2.8.12)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_C_STANDARD 99)
project("Project64-rsp-hle")
add_library(Project64-rsp-hle SHARED
alist.cpp
alist_audio.cpp
alist_naudio.cpp
alist_nead.cpp
audio.cpp
cicx105.cpp
hle.cpp
jpeg.cpp
main.cpp
mem.cpp
mp3.cpp
musyx.cpp)
add_definitions(-DANDROID)
target_link_libraries(Project64-rsp-hle)

View File

@ -1 +1 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="emu.project64.project64_core" />
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="emu.project64.project64_core" />

View File

@ -0,0 +1 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="emu.project64.project64_rsp_core" />

View File

@ -0,0 +1,12 @@
cmake_minimum_required(VERSION 2.8.12)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_C_STANDARD 99)
project("Project64.rsp.core")
add_library(Project64.rsp.core STATIC
Hle/alist.cpp)
add_definitions(-DANDROID)
target_link_libraries(Project64.rsp.core)

View File

@ -0,0 +1,63 @@
apply plugin: 'com.android.library'
apply from: '../../config/version.gradle'
android {
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
ndk {
debugSymbolLevel 'FULL'
}
}
debug {
minifyEnabled true
jniDebuggable true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
ndk {
debugSymbolLevel 'FULL'
}
}
}
externalNativeBuild {
cmake {
version "3.22.1"
path "CMakeLists.txt"
}
}
defaultConfig {
externalNativeBuild {
cmake {
arguments "-DANDROID=1", "-DCMAKE_BUILD_TYPE=Release", "-DANDROID_ARM_NEON=TRUE", "-DANDROID_TOOLCHAIN=clang"
cppFlags "-fexceptions", "-ffast-math", "-ftree-vectorize"
cFlags "-ffast-math", "-ftree-vectorize"
abiFilters "armeabi-v7a", "arm64-v8a", "x86", "x86_64"
}
}
}
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
}
}
packagingOptions {
exclude 'lib/x86/libc++_shared.so'
exclude 'lib/x86_64/libc++_shared.so'
exclude 'lib/armeabi-v7a/libc++_shared.so'
exclude 'lib/arm64-v8a/libc++_shared.so'
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
}

View File

@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

View File

@ -1,2 +1,2 @@
rootProject.name = 'Project64'
include ':app', ':jni:3rdParty:asmjit', ':jni:3rdParty:png', ':jni:3rdParty:zlib', ':jni:Common', ':jni:Settings', ':jni:Project64-core', ':jni:Project64-bridge', ':jni:Project64-video', ':jni:Project64-audio', ':jni:Plugin-input', ':jni:Plugin-RspHle'
include ':app', ':jni:3rdParty:asmjit', ':jni:3rdParty:png', ':jni:3rdParty:zlib', ':jni:Common', ':jni:Settings', ':jni:Project64-core', ':jni:Project64-bridge', ':jni:Project64-video', ':jni:Project64-audio', ':jni:Plugin-input'

View File

@ -60,7 +60,6 @@ EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Project64", "Source\Project64\Project64.vcxproj", "{7E534C8E-1ACE-4A88-8807-39A11ED4DA18}"
ProjectSection(ProjectDependencies) = postProject
{A7ED562C-63F3-4B7E-B6B3-2CF7848752E1} = {A7ED562C-63F3-4B7E-B6B3-2CF7848752E1}
{B685BB34-D700-4FCC-8503-9B6AA1A0C95D} = {B685BB34-D700-4FCC-8503-9B6AA1A0C95D}
{D3F979CE-8FA7-48C9-A2B3-A33594B48536} = {D3F979CE-8FA7-48C9-A2B3-A33594B48536}
EndProjectSection
EndProject

View File

@ -20,8 +20,7 @@
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{B685BB34-D700-4FCC-8503-9B6AA1A0C95D}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>RSPhle</RootNamespace>
<RootNamespace>RSPbasic</RootNamespace>
</PropertyGroup>
<PropertyGroup Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
@ -33,45 +32,34 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<PropertyGroup>
<TargetName>RSP-HLE</TargetName>
<TargetName Condition="'$(Configuration)'=='Debug'">RSP-HLE_d</TargetName>
<TargetName>Project64-RSP-Basic</TargetName>
<TargetName Condition="'$(Configuration)'=='Debug'">Project64-RSP-Basic_d</TargetName>
<OutDir>$(SolutionDir)Plugin\RSP\</OutDir>
<OutDir Condition="'$(Platform)'=='x64'">$(SolutionDir)Plugin64\RSP\</OutDir>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DisableSpecificWarnings>4800;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="alist.cpp" />
<ClCompile Include="alist_audio.cpp" />
<ClCompile Include="alist_naudio.cpp" />
<ClCompile Include="alist_nead.cpp" />
<ClCompile Include="audio.cpp" />
<ClCompile Include="cicx105.cpp" />
<ClCompile Include="hle.cpp" />
<ClCompile Include="jpeg.cpp" />
<ClCompile Include="main.cpp" />
<ClCompile Include="mem.cpp" />
<ClCompile Include="mp3.cpp" />
<ClCompile Include="musyx.cpp" />
<ClCompile Include="stdafx.cpp">
<PrecompiledHeader>Create</PrecompiledHeader>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="alist.h" />
<ClInclude Include="arithmetics.h" />
<ClInclude Include="audio.h" />
<ClInclude Include="common.h" />
<ClInclude Include="hle.h" />
<ClInclude Include="mem.h" />
<ClInclude Include="Rsp.h" />
<ClInclude Include="stdafx.h" />
<ClInclude Include="ucodes.h" />
<ClInclude Include="Version.h" />
<ProjectReference Include="..\..\Common\Common.vcxproj">
<Project>{b4a4b994-9111-42b1-93c2-6f1ca8bc4421}</Project>
</ProjectReference>
<ProjectReference Include="..\..\Project64-rsp-core\Project64-rsp-core.vcxproj">
<Project>{7598f6b8-9da6-4897-b26f-f6865f824bf4}</Project>
</ProjectReference>
<ProjectReference Include="..\..\Settings\Settings.vcxproj">
<Project>{8b9961b1-88d9-4ea3-a752-507a00dd9f3d}</Project>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Project64-rsp.rc" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="resource.h" />
</ItemGroup>
</Project>

View File

@ -18,72 +18,14 @@
<ClCompile Include="main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="stdafx.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="hle.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="alist_audio.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="alist.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="audio.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="mem.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="jpeg.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="alist_naudio.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="alist_nead.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="mp3.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="musyx.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="cicx105.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="stdafx.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Rsp.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Version.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="hle.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ucodes.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="alist.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="common.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="mem.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="arithmetics.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="audio.h">
<ResourceCompile Include="Project64-rsp.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="resource.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>

View File

@ -0,0 +1,74 @@
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#include "../../Project64-rsp-core/Version.h"
#define APSTUDIO_READONLY_SYMBOLS
#include "WinResrc.h"
#ifdef IDC_STATIC
#undef IDC_STATIC
#endif
#define IDC_STATIC (-1)
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (Australia) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENA)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_AUS
#pragma code_page(1252)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION VER_FILE_VERSION
PRODUCTVERSION VER_PRODUCT_VERSION
FILEFLAGSMASK 0x3fL
FILEFLAGS VER_FILEFLAGS
FILEOS VER_FILEOS
FILETYPE VER_FILETYPE
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "0c0904b0"
BEGIN
VALUE "FileDescription", VER_FILE_DESCRIPTION_STR "\0"
VALUE "FileVersion", VER_FILE_VERSION_STR "\0"
VALUE "InternalName", VER_INTERNAL_NAME_STR "\0"
VALUE "LegalCopyright", VER_COPYRIGHT_STR "\0"
VALUE "OriginalFilename", VER_ORIGINAL_FILENAME_STR "\0"
VALUE "ProductName", VER_PRODUCTNAME_STR
VALUE "ProductVersion", VER_PRODUCT_VERSION_STR "\0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
#endif // English (Australia) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View File

@ -5,7 +5,7 @@
typedef struct
{
void * hInst;
int32_t MemoryBswaped; // If this is set to TRUE, then the memory has been pre-bswap'd on a DWORD (32-bits) boundary
int32_t MemoryBswaped; // If this is set to TRUE, then the memory has been pre-bswap'd on a DWORD (32-bits) boundary
uint8_t * RDRAM;
uint8_t * DMEM;
uint8_t * IMEM;
@ -31,11 +31,11 @@ typedef struct
uint32_t * DPC_PIPEBUSY_REG;
uint32_t * DPC_TMEM_REG;
void(*CheckInterrupts)(void);
void(*ProcessDList)(void);
void(*ProcessAList)(void);
void(*ProcessRdpList)(void);
void(*ShowCFB)(void);
void (*CheckInterrupts)(void);
void (*ProcessDList)(void);
void (*ProcessAList)(void);
void (*ProcessRdpList)(void);
void (*ShowCFB)(void);
} RSP_INFO;
EXPORT void CloseDLL(void);

View File

@ -1,31 +0,0 @@
#define STRINGIZE2(s) #s
#define STRINGIZE(s) STRINGIZE2(s)
#define VERSION_MAJOR 1
#define VERSION_MINOR 0
#define VERSION_REVISION 1
#define VERSION_BUILD 9999
#define VER_FILE_DESCRIPTION_STR "RSP HLE Plugin"
#define VER_FILE_VERSION VERSION_MAJOR, VERSION_MINOR, VERSION_REVISION, VERSION_BUILD
#define VER_FILE_VERSION_STR STRINGIZE(VERSION_MAJOR) \
"." STRINGIZE(VERSION_MINOR) \
"." STRINGIZE(VERSION_REVISION) \
"." STRINGIZE(VERSION_BUILD) \
#define VER_PRODUCTNAME_STR "RSP-HLE"
#define VER_PRODUCT_VERSION VER_FILE_VERSION
#define VER_PRODUCT_VERSION_STR VER_FILE_VERSION_STR
#define VER_ORIGINAL_FILENAME_STR VER_PRODUCTNAME_STR ".dll"
#define VER_INTERNAL_NAME_STR VER_PRODUCTNAME_STR
#define VER_COPYRIGHT_STR "Copyright (C) 2021"
#ifdef _DEBUG
#define VER_VER_DEBUG VS_FF_DEBUG
#else
#define VER_VER_DEBUG 0
#endif
#define VER_FILEOS VOS_NT_WINDOWS32
#define VER_FILEFLAGS VER_VER_DEBUG
#define VER_FILETYPE VFT_DLL

View File

@ -1,50 +0,0 @@
// Project64 - A Nintendo 64 emulator
// https://www.pj64-emu.com/
// Copyright(C) 2001-2021 Project64
// Copyright(C) 2014 Bobby Smiles
// GNU/GPLv2 licensed: https://gnu.org/licenses/gpl-2.0.html
#pragma once
class CHle;
typedef void(*acmd_callback_t)(CHle* hle, uint32_t w1, uint32_t w2);
void alist_process(CHle * hle, const acmd_callback_t abi[], unsigned int abi_size);
uint32_t alist_get_address(CHle * hle, uint32_t so, const uint32_t *segments, size_t n);
void alist_set_address(CHle * hle, uint32_t so, uint32_t *segments, size_t n);
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_save(CHle * hle, uint16_t dmem, uint32_t address, uint16_t count);
void alist_move(CHle * hle, uint16_t dmemo, uint16_t dmemi, uint16_t count);
void alist_copy_every_other_sample(CHle * hle, uint16_t dmemo, uint16_t dmemi, uint16_t count);
void alist_repeat64(CHle * hle, uint16_t dmemo, uint16_t dmemi, uint8_t count);
void alist_copy_blocks(CHle * hle, uint16_t dmemo, uint16_t dmemi, uint16_t block_size, uint8_t count);
void alist_interleave(CHle * hle, uint16_t dmemo, uint16_t left, uint16_t right, uint16_t count);
void alist_envmix_exp( CHle * hle, bool init, bool aux, uint16_t dmem_dl, uint16_t dmem_dr, uint16_t dmem_wl, uint16_t dmem_wr, uint16_t dmemi, uint16_t count, int16_t dry, int16_t wet, const int16_t *vol, const int16_t *target, const int32_t *rate, uint32_t address);
void alist_envmix_ge( CHle * hle, bool init, bool aux, uint16_t dmem_dl, uint16_t dmem_dr, uint16_t dmem_wl, uint16_t dmem_wr, uint16_t dmemi, uint16_t count, int16_t dry, int16_t wet, const int16_t *vol, const int16_t *target, const int32_t *rate, uint32_t address);
void alist_envmix_lin( CHle * hle, bool init, uint16_t dmem_dl, uint16_t dmem_dr, uint16_t dmem_wl, uint16_t dmem_wr, uint16_t dmemi, uint16_t count, int16_t dry, int16_t wet, const int16_t *vol, const int16_t *target, const int32_t *rate, uint32_t address);
void alist_envmix_nead( CHle * hle, bool swap_wet_LR, uint16_t dmem_dl, uint16_t dmem_dr, uint16_t dmem_wl, uint16_t dmem_wr, uint16_t dmemi, unsigned count, uint16_t *env_values, uint16_t *env_steps, const int16_t *xors);
void alist_mix(CHle * hle, uint16_t dmemo, uint16_t dmemi, uint16_t count, int16_t gain);
void alist_multQ44(CHle * hle, uint16_t dmem, uint16_t count, int8_t gain);
void alist_add(CHle * hle, uint16_t dmemo, uint16_t dmemi, uint16_t count);
void alist_adpcm( CHle * hle, bool init, bool loop, bool two_bit_per_sample, uint16_t dmemo, uint16_t dmemi, uint16_t count, const int16_t* codebook, uint32_t loop_address, uint32_t last_frame_address);
void alist_resample( CHle * hle, bool init, bool flag2, uint16_t dmemo, uint16_t dmemi, uint16_t count, uint32_t pitch, uint32_t address);
void alist_polef( CHle * hle, bool init,uint16_t dmemo, uint16_t dmemi, uint16_t count, uint16_t gain, int16_t* table, uint32_t address);
void alist_iirf( CHle * hle, bool init, uint16_t dmemo, uint16_t dmemi, uint16_t count, int16_t* table, uint32_t address);
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);
// Audio flags
#define A_INIT 0x01
#define A_CONTINUE 0x00
#define A_LOOP 0x02
#define A_OUT 0x02
#define A_LEFT 0x02
#define A_RIGHT 0x00
#define A_VOL 0x04
#define A_RATE 0x00
#define A_AUX 0x08
#define A_NOAUX 0x00
#define A_MAIN 0x00
#define A_MIX 0x10

View File

@ -1,114 +0,0 @@
// Project64 - A Nintendo 64 emulator
// https://www.pj64-emu.com/
// Copyright(C) 2001-2021 Project64
// Copyright(C) 2014 Bobby Smiles
// GNU/GPLv2 licensed: https://gnu.org/licenses/gpl-2.0.html
#include "stdafx.h"
#include <assert.h>
#include "audio.h"
#include "arithmetics.h"
const int16_t RESAMPLE_LUT[64 * 4] =
{
(int16_t)0x0c39u, (int16_t)0x66adu, (int16_t)0x0d46u, (int16_t)0xffdfu,
(int16_t)0x0b39u, (int16_t)0x6696u, (int16_t)0x0e5fu, (int16_t)0xffd8u,
(int16_t)0x0a44u, (int16_t)0x6669u, (int16_t)0x0f83u, (int16_t)0xffd0u,
(int16_t)0x095au, (int16_t)0x6626u, (int16_t)0x10b4u, (int16_t)0xffc8u,
(int16_t)0x087du, (int16_t)0x65cdu, (int16_t)0x11f0u, (int16_t)0xffbfu,
(int16_t)0x07abu, (int16_t)0x655eu, (int16_t)0x1338u, (int16_t)0xffb6u,
(int16_t)0x06e4u, (int16_t)0x64d9u, (int16_t)0x148cu, (int16_t)0xffacu,
(int16_t)0x0628u, (int16_t)0x643fu, (int16_t)0x15ebu, (int16_t)0xffa1u,
(int16_t)0x0577u, (int16_t)0x638fu, (int16_t)0x1756u, (int16_t)0xff96u,
(int16_t)0x04d1u, (int16_t)0x62cbu, (int16_t)0x18cbu, (int16_t)0xff8au,
(int16_t)0x0435u, (int16_t)0x61f3u, (int16_t)0x1a4cu, (int16_t)0xff7eu,
(int16_t)0x03a4u, (int16_t)0x6106u, (int16_t)0x1bd7u, (int16_t)0xff71u,
(int16_t)0x031cu, (int16_t)0x6007u, (int16_t)0x1d6cu, (int16_t)0xff64u,
(int16_t)0x029fu, (int16_t)0x5ef5u, (int16_t)0x1f0bu, (int16_t)0xff56u,
(int16_t)0x022au, (int16_t)0x5dd0u, (int16_t)0x20b3u, (int16_t)0xff48u,
(int16_t)0x01beu, (int16_t)0x5c9au, (int16_t)0x2264u, (int16_t)0xff3au,
(int16_t)0x015bu, (int16_t)0x5b53u, (int16_t)0x241eu, (int16_t)0xff2cu,
(int16_t)0x0101u, (int16_t)0x59fcu, (int16_t)0x25e0u, (int16_t)0xff1eu,
(int16_t)0x00aeu, (int16_t)0x5896u, (int16_t)0x27a9u, (int16_t)0xff10u,
(int16_t)0x0063u, (int16_t)0x5720u, (int16_t)0x297au, (int16_t)0xff02u,
(int16_t)0x001fu, (int16_t)0x559du, (int16_t)0x2b50u, (int16_t)0xfef4u,
(int16_t)0xffe2u, (int16_t)0x540du, (int16_t)0x2d2cu, (int16_t)0xfee8u,
(int16_t)0xffacu, (int16_t)0x5270u, (int16_t)0x2f0du, (int16_t)0xfedbu,
(int16_t)0xff7cu, (int16_t)0x50c7u, (int16_t)0x30f3u, (int16_t)0xfed0u,
(int16_t)0xff53u, (int16_t)0x4f14u, (int16_t)0x32dcu, (int16_t)0xfec6u,
(int16_t)0xff2eu, (int16_t)0x4d57u, (int16_t)0x34c8u, (int16_t)0xfebdu,
(int16_t)0xff0fu, (int16_t)0x4b91u, (int16_t)0x36b6u, (int16_t)0xfeb6u,
(int16_t)0xfef5u, (int16_t)0x49c2u, (int16_t)0x38a5u, (int16_t)0xfeb0u,
(int16_t)0xfedfu, (int16_t)0x47edu, (int16_t)0x3a95u, (int16_t)0xfeacu,
(int16_t)0xfeceu, (int16_t)0x4611u, (int16_t)0x3c85u, (int16_t)0xfeabu,
(int16_t)0xfec0u, (int16_t)0x4430u, (int16_t)0x3e74u, (int16_t)0xfeacu,
(int16_t)0xfeb6u, (int16_t)0x424au, (int16_t)0x4060u, (int16_t)0xfeafu,
(int16_t)0xfeafu, (int16_t)0x4060u, (int16_t)0x424au, (int16_t)0xfeb6u,
(int16_t)0xfeacu, (int16_t)0x3e74u, (int16_t)0x4430u, (int16_t)0xfec0u,
(int16_t)0xfeabu, (int16_t)0x3c85u, (int16_t)0x4611u, (int16_t)0xfeceu,
(int16_t)0xfeacu, (int16_t)0x3a95u, (int16_t)0x47edu, (int16_t)0xfedfu,
(int16_t)0xfeb0u, (int16_t)0x38a5u, (int16_t)0x49c2u, (int16_t)0xfef5u,
(int16_t)0xfeb6u, (int16_t)0x36b6u, (int16_t)0x4b91u, (int16_t)0xff0fu,
(int16_t)0xfebdu, (int16_t)0x34c8u, (int16_t)0x4d57u, (int16_t)0xff2eu,
(int16_t)0xfec6u, (int16_t)0x32dcu, (int16_t)0x4f14u, (int16_t)0xff53u,
(int16_t)0xfed0u, (int16_t)0x30f3u, (int16_t)0x50c7u, (int16_t)0xff7cu,
(int16_t)0xfedbu, (int16_t)0x2f0du, (int16_t)0x5270u, (int16_t)0xffacu,
(int16_t)0xfee8u, (int16_t)0x2d2cu, (int16_t)0x540du, (int16_t)0xffe2u,
(int16_t)0xfef4u, (int16_t)0x2b50u, (int16_t)0x559du, (int16_t)0x001fu,
(int16_t)0xff02u, (int16_t)0x297au, (int16_t)0x5720u, (int16_t)0x0063u,
(int16_t)0xff10u, (int16_t)0x27a9u, (int16_t)0x5896u, (int16_t)0x00aeu,
(int16_t)0xff1eu, (int16_t)0x25e0u, (int16_t)0x59fcu, (int16_t)0x0101u,
(int16_t)0xff2cu, (int16_t)0x241eu, (int16_t)0x5b53u, (int16_t)0x015bu,
(int16_t)0xff3au, (int16_t)0x2264u, (int16_t)0x5c9au, (int16_t)0x01beu,
(int16_t)0xff48u, (int16_t)0x20b3u, (int16_t)0x5dd0u, (int16_t)0x022au,
(int16_t)0xff56u, (int16_t)0x1f0bu, (int16_t)0x5ef5u, (int16_t)0x029fu,
(int16_t)0xff64u, (int16_t)0x1d6cu, (int16_t)0x6007u, (int16_t)0x031cu,
(int16_t)0xff71u, (int16_t)0x1bd7u, (int16_t)0x6106u, (int16_t)0x03a4u,
(int16_t)0xff7eu, (int16_t)0x1a4cu, (int16_t)0x61f3u, (int16_t)0x0435u,
(int16_t)0xff8au, (int16_t)0x18cbu, (int16_t)0x62cbu, (int16_t)0x04d1u,
(int16_t)0xff96u, (int16_t)0x1756u, (int16_t)0x638fu, (int16_t)0x0577u,
(int16_t)0xffa1u, (int16_t)0x15ebu, (int16_t)0x643fu, (int16_t)0x0628u,
(int16_t)0xffacu, (int16_t)0x148cu, (int16_t)0x64d9u, (int16_t)0x06e4u,
(int16_t)0xffb6u, (int16_t)0x1338u, (int16_t)0x655eu, (int16_t)0x07abu,
(int16_t)0xffbfu, (int16_t)0x11f0u, (int16_t)0x65cdu, (int16_t)0x087du,
(int16_t)0xffc8u, (int16_t)0x10b4u, (int16_t)0x6626u, (int16_t)0x095au,
(int16_t)0xffd0u, (int16_t)0x0f83u, (int16_t)0x6669u, (int16_t)0x0a44u,
(int16_t)0xffd8u, (int16_t)0x0e5fu, (int16_t)0x6696u, (int16_t)0x0b39u,
(int16_t)0xffdfu, (int16_t)0x0d46u, (int16_t)0x66adu, (int16_t)0x0c39u
};
int32_t rdot(size_t n, const int16_t *x, const int16_t *y)
{
int32_t accu = 0;
y += n;
while (n != 0) {
accu += *(x++) * *(--y);
--n;
}
return accu;
}
void adpcm_compute_residuals(int16_t* dst, const int16_t* src,
const int16_t* cb_entry, const int16_t* last_samples, size_t count)
{
const int16_t* const book1 = cb_entry;
const int16_t* const book2 = cb_entry + 8;
const int16_t l1 = last_samples[0];
const int16_t l2 = last_samples[1];
size_t i;
assert(count <= 8);
for (i = 0; i < count; ++i)
{
int32_t accu = (int32_t)src[i] << 11;
accu += book1[i] * l1 + book2[i] * l2 + rdot(i, book2, src);
dst[i] = clamp_s16(accu >> 11);
}
}

View File

@ -1,51 +0,0 @@
// Project64 - A Nintendo 64 emulator
// https://www.pj64-emu.com/
// Copyright(C) 2001-2021 Project64
// Copyright(C) 2014 Bobby Smiles
// Copyright(C) 2009 Richard Goedeken
// Copyright(C) 2002 Hacktarux
// GNU/GPLv2 licensed: https://gnu.org/licenses/gpl-2.0.html
#pragma once
// Macro for unused variable warning suppression
#ifdef __GNUC__
# define UNUSED(x) UNUSED_ ## x __attribute__((__unused__))
#else
# define UNUSED(x) /* x */
#endif
// Macro for inline keyword
#ifdef _MSC_VER
#define inline __inline
#endif
// DLL function linking
#if defined(_WIN32)
#define EXPORT extern "C" __declspec(dllexport)
#define CALL __cdecl
#else
#define EXPORT extern "C" __attribute__((visibility("default")))
#define CALL
#endif
// Plugin types
enum
{
PLUGIN_TYPE_RSP = 1,
PLUGIN_TYPE_VIDEO = 2,
PLUGIN_TYPE_AUDIO = 3,
PLUGIN_TYPE_CONTROLLER = 4,
};
// Structures
typedef struct
{
uint16_t Version; // Should be set to 0x0101
uint16_t Type; // Set to PLUGIN_TYPE_RSP
char Name[100]; // Name of the DLL
// If DLL supports memory, these memory options then set them to TRUE or FALSE if it does not support it
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
} PLUGIN_INFO;

View File

@ -1,158 +0,0 @@
// Project64 - A Nintendo 64 emulator
// https://www.pj64-emu.com/
// Copyright(C) 2001-2021 Project64
// Copyright(C) 2014 Bobby Smiles
// GNU/GPLv2 licensed: https://gnu.org/licenses/gpl-2.0.html
#pragma once
#include <stdint.h>
#include "Rsp.h"
#include "ucodes.h"
// Signal processor interface flags
enum
{
SP_CLR_HALT = 0x00001, // Bit 0: Clear halt
SP_SET_HALT = 0x00002, // Bit 1: Set halt
SP_CLR_BROKE = 0x00004, // Bit 2: Clear broke
SP_CLR_INTR = 0x00008, // Bit 3: Clear INTR
SP_SET_INTR = 0x00010, // Bit 4: Set INTR
SP_CLR_SSTEP = 0x00020, // Bit 5: Clear SSTEP
SP_SET_SSTEP = 0x00040, // Bit 6: Set SSTEP
SP_CLR_INTR_BREAK = 0x00080, // Bit 7: Clear INTR on break
SP_SET_INTR_BREAK = 0x00100, // Bit 8: Set INTR on break
SP_CLR_SIG0 = 0x00200, // Bit 9: Clear signal 0
SP_SET_SIG0 = 0x00400, // Bit 10: Set signal 0
SP_CLR_SIG1 = 0x00800, // Bit 11: Clear signal 1
SP_SET_SIG1 = 0x01000, // Bit 12: Set signal 1
SP_CLR_SIG2 = 0x02000, // Bit 13: Clear signal 2
SP_SET_SIG2 = 0x04000, // Bit 14: Set signal 2
SP_CLR_SIG3 = 0x08000, // Bit 15: Clear signal 3
SP_SET_SIG3 = 0x10000, // Bit 16: Set signal 3
SP_CLR_SIG4 = 0x20000, // Bit 17: Clear signal 4
SP_SET_SIG4 = 0x40000, // Bit 18: Set signal 4
SP_CLR_SIG5 = 0x80000, // Bit 19: Clear signal 5
SP_SET_SIG5 = 0x100000, // Bit 20: Set signal 5
SP_CLR_SIG6 = 0x200000, // Bit 21: Clear signal 6
SP_SET_SIG6 = 0x400000, // Bit 22: Set signal 6
SP_CLR_SIG7 = 0x800000, // Bit 23: Clear signal 7
SP_SET_SIG7 = 0x1000000, // Bit 24: Set signal 7
SP_STATUS_HALT = 0x001, // Bit 0: Halt
SP_STATUS_BROKE = 0x002, // Bit 1: Broke
SP_STATUS_DMA_BUSY = 0x004, // Bit 2: DMA busy
SP_STATUS_DMA_FULL = 0x008, // Bit 3: DMA full
SP_STATUS_IO_FULL = 0x010, // Bit 4: IO full
SP_STATUS_SSTEP = 0x020, // Bit 5: Single step
SP_STATUS_INTR_BREAK = 0x040, // Bit 6: Interrupt on break
SP_STATUS_SIG0 = 0x080, // Bit 7: Signal 0 set
SP_STATUS_SIG1 = 0x100, // Bit 8: Signal 1 set
SP_STATUS_SIG2 = 0x200, // Bit 9: Signal 2 set
SP_STATUS_SIG3 = 0x400, // Bit 10: Signal 3 set
SP_STATUS_SIG4 = 0x800, // Bit 11: Signal 4 set
SP_STATUS_SIG5 = 0x1000, // Bit 12: Signal 5 set
SP_STATUS_SIG6 = 0x2000, // Bit 13: Signal 6 set
SP_STATUS_SIG7 = 0x4000, // Bit 14: Signal 7 set
};
// MIPS interface flags
enum
{
MI_INTR_SP = 0x01, // Bit 0: SP INTR
MI_INTR_SI = 0x02, // Bit 1: SI INTR
MI_INTR_AI = 0x04, // Bit 2: AI INTR
MI_INTR_VI = 0x08, // Bit 3: VI INTR
MI_INTR_PI = 0x10, // Bit 4: PI INTR
MI_INTR_DP = 0x20, // Bit 5: DP INTR
};
class CHle
{
public:
CHle(const RSP_INFO & Rsp_Info);
~CHle();
uint8_t * dram() { return m_dram; }
uint8_t * dmem() { return m_dmem; }
uint8_t * imem() { return m_imem; }
bool AudioHle() { return m_AudioHle; }
bool GraphicsHle() { return m_GraphicsHle; }
struct alist_audio_t & alist_audio() { return m_alist_audio; }
struct alist_naudio_t & alist_naudio() { return m_alist_naudio; }
struct alist_nead_t & alist_nead() { return m_alist_nead; }
uint8_t * mp3_buffer() { return &m_mp3_buffer[0]; }
uint8_t * alist_buffer() { return &m_alist_buffer[0]; }
void VerboseMessage(const char *message, ...);
void WarnMessage(const char *message, ...);
void ErrorMessage(const char *message, ...);
void rsp_break(uint32_t setbits);
void hle_execute(void);
private:
CHle(void);
CHle(const CHle&);
CHle& operator=(const CHle&);
bool is_task(void);
bool try_fast_audio_dispatching(void);
bool try_fast_task_dispatching(void);
void normal_task_dispatching(void);
void non_task_dispatching(void);
uint8_t * m_dram;
uint8_t * m_dmem;
uint8_t * m_imem;
uint32_t* m_mi_intr;
uint32_t* m_sp_mem_addr;
uint32_t* m_sp_dram_addr;
uint32_t* m_sp_rd_length;
uint32_t* m_sp_wr_length;
uint32_t* m_sp_status;
uint32_t* m_sp_dma_full;
uint32_t* m_sp_dma_busy;
uint32_t* m_sp_pc;
uint32_t* m_sp_semaphore;
uint32_t* m_dpc_start;
uint32_t* m_dpc_end;
uint32_t* m_dpc_current;
uint32_t* m_dpc_status;
uint32_t* m_dpc_clock;
uint32_t* m_dpc_bufbusy;
uint32_t* m_dpc_pipebusy;
uint32_t* m_dpc_tmem;
void(*m_CheckInterrupts)(void);
void(*m_ProcessDList)(void);
void(*m_ProcessAList)(void);
void(*m_ProcessRdpList)(void);
void(*m_ShowCFB)(void);
// alist.cpp
uint8_t m_alist_buffer[0x1000];
// alist_audio.cpp
struct alist_audio_t m_alist_audio;
// alist_naudio.cpp
struct alist_naudio_t m_alist_naudio;
// alist_nead.cpp
struct alist_nead_t m_alist_nead;
// mp3.cpp
uint8_t m_mp3_buffer[0x1000];
bool m_AudioHle;
bool m_GraphicsHle;
bool m_ForwardAudio;
bool m_ForwardGFX;
};

View File

@ -1,7 +1,8 @@
#include "stdafx.h"
#include "Rsp.h"
CHle * g_hle = NULL;
#include <Project64-rsp-core/RSPInfo.h>
#include <Project64-rsp-core/Version.h>
#include <Settings/Settings.h>
#include <stdio.h>
#include <string.h>
#ifdef _WIN32
#include <Windows.h>
@ -17,123 +18,101 @@ BOOL WINAPI DllMain(void * hinst, DWORD /*fdwReason*/, LPVOID /*lpvReserved*/)
/*
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-initialize.
Input: None
Output: None
Input: None
Output: None
*/
void CloseDLL(void)
{
if (g_hle)
{
delete g_hle;
g_hle = NULL;
}
FreeRSP();
}
/*
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.
Input: A handle to the window that calls this function
Output: None
Input: A handle to the window that calls this function
Output: None
*/
void DllAbout(void * hParent)
{
#ifdef _WIN32
MessageBox((HWND)hParent, L"need to do", L"About", MB_OK | MB_ICONINFORMATION);
MessageBox((HWND)hParent, L"need to do", L"About", MB_OK | MB_ICONINFORMATION);
#endif
}
/*
Function: DoRspCycles
Purpose: This function is to allow the RSP to run in parallel with
the r4300 switching control back to the r4300 once the
function ends.
Input: The number of cycles that is meant to be executed
Output: The number of cycles that was executed. This value can
be greater than the number of cycles that the RSP
should have performed.
(this value is ignored if the RSP is stopped)
*/
uint32_t DoRspCycles(uint32_t Cycles)
{
if (g_hle)
{
g_hle->hle_execute();
}
return Cycles;
}
/*
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.
Input: A pointer to a PLUGIN_INFO structure that needs to be
Input: A pointer to a PLUGIN_INFO structure that needs to be
filled by the function. (see def above)
Output: None
Output: None
*/
void GetDllInfo(PLUGIN_INFO * PluginInfo)
EXPORT void GetDllInfo(PLUGIN_INFO * PluginInfo)
{
PluginInfo->Version = 0x0102;
PluginInfo->Version = 0x0103;
PluginInfo->Type = PLUGIN_TYPE_RSP;
#ifdef _DEBUG
sprintf(PluginInfo->Name, "RSP HLE debug plugin %s", VER_FILE_VERSION_STR);
sprintf(PluginInfo->Name, "RSP Basic Debug Plugin %s", VER_FILE_VERSION_STR);
#else
sprintf(PluginInfo->Name, "RSP HLE plugin %s", VER_FILE_VERSION_STR);
sprintf(PluginInfo->Name, "RSP Basic Plugin %s", VER_FILE_VERSION_STR);
#endif
PluginInfo->NormalMemory = false;
PluginInfo->MemoryBswaped = true;
PluginInfo->Reserved2 = false;
PluginInfo->Reserved1 = true;
}
/*
Function: InitiateRSP
Purpose: This function is called when the DLL is started to give
information from the emulator that the N64 RSP
interface needs
Input: Rsp_Info is passed to this function which is defined
Purpose: This function is called when the DLL is started to give
information from the emulator that the N64 RSP interface needs.
Input: Rsp_Info is passed to this function which is defined
above.
CycleCount is the number of cycles between switching
control between the RSP and r4300i core.
Output: None
Output: None
*/
void InitiateRSP(RSP_INFO Rsp_Info, uint32_t * /*CycleCount*/)
EXPORT void InitiateRSP(RSP_INFO Rsp_Info, uint32_t * CycleCount)
{
if (g_hle)
{
delete g_hle;
g_hle = NULL;
}
g_hle = new CHle(Rsp_Info);
InitilizeRSP(Rsp_Info);
*CycleCount = 0;
}
/*
Function: RomOpen
Purpose: This function is called when a ROM is opened
Input: None
Output: None
Purpose: This function is called when a ROM is opened.
Input: None
Output: None
*/
void RomOpen(void)
EXPORT void RomOpen(void)
{
RspRomOpened();
}
/*
Function: RomClosed
Purpose: This function is called when a ROM is closed
Input: None
Output: None
Purpose: This function is called when a ROM is closed.
Input: None
Output: None
*/
void RomClosed(void)
EXPORT void RomClosed(void)
{
RspRomClosed();
}
void PluginLoaded(void)
{
RspPluginLoaded();
}
void UseUnregisteredSetting(int /*SettingID*/)
{
g_Notify->BreakPoint(__FILE__, __LINE__);
}

View File

@ -1,112 +0,0 @@
// Project64 - A Nintendo 64 emulator
// https://www.pj64-emu.com/
// Copyright(C) 2001-2021 Project64
// Copyright(C) 2014 Bobby Smiles
// GNU/GPLv2 licensed: https://gnu.org/licenses/gpl-2.0.html
#pragma once
#include <assert.h>
#define S 1
#define S16 2
#define S8 3
enum
{
TASK_TYPE = 0xfc0,
TASK_FLAGS = 0xfc4,
TASK_UCODE_BOOT = 0xfc8,
TASK_UCODE_BOOT_SIZE = 0xfcc,
TASK_UCODE = 0xfd0,
TASK_UCODE_SIZE = 0xfd4,
TASK_UCODE_DATA = 0xfd8,
TASK_UCODE_DATA_SIZE = 0xfdc,
TASK_DRAM_STACK = 0xfe0,
TASK_DRAM_STACK_SIZE = 0xfe4,
TASK_OUTPUT_BUFF = 0xfe8,
TASK_OUTPUT_BUFF_SIZE = 0xfec,
TASK_DATA_PTR = 0xff0,
TASK_DATA_SIZE = 0xff4,
TASK_YIELD_DATA_PTR = 0xff8,
TASK_YIELD_DATA_SIZE = 0xffc
};
static inline unsigned int align(unsigned int x, unsigned amount)
{
--amount;
return (x + amount) & ~amount;
}
static inline uint8_t* u8(const unsigned char* buffer, unsigned address)
{
return (uint8_t*)(buffer + (address ^ S8));
}
static inline uint16_t* u16(const unsigned char* buffer, unsigned address)
{
assert((address & 1) == 0);
return (uint16_t*)(buffer + (address ^ S16));
}
static inline uint32_t* u32(const unsigned char* buffer, unsigned address)
{
assert((address & 3) == 0);
return (uint32_t*)(buffer + address);
}
void load_u8 (uint8_t* dst, const unsigned char* buffer, unsigned address, size_t count);
void load_u16(uint16_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);
void store_u16(unsigned char* buffer, unsigned address, const uint16_t* src, size_t count);
void store_u32(unsigned char* buffer, unsigned address, const uint32_t* src, size_t count);
static inline uint32_t* dmem_u32(CHle * hle, uint16_t address)
{
return u32(hle->dmem(), address & 0xfff);
}
static inline void dmem_store_u32(CHle * hle, const uint32_t* src, uint16_t address, size_t count)
{
store_u32(hle->dmem(), address & 0xfff, src, count);
}
// Convenient functions DRAM access
static inline uint8_t* dram_u8(CHle * hle, uint32_t address)
{
return u8(hle->dram(), address & 0xffffff);
}
static inline uint16_t* dram_u16(CHle * hle, uint32_t address)
{
return u16(hle->dram(), address & 0xffffff);
}
static inline uint32_t* dram_u32(CHle * hle, uint32_t address)
{
return u32(hle->dram(), address & 0xffffff);
}
static inline void dram_load_u8(CHle * hle, uint8_t* dst, uint32_t address, size_t count)
{
load_u8(dst, hle->dram(), address & 0xffffff, count);
}
static inline void dram_load_u16(CHle * hle, uint16_t* dst, uint32_t address, size_t count)
{
load_u16(dst, hle->dram(), address & 0xffffff, count);
}
static inline void dram_load_u32(CHle * hle, uint32_t* dst, uint32_t address, size_t count)
{
load_u32(dst, hle->dram(), address & 0xffffff, count);
}
static inline void dram_store_u16(CHle * hle, const uint16_t* src, uint32_t address, size_t count)
{
store_u16(hle->dram(), address & 0xffffff, src, count);
}
static inline void dram_store_u32(CHle * hle, const uint32_t* src, uint32_t address, size_t count)
{
store_u32(hle->dram(), address & 0xffffff, src, count);
}

View File

@ -0,0 +1,15 @@
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by RSP.rc
//
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 101
#define _APS_NEXT_COMMAND_VALUE 5001
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

View File

@ -1 +0,0 @@
#include "stdafx.h"

View File

@ -1,6 +0,0 @@
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "Version.h"
#include "Rsp.h"
#include "hle.h"

View File

@ -6,12 +6,15 @@
// Copyright(C) 2002 Hacktarux
// GNU/GPLv2 licensed: https://gnu.org/licenses/gpl-2.0.html
#include "stdafx.h"
#include <memory.h>
#include "alist.h"
#include "arithmetics.h"
#include "audio.h"
#include "hle.h"
#include "mem.h"
#include <memory.h>
#include <stdint.h>
aaa
struct ramp_t
{
@ -22,34 +25,34 @@ struct ramp_t
// 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;
*b = *a;
*a = tmp;
}
static int16_t* sample(CHle * hle, unsigned pos)
static int16_t * sample(CHle * hle, unsigned pos)
{
return (int16_t*)hle->alist_buffer() + (pos ^ S);
return (int16_t *)hle->alist_buffer() + (pos ^ S);
}
static uint8_t* alist_u8(CHle * hle, uint16_t dmem)
static uint8_t * alist_u8(CHle * hle, uint16_t dmem)
{
return u8(hle->alist_buffer(), dmem);
}
static int16_t* alist_s16(CHle * hle, uint16_t dmem)
static int16_t * alist_s16(CHle * hle, uint16_t dmem)
{
return (int16_t*)u16(hle->alist_buffer(), dmem);
return (int16_t *)u16(hle->alist_buffer(), dmem);
}
static void sample_mix(int16_t* dst, int16_t src, int16_t gain)
static void sample_mix(int16_t * dst, int16_t src, int16_t gain)
{
*dst = clamp_s16(*dst + ((src * gain) >> 15));
}
static void alist_envmix_mix(size_t n, int16_t** dst, const int16_t* gains, int16_t src)
static void alist_envmix_mix(size_t n, int16_t ** dst, const int16_t * gains, int16_t src)
{
size_t i;
@ -59,7 +62,7 @@ static void alist_envmix_mix(size_t n, int16_t** dst, const int16_t* gains, int1
}
}
static int16_t ramp_step(struct ramp_t* ramp)
static int16_t ramp_step(struct ramp_t * ramp)
{
bool target_reached;
@ -83,8 +86,8 @@ void alist_process(CHle * hle, const acmd_callback_t abi[], unsigned int abi_siz
uint32_t w1, w2;
unsigned int acmd;
const uint32_t *alist = dram_u32(hle, *dmem_u32(hle, TASK_DATA_PTR));
const uint32_t *const alist_end = alist + (*dmem_u32(hle, TASK_DATA_SIZE) >> 2);
const uint32_t * alist = dram_u32(hle, *dmem_u32(hle, TASK_DATA_PTR));
const uint32_t * const alist_end = alist + (*dmem_u32(hle, TASK_DATA_SIZE) >> 2);
while (alist != alist_end)
{
@ -104,9 +107,9 @@ void alist_process(CHle * hle, const acmd_callback_t abi[], unsigned int abi_siz
}
}
uint32_t alist_get_address(CHle * hle, uint32_t so, const uint32_t *segments, size_t n)
uint32_t alist_get_address(CHle * hle, uint32_t so, const uint32_t * segments, size_t n)
{
uint8_t segment = (so >> 24) & 0x3f;
uint8_t segment = (so >> 24) & 0x3f;
uint32_t offset = (so & 0xffffff);
if (segment >= n)
@ -118,9 +121,9 @@ uint32_t alist_get_address(CHle * hle, uint32_t so, const uint32_t *segments, si
return segments[segment] + offset;
}
void alist_set_address(CHle * hle, uint32_t so, uint32_t *segments, size_t n)
void alist_set_address(CHle * hle, uint32_t so, uint32_t * segments, size_t n)
{
uint8_t segment = (so >> 24) & 0x3f;
uint8_t segment = (so >> 24) & 0x3f;
uint32_t offset = (so & 0xffffff);
if (segment >= n)
@ -146,7 +149,7 @@ void alist_load(CHle * hle, uint16_t dmem, uint32_t address, uint16_t count)
// Enforce DMA alignment constraints
dmem &= ~3;
address &= ~7;
count = align(count, 8);
count = (uint16_t)align(count, 8);
memcpy(hle->alist_buffer() + dmem, hle->dram() + address, count);
}
@ -184,7 +187,7 @@ void alist_repeat64(CHle * hle, uint16_t dmemo, uint16_t dmemi, uint8_t count)
uint16_t buffer[64];
memcpy(buffer, hle->alist_buffer() + dmemi, 128);
while(count != 0)
while (count != 0)
{
memcpy(hle->alist_buffer() + dmemo, buffer, 128);
dmemo += 128;
@ -206,17 +209,17 @@ void alist_copy_blocks(CHle * hle, uint16_t dmemo, uint16_t dmemi, uint16_t bloc
dmemi += 0x20;
dmemo += 0x20;
} while(bytes_left > 0);
} while (bytes_left > 0);
--block_left;
} while(block_left > 0);
} while (block_left > 0);
}
void alist_interleave(CHle * hle, uint16_t dmemo, uint16_t left, uint16_t right, uint16_t count)
{
uint16_t *dst = (uint16_t*)(hle->alist_buffer() + dmemo);
const uint16_t *srcL = (uint16_t*)(hle->alist_buffer() + left);
const uint16_t *srcR = (uint16_t*)(hle->alist_buffer() + right);
uint16_t * dst = (uint16_t *)(hle->alist_buffer() + dmemo);
const uint16_t * srcL = (uint16_t *)(hle->alist_buffer() + left);
const uint16_t * srcR = (uint16_t *)(hle->alist_buffer() + right);
count >>= 2;
@ -242,15 +245,15 @@ void alist_interleave(CHle * hle, uint16_t dmemo, uint16_t left, uint16_t right,
}
}
void alist_envmix_exp( CHle * hle, bool init, bool aux, uint16_t dmem_dl, uint16_t dmem_dr, uint16_t dmem_wl, uint16_t dmem_wr, uint16_t dmemi, uint16_t count, int16_t dry, int16_t wet, const int16_t *vol, const int16_t *target, const int32_t *rate, uint32_t address)
void alist_envmix_exp(CHle * hle, bool init, bool aux, uint16_t dmem_dl, uint16_t dmem_dr, uint16_t dmem_wl, uint16_t dmem_wr, uint16_t dmemi, uint16_t count, int16_t dry, int16_t wet, const int16_t * vol, const int16_t * target, const int32_t * rate, uint32_t address)
{
size_t n = (aux) ? 4 : 2;
const int16_t* const in = (int16_t*)(hle->alist_buffer() + dmemi);
int16_t* const dl = (int16_t*)(hle->alist_buffer() + dmem_dl);
int16_t* const dr = (int16_t*)(hle->alist_buffer() + dmem_dr);
int16_t* const wl = (int16_t*)(hle->alist_buffer() + dmem_wl);
int16_t* const wr = (int16_t*)(hle->alist_buffer() + dmem_wr);
const int16_t * const in = (int16_t *)(hle->alist_buffer() + dmemi);
int16_t * const dl = (int16_t *)(hle->alist_buffer() + dmem_dl);
int16_t * const dr = (int16_t *)(hle->alist_buffer() + dmem_dr);
int16_t * const wl = (int16_t *)(hle->alist_buffer() + dmem_wl);
int16_t * const wr = (int16_t *)(hle->alist_buffer() + dmem_wr);
struct ramp_t ramps[2];
int32_t exp_seq[2];
@ -274,14 +277,14 @@ void alist_envmix_exp( CHle * hle, bool init, bool aux, uint16_t dmem_dl, uint16
}
else
{
wet = *(int16_t *)(save_buffer + 0); // 0-1
dry = *(int16_t *)(save_buffer + 2); // 2-3
wet = *(int16_t *)(save_buffer + 0); // 0-1
dry = *(int16_t *)(save_buffer + 2); // 2-3
ramps[0].target = *(int32_t *)(save_buffer + 4); // 4-5
ramps[1].target = *(int32_t *)(save_buffer + 6); // 6-7
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_seq[0] = *(int32_t *)(save_buffer + 12); // 12-13
exp_seq[1] = *(int32_t *)(save_buffer + 14); // 14-15
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_seq[0] = *(int32_t *)(save_buffer + 12); // 12-13
exp_seq[1] = *(int32_t *)(save_buffer + 14); // 14-15
ramps[0].value = *(int32_t *)(save_buffer + 16); // 12-13
ramps[1].value = *(int32_t *)(save_buffer + 18); // 14-15
}
@ -306,49 +309,49 @@ void alist_envmix_exp( CHle * hle, bool init, bool aux, uint16_t dmem_dl, uint16
for (x = 0; x < 8; ++x)
{
int16_t gains[4];
int16_t* buffers[4];
int16_t gains[4];
int16_t * buffers[4];
int16_t l_vol = ramp_step(&ramps[0]);
int16_t r_vol = ramp_step(&ramps[1]);
buffers[0] = dl + (ptr^S);
buffers[1] = dr + (ptr^S);
buffers[2] = wl + (ptr^S);
buffers[3] = wr + (ptr^S);
buffers[0] = dl + (ptr ^ S);
buffers[1] = dr + (ptr ^ S);
buffers[2] = wl + (ptr ^ S);
buffers[3] = wr + (ptr ^ S);
gains[0] = clamp_s16((l_vol * dry + 0x4000) >> 15);
gains[1] = clamp_s16((r_vol * dry + 0x4000) >> 15);
gains[2] = clamp_s16((l_vol * wet + 0x4000) >> 15);
gains[3] = clamp_s16((r_vol * wet + 0x4000) >> 15);
alist_envmix_mix(n, buffers, gains, in[ptr^S]);
alist_envmix_mix(n, buffers, gains, in[ptr ^ S]);
++ptr;
}
}
*(int16_t *)(save_buffer + 0) = wet; // 0-1
*(int16_t *)(save_buffer + 2) = dry; // 2-3
*(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 + 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 + 12) = exp_seq[0]; // 12-13
*(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 + 18) = (int32_t)ramps[1].value; // 14-15
*(int16_t *)(save_buffer + 0) = wet; // 0-1
*(int16_t *)(save_buffer + 2) = dry; // 2-3
*(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 + 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 + 12) = exp_seq[0]; // 12-13
*(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 + 18) = (int32_t)ramps[1].value; // 14-15
memcpy(hle->dram() + address, (uint8_t *)save_buffer, sizeof(save_buffer));
}
void alist_envmix_ge( CHle * hle, bool init, bool aux, uint16_t dmem_dl, uint16_t dmem_dr, uint16_t dmem_wl, uint16_t dmem_wr, uint16_t dmemi, uint16_t count, int16_t dry, int16_t wet, const int16_t *vol, const int16_t *target, const int32_t *rate, uint32_t address)
void alist_envmix_ge(CHle * hle, bool init, bool aux, uint16_t dmem_dl, uint16_t dmem_dr, uint16_t dmem_wl, uint16_t dmem_wr, uint16_t dmemi, uint16_t count, int16_t dry, int16_t wet, const int16_t * vol, const int16_t * target, const int32_t * rate, uint32_t address)
{
unsigned k;
size_t n = (aux) ? 4 : 2;
const int16_t* const in = (int16_t*)(hle->alist_buffer() + dmemi);
int16_t* const dl = (int16_t*)(hle->alist_buffer() + dmem_dl);
int16_t* const dr = (int16_t*)(hle->alist_buffer() + dmem_dr);
int16_t* const wl = (int16_t*)(hle->alist_buffer() + dmem_wl);
int16_t* const wr = (int16_t*)(hle->alist_buffer() + dmem_wr);
const int16_t * const in = (int16_t *)(hle->alist_buffer() + dmemi);
int16_t * const dl = (int16_t *)(hle->alist_buffer() + dmem_dl);
int16_t * const dr = (int16_t *)(hle->alist_buffer() + dmem_dr);
int16_t * const wl = (int16_t *)(hle->alist_buffer() + dmem_wl);
int16_t * const wr = (int16_t *)(hle->alist_buffer() + dmem_wr);
struct ramp_t ramps[2];
short save_buffer[40];
@ -365,122 +368,122 @@ void alist_envmix_ge( CHle * hle, bool init, bool aux, uint16_t dmem_dl, uint16_
}
else
{
wet = *(int16_t *)(save_buffer + 0); // 0-1
dry = *(int16_t *)(save_buffer + 2); // 2-3
ramps[0].target = *(int32_t *)(save_buffer + 4); // 4-5
ramps[1].target = *(int32_t *)(save_buffer + 6); // 6-7
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
wet = *(int16_t *)(save_buffer + 0); // 0-1
dry = *(int16_t *)(save_buffer + 2); // 2-3
ramps[0].target = *(int32_t *)(save_buffer + 4); // 4-5
ramps[1].target = *(int32_t *)(save_buffer + 6); // 6-7
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
/* *(int32_t *)(save_buffer + 12);*/ // 12-13
/* *(int32_t *)(save_buffer + 14);*/ // 14-15
ramps[0].value = *(int32_t *)(save_buffer + 16); // 12-13
ramps[1].value = *(int32_t *)(save_buffer + 18); // 14-15
ramps[0].value = *(int32_t *)(save_buffer + 16); // 12-13
ramps[1].value = *(int32_t *)(save_buffer + 18); // 14-15
}
count >>= 1;
for (k = 0; k < count; ++k)
{
int16_t gains[4];
int16_t* buffers[4];
int16_t gains[4];
int16_t * buffers[4];
int16_t l_vol = ramp_step(&ramps[0]);
int16_t r_vol = ramp_step(&ramps[1]);
buffers[0] = dl + (k^S);
buffers[1] = dr + (k^S);
buffers[2] = wl + (k^S);
buffers[3] = wr + (k^S);
buffers[0] = dl + (k ^ S);
buffers[1] = dr + (k ^ S);
buffers[2] = wl + (k ^ S);
buffers[3] = wr + (k ^ S);
gains[0] = clamp_s16((l_vol * dry + 0x4000) >> 15);
gains[1] = clamp_s16((r_vol * dry + 0x4000) >> 15);
gains[2] = clamp_s16((l_vol * wet + 0x4000) >> 15);
gains[3] = clamp_s16((r_vol * wet + 0x4000) >> 15);
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 + 2) = dry; // 2-3
*(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 + 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 + 12);*/ // 12-13
/**(int32_t *)(save_buffer + 14);*/ // 14-15
*(int32_t *)(save_buffer + 16) = (int32_t)ramps[0].value; // 12-13
*(int32_t *)(save_buffer + 18) = (int32_t)ramps[1].value; // 14-15
*(int16_t *)(save_buffer + 0) = wet; // 0-1
*(int16_t *)(save_buffer + 2) = dry; // 2-3
*(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 + 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 + 12);*/ // 12-13
/**(int32_t *)(save_buffer + 14);*/ // 14-15
*(int32_t *)(save_buffer + 16) = (int32_t)ramps[0].value; // 12-13
*(int32_t *)(save_buffer + 18) = (int32_t)ramps[1].value; // 14-15
memcpy(hle->dram() + address, (uint8_t *)save_buffer, 80);
}
void alist_envmix_lin(CHle * hle, bool init, uint16_t dmem_dl, uint16_t dmem_dr, uint16_t dmem_wl, uint16_t dmem_wr, uint16_t dmemi, uint16_t count, int16_t dry, int16_t wet, const int16_t *vol, const int16_t *target, const int32_t *rate, uint32_t address)
void alist_envmix_lin(CHle * hle, bool init, uint16_t dmem_dl, uint16_t dmem_dr, uint16_t dmem_wl, uint16_t dmem_wr, uint16_t dmemi, uint16_t count, int16_t dry, int16_t wet, const int16_t * vol, const int16_t * target, const int32_t * rate, uint32_t address)
{
size_t k;
struct ramp_t ramps[2];
int16_t save_buffer[40];
const int16_t * const in = (int16_t*)(hle->alist_buffer() + dmemi);
int16_t* const dl = (int16_t*)(hle->alist_buffer() + dmem_dl);
int16_t* const dr = (int16_t*)(hle->alist_buffer() + dmem_dr);
int16_t* const wl = (int16_t*)(hle->alist_buffer() + dmem_wl);
int16_t* const wr = (int16_t*)(hle->alist_buffer() + dmem_wr);
const int16_t * const in = (int16_t *)(hle->alist_buffer() + dmemi);
int16_t * const dl = (int16_t *)(hle->alist_buffer() + dmem_dl);
int16_t * const dr = (int16_t *)(hle->alist_buffer() + dmem_dr);
int16_t * const wl = (int16_t *)(hle->alist_buffer() + dmem_wl);
int16_t * const wr = (int16_t *)(hle->alist_buffer() + dmem_wr);
memcpy((uint8_t *)save_buffer, hle->dram() + address, 80);
if (init)
{
ramps[0].step = rate[0] / 8;
ramps[0].value = (vol[0] << 16);
ramps[0].step = rate[0] / 8;
ramps[0].value = (vol[0] << 16);
ramps[0].target = (target[0] << 16);
ramps[1].step = rate[1] / 8;
ramps[1].value = (vol[1] << 16);
ramps[1].step = rate[1] / 8;
ramps[1].value = (vol[1] << 16);
ramps[1].target = (target[1] << 16);
}
else
{
wet = *(int16_t *)(save_buffer + 0); // 0-1
dry = *(int16_t *)(save_buffer + 2); // 2-3
ramps[0].target = *(int16_t *)(save_buffer + 4) << 16; // 4-5
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 16-bit pointer)
ramps[1].step = *(int32_t *)(save_buffer + 10); // 10-11
ramps[0].value = *(int32_t *)(save_buffer + 16); // 16-17
ramps[1].value = *(int32_t *)(save_buffer + 18); // 16-17
wet = *(int16_t *)(save_buffer + 0); // 0-1
dry = *(int16_t *)(save_buffer + 2); // 2-3
ramps[0].target = *(int16_t *)(save_buffer + 4) << 16; // 4-5
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 16-bit pointer)
ramps[1].step = *(int32_t *)(save_buffer + 10); // 10-11
ramps[0].value = *(int32_t *)(save_buffer + 16); // 16-17
ramps[1].value = *(int32_t *)(save_buffer + 18); // 16-17
}
count >>= 1;
for(k = 0; k < count; ++k)
for (k = 0; k < count; ++k)
{
int16_t gains[4];
int16_t* buffers[4];
int16_t gains[4];
int16_t * buffers[4];
int16_t l_vol = ramp_step(&ramps[0]);
int16_t r_vol = ramp_step(&ramps[1]);
buffers[0] = dl + (k^S);
buffers[1] = dr + (k^S);
buffers[2] = wl + (k^S);
buffers[3] = wr + (k^S);
buffers[0] = dl + (k ^ S);
buffers[1] = dr + (k ^ S);
buffers[2] = wl + (k ^ S);
buffers[3] = wr + (k ^ S);
gains[0] = clamp_s16((l_vol * dry + 0x4000) >> 15);
gains[1] = clamp_s16((r_vol * dry + 0x4000) >> 15);
gains[2] = clamp_s16((l_vol * wet + 0x4000) >> 15);
gains[3] = clamp_s16((r_vol * wet + 0x4000) >> 15);
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 + 2) = dry; // 2-3
*(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
*(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 + 16) = (int32_t)ramps[0].value; // 16-17
*(int32_t *)(save_buffer + 18) = (int32_t)ramps[1].value; // 18-19
*(int16_t *)(save_buffer + 0) = wet; // 0-1
*(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 + 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 16-bit pointer)
*(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 + 18) = (int32_t)ramps[1].value; // 18-19
memcpy(hle->dram() + address, (uint8_t *)save_buffer, 80);
}
void alist_mix(CHle * hle, uint16_t dmemo, uint16_t dmemi, uint16_t count, int16_t gain)
{
int16_t *dst = (int16_t*)(hle->alist_buffer() + dmemo);
const int16_t *src = (int16_t*)(hle->alist_buffer() + dmemi);
int16_t * dst = (int16_t *)(hle->alist_buffer() + dmemo);
const int16_t * src = (int16_t *)(hle->alist_buffer() + dmemi);
count >>= 1;
@ -494,13 +497,13 @@ void alist_mix(CHle * hle, uint16_t dmemo, uint16_t dmemi, uint16_t count, int16
}
}
void alist_envmix_nead( CHle * hle, bool swap_wet_LR, uint16_t dmem_dl, uint16_t dmem_dr, uint16_t dmem_wl, uint16_t dmem_wr, uint16_t dmemi, unsigned count, uint16_t *env_values, uint16_t *env_steps, const int16_t *xors)
void alist_envmix_nead(CHle * hle, bool swap_wet_LR, uint16_t dmem_dl, uint16_t dmem_dr, uint16_t dmem_wl, uint16_t dmem_wr, uint16_t dmemi, unsigned count, uint16_t * env_values, uint16_t * env_steps, const int16_t * xors)
{
int16_t *in = (int16_t*)(hle->alist_buffer() + dmemi);
int16_t *dl = (int16_t*)(hle->alist_buffer() + dmem_dl);
int16_t *dr = (int16_t*)(hle->alist_buffer() + dmem_dr);
int16_t *wl = (int16_t*)(hle->alist_buffer() + dmem_wl);
int16_t *wr = (int16_t*)(hle->alist_buffer() + dmem_wr);
int16_t * in = (int16_t *)(hle->alist_buffer() + dmemi);
int16_t * dl = (int16_t *)(hle->alist_buffer() + dmem_dl);
int16_t * dr = (int16_t *)(hle->alist_buffer() + dmem_dr);
int16_t * wl = (int16_t *)(hle->alist_buffer() + dmem_wl);
int16_t * wr = (int16_t *)(hle->alist_buffer() + dmem_wr);
// Make sure count is a multiple of 8
count = align(count, 8);
@ -513,17 +516,17 @@ void alist_envmix_nead( CHle * hle, bool swap_wet_LR, uint16_t dmem_dl, uint16_t
while (count != 0)
{
size_t i;
for(i = 0; i < 8; ++i)
for (i = 0; i < 8; ++i)
{
int16_t l = (((int32_t)in[i^S] * (uint32_t)env_values[0]) >> 16) ^ xors[0];
int16_t r = (((int32_t)in[i^S] * (uint32_t)env_values[1]) >> 16) ^ xors[1];
int16_t l = (((int32_t)in[i ^ S] * (uint32_t)env_values[0]) >> 16) ^ xors[0];
int16_t r = (((int32_t)in[i ^ S] * (uint32_t)env_values[1]) >> 16) ^ xors[1];
int16_t l2 = (((int32_t)l * (uint32_t)env_values[2]) >> 16) ^ xors[2];
int16_t r2 = (((int32_t)r * (uint32_t)env_values[2]) >> 16) ^ xors[3];
dl[i^S] = clamp_s16(dl[i^S] + l);
dr[i^S] = clamp_s16(dr[i^S] + r);
wl[i^S] = clamp_s16(wl[i^S] + l2);
wr[i^S] = clamp_s16(wr[i^S] + r2);
dl[i ^ S] = clamp_s16(dl[i ^ S] + l);
dr[i ^ S] = clamp_s16(dr[i ^ S] + r);
wl[i ^ S] = clamp_s16(wl[i ^ S] + l2);
wr[i ^ S] = clamp_s16(wr[i ^ S] + r2);
}
env_values[0] += env_steps[0];
@ -541,12 +544,12 @@ void alist_envmix_nead( CHle * hle, bool swap_wet_LR, uint16_t dmem_dl, uint16_t
void alist_add(CHle * hle, uint16_t dmemo, uint16_t dmemi, uint16_t count)
{
int16_t *dst = (int16_t*)(hle->alist_buffer() + dmemo);
const int16_t *src = (int16_t*)(hle->alist_buffer() + dmemi);
int16_t * dst = (int16_t *)(hle->alist_buffer() + dmemo);
const int16_t * src = (int16_t *)(hle->alist_buffer() + dmemi);
count >>= 1;
while(count != 0)
while (count != 0)
{
*dst = clamp_s16(*dst + *src);
@ -558,11 +561,11 @@ void alist_add(CHle * hle, uint16_t dmemo, uint16_t dmemi, uint16_t count)
void alist_multQ44(CHle * hle, uint16_t dmem, uint16_t count, int8_t gain)
{
int16_t *dst = (int16_t*)(hle->alist_buffer() + dmem);
int16_t * dst = (int16_t *)(hle->alist_buffer() + dmem);
count >>= 1;
while(count != 0)
while (count != 0)
{
*dst = clamp_s16(*dst * gain >> 4);
@ -571,7 +574,7 @@ void alist_multQ44(CHle * hle, uint16_t dmem, uint16_t count, int8_t gain)
}
}
static void alist_resample_reset(CHle * hle, uint16_t pos, uint32_t* pitch_accu)
static void alist_resample_reset(CHle * hle, uint16_t pos, uint32_t * pitch_accu)
{
unsigned k;
@ -582,7 +585,7 @@ static void alist_resample_reset(CHle * hle, uint16_t pos, uint32_t* pitch_accu)
*pitch_accu = 0;
}
static void alist_resample_load(CHle * hle, uint32_t address, uint16_t pos, uint32_t* pitch_accu)
static void alist_resample_load(CHle * hle, uint32_t address, uint16_t pos, uint32_t * pitch_accu)
{
*sample(hle, pos + 0) = *dram_u16(hle, address + 0);
*sample(hle, pos + 1) = *dram_u16(hle, address + 2);
@ -602,7 +605,7 @@ static void alist_resample_save(CHle * hle, uint32_t address, uint16_t pos, uint
*dram_u16(hle, address + 8) = pitch_accu;
}
void alist_resample( CHle * hle, bool init, bool flag2, uint16_t dmemo, uint16_t dmemi, uint16_t count, uint32_t pitch /* Q16.16 */, uint32_t address)
void alist_resample(CHle * hle, bool init, bool flag2, uint16_t dmemo, uint16_t dmemi, uint16_t count, uint32_t pitch /* Q16.16 */, uint32_t address)
{
uint32_t pitch_accu;
@ -627,13 +630,14 @@ void alist_resample( CHle * hle, bool init, bool flag2, uint16_t dmemo, uint16_t
while (count != 0)
{
const int16_t* lut = RESAMPLE_LUT + ((pitch_accu & 0xfc00) >> 8);
const int16_t * lut = RESAMPLE_LUT + ((pitch_accu & 0xfc00) >> 8);
*sample(hle, opos++) = clamp_s16( (
(*sample(hle, ipos ) * lut[0]) +
(*sample(hle, ipos + 1) * lut[1]) +
(*sample(hle, ipos + 2) * lut[2]) +
(*sample(hle, ipos + 3) * lut[3]) ) >> 15);
*sample(hle, opos++) = clamp_s16((
(*sample(hle, ipos) * lut[0]) +
(*sample(hle, ipos + 1) * lut[1]) +
(*sample(hle, ipos + 2) * lut[2]) +
(*sample(hle, ipos + 3) * lut[3])) >>
15);
pitch_accu += pitch;
ipos += (pitch_accu >> 16);
@ -650,7 +654,7 @@ void alist_resample_zoh(CHle * hle, uint16_t dmemo, uint16_t dmemi, uint16_t cou
uint16_t opos = dmemo >> 1;
count >>= 1;
while(count != 0)
while (count != 0)
{
*sample(hle, opos++) = *sample(hle, ipos);
@ -661,9 +665,9 @@ void alist_resample_zoh(CHle * hle, uint16_t dmemo, uint16_t dmemi, uint16_t cou
}
}
typedef unsigned int(*adpcm_predict_frame_t)(CHle * hle, int16_t* dst, uint16_t dmemi, unsigned char scale);
typedef unsigned int (*adpcm_predict_frame_t)(CHle * hle, int16_t * dst, uint16_t dmemi, unsigned char scale);
static unsigned int adpcm_predict_frame_4bits(CHle * hle, int16_t* dst, uint16_t dmemi, unsigned char scale)
static unsigned int adpcm_predict_frame_4bits(CHle * hle, int16_t * dst, uint16_t dmemi, unsigned char scale)
{
unsigned int i;
unsigned int rshift = (scale < 12) ? 12 - scale : 0;
@ -679,7 +683,7 @@ static unsigned int adpcm_predict_frame_4bits(CHle * hle, int16_t* dst, uint16_t
return 8;
}
static unsigned int adpcm_predict_frame_2bits(CHle * hle, int16_t* dst, uint16_t dmemi, unsigned char scale)
static unsigned int adpcm_predict_frame_2bits(CHle * hle, int16_t * dst, uint16_t dmemi, unsigned char scale)
{
unsigned int i;
unsigned int rshift = (scale < 14) ? 14 - scale : 0;
@ -697,14 +701,14 @@ static unsigned int adpcm_predict_frame_2bits(CHle * hle, int16_t* dst, uint16_t
return 4;
}
void alist_adpcm( CHle * hle, bool init, bool loop, bool two_bit_per_sample, uint16_t dmemo, uint16_t dmemi, uint16_t count, const int16_t* codebook, uint32_t loop_address, uint32_t last_frame_address)
void alist_adpcm(CHle * hle, bool init, bool loop, bool two_bit_per_sample, uint16_t dmemo, uint16_t dmemi, uint16_t count, const int16_t * codebook, uint32_t loop_address, uint32_t last_frame_address)
{
int16_t last_frame[16];
size_t i;
adpcm_predict_frame_t predict_frame = (two_bit_per_sample)
? adpcm_predict_frame_2bits
: adpcm_predict_frame_4bits;
? adpcm_predict_frame_2bits
: adpcm_predict_frame_4bits;
assert((count & 0x1f) == 0);
@ -714,7 +718,7 @@ void alist_adpcm( CHle * hle, bool init, bool loop, bool two_bit_per_sample, uin
}
else
{
dram_load_u16(hle, (uint16_t*)last_frame, (loop) ? loop_address : last_frame_address, 16);
dram_load_u16(hle, (uint16_t *)last_frame, (loop) ? loop_address : last_frame_address, 16);
}
for (i = 0; i < 16; ++i, dmemo += 2)
@ -726,7 +730,7 @@ void alist_adpcm( CHle * hle, bool init, bool loop, bool two_bit_per_sample, uin
int16_t frame[16];
uint8_t code = *alist_u8(hle, dmemi++);
unsigned char scale = (code & 0xf0) >> 4;
const int16_t* const cb_entry = codebook + ((code & 0xf) << 4);
const int16_t * const cb_entry = codebook + ((code & 0xf) << 4);
dmemi += predict_frame(hle, frame, dmemi, scale);
@ -740,20 +744,20 @@ void alist_adpcm( CHle * hle, bool init, bool loop, bool two_bit_per_sample, uin
count -= 32;
}
dram_store_u16(hle, (uint16_t*)last_frame, last_frame_address, 16);
dram_store_u16(hle, (uint16_t *)last_frame, last_frame_address, 16);
}
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)
{
int x;
int16_t outbuff[0x3c0];
int16_t *outp = outbuff;
int16_t * outp = outbuff;
int16_t* const lutt6 = (int16_t*)(hle->dram() + lut_address[0]);
int16_t* const lutt5 = (int16_t*)(hle->dram() + lut_address[1]);
int16_t * const lutt6 = (int16_t *)(hle->dram() + lut_address[0]);
int16_t * const lutt5 = (int16_t *)(hle->dram() + lut_address[1]);
int16_t* in1 = (int16_t*)(hle->dram() + address);
int16_t* in2 = (int16_t*)(hle->alist_buffer() + dmem);
int16_t * in1 = (int16_t *)(hle->dram() + address);
int16_t * in2 = (int16_t *)(hle->alist_buffer() + dmem);
for (x = 0; x < 8; ++x)
{
@ -765,7 +769,7 @@ void alist_filter( CHle * hle, uint16_t dmem,uint16_t count, uint32_t address, c
{
int32_t v[8];
v[1] = in1[0] * lutt6[6];
v[1] = in1[0] * lutt6[6];
v[1] += in1[3] * lutt6[7];
v[1] += in1[2] * lutt6[4];
v[1] += in1[5] * lutt6[5];
@ -774,7 +778,7 @@ void alist_filter( CHle * hle, uint16_t dmem,uint16_t count, uint32_t address, c
v[1] += in1[6] * lutt6[0];
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[5] * lutt6[4];
v[0] += in1[4] * lutt6[5];
@ -783,7 +787,7 @@ void alist_filter( CHle * hle, uint16_t dmem,uint16_t count, uint32_t address, c
v[0] += in2[1] * lutt6[0];
v[0] += in2[0] * lutt6[1];
v[3] = in1[2] * lutt6[6];
v[3] = in1[2] * lutt6[6];
v[3] += in1[5] * lutt6[7];
v[3] += in1[4] * lutt6[4];
v[3] += in1[7] * lutt6[5];
@ -792,7 +796,7 @@ void alist_filter( CHle * hle, uint16_t dmem,uint16_t count, uint32_t address, c
v[3] += in2[0] * lutt6[0];
v[3] += in2[3] * lutt6[1];
v[2] = in1[5] * lutt6[6];
v[2] = in1[5] * lutt6[6];
v[2] += in1[4] * lutt6[7];
v[2] += in1[7] * lutt6[4];
v[2] += in1[6] * lutt6[5];
@ -801,7 +805,7 @@ void alist_filter( CHle * hle, uint16_t dmem,uint16_t count, uint32_t address, c
v[2] += in2[3] * lutt6[0];
v[2] += in2[2] * lutt6[1];
v[5] = in1[4] * lutt6[6];
v[5] = in1[4] * lutt6[6];
v[5] += in1[7] * lutt6[7];
v[5] += in1[6] * lutt6[4];
v[5] += in2[1] * lutt6[5];
@ -810,7 +814,7 @@ void alist_filter( CHle * hle, uint16_t dmem,uint16_t count, uint32_t address, c
v[5] += in2[2] * lutt6[0];
v[5] += in2[5] * lutt6[1];
v[4] = in1[7] * lutt6[6];
v[4] = in1[7] * lutt6[6];
v[4] += in1[6] * lutt6[7];
v[4] += in2[1] * lutt6[4];
v[4] += in2[0] * lutt6[5];
@ -819,7 +823,7 @@ void alist_filter( CHle * hle, uint16_t dmem,uint16_t count, uint32_t address, c
v[4] += in2[5] * lutt6[0];
v[4] += in2[4] * lutt6[1];
v[7] = in1[6] * lutt6[6];
v[7] = in1[6] * lutt6[6];
v[7] += in2[1] * lutt6[7];
v[7] += in2[0] * lutt6[4];
v[7] += in2[3] * lutt6[5];
@ -828,7 +832,7 @@ void alist_filter( CHle * hle, uint16_t dmem,uint16_t count, uint32_t address, c
v[7] += in2[4] * lutt6[0];
v[7] += in2[7] * lutt6[1];
v[6] = in2[1] * lutt6[6];
v[6] = in2[1] * lutt6[6];
v[6] += in2[0] * lutt6[7];
v[6] += in2[3] * lutt6[4];
v[6] += in2[2] * lutt6[5];
@ -854,12 +858,12 @@ void alist_filter( CHle * hle, uint16_t dmem,uint16_t count, uint32_t address, c
memcpy(hle->alist_buffer() + dmem, outbuff, count);
}
void alist_polef(CHle * hle, bool init, uint16_t dmemo, uint16_t dmemi, uint16_t count, uint16_t gain, int16_t* table, uint32_t address)
void alist_polef(CHle * hle, bool init, uint16_t dmemo, uint16_t dmemi, uint16_t count, uint16_t gain, int16_t * table, uint32_t address)
{
int16_t *dst = (int16_t*)(hle->alist_buffer() + dmemo);
int16_t * dst = (int16_t *)(hle->alist_buffer() + dmemo);
const int16_t* const h1 = table;
int16_t* const h2 = table + 8;
const int16_t * const h1 = table;
int16_t * const h2 = table + 8;
unsigned i;
int16_t l1, l2;
@ -897,7 +901,7 @@ void alist_polef(CHle * hle, bool init, uint16_t dmemo, uint16_t dmemi, uint16_t
{
int32_t accu = frame[i] * gain;
accu += h1[i] * l1 + h2_before[i] * l2 + rdot(i, h2, frame);
dst[i^S] = clamp_s16(accu >> 14);
dst[i ^ S] = clamp_s16(accu >> 14);
}
l1 = dst[6 ^ S];
@ -907,12 +911,12 @@ void alist_polef(CHle * hle, bool init, uint16_t dmemo, uint16_t dmemi, uint16_t
count -= 16;
} while (count != 0);
dram_store_u32(hle, (uint32_t*)(dst - 4), address, 2);
dram_store_u32(hle, (uint32_t *)(dst - 4), address, 2);
}
void alist_iirf(CHle * hle, bool init, uint16_t dmemo, uint16_t dmemi, uint16_t count, int16_t* table, uint32_t address)
void alist_iirf(CHle * hle, bool init, uint16_t dmemo, uint16_t dmemi, uint16_t count, int16_t * table, uint32_t address)
{
int16_t *dst = (int16_t*)(hle->alist_buffer() + dmemo);
int16_t * dst = (int16_t *)(hle->alist_buffer() + dmemo);
int32_t i, prev;
int16_t frame[8];
int16_t ibuf[4];
@ -920,9 +924,9 @@ void alist_iirf(CHle * hle, bool init, uint16_t dmemo, uint16_t dmemi, uint16_t
count = align(count, 16);
if(init)
if (init)
{
for(i = 0; i < 8; ++i)
for (i = 0; i < 8; ++i)
{
frame[i] = 0;
}
@ -940,24 +944,24 @@ void alist_iirf(CHle * hle, bool init, uint16_t dmemo, uint16_t dmemi, uint16_t
prev = vmulf(table[9], frame[6]) * 2;
do
{
for(i = 0; i < 8; ++i)
for (i = 0; i < 8; ++i)
{
int32_t accu;
ibuf[index&3] = *alist_s16(hle, dmemi);
ibuf[index & 3] = *alist_s16(hle, dmemi);
accu = prev + vmulf(table[0], ibuf[index&3]) + vmulf(table[1], ibuf[(index-1)&3]) + vmulf(table[0], ibuf[(index-2)&3]);
accu = prev + vmulf(table[0], ibuf[index & 3]) + vmulf(table[1], ibuf[(index - 1) & 3]) + vmulf(table[0], ibuf[(index - 2) & 3]);
accu += vmulf(table[8], frame[index]) * 2;
prev = vmulf(table[9], frame[index]) * 2;
dst[i^S] = frame[i] = accu;
dst[i ^ S] = frame[i] = accu;
index=(index+1)&7;
index = (index + 1) & 7;
dmemi += 2;
}
dst += 8;
count -= 0x10;
} while (count > 0);
dram_store_u16(hle, (uint16_t*)&frame[6], address + 4, 4);
dram_store_u16(hle, (uint16_t*)&ibuf[(index-2)&3], address+8, 2);
dram_store_u16(hle, (uint16_t*)&ibuf[(index-1)&3], address+10, 2);
dram_store_u16(hle, (uint16_t *)&frame[6], address + 4, 4);
dram_store_u16(hle, (uint16_t *)&ibuf[(index - 2) & 3], address + 8, 2);
dram_store_u16(hle, (uint16_t *)&ibuf[(index - 1) & 3], address + 10, 2);
}

View File

@ -0,0 +1,52 @@
// Project64 - A Nintendo 64 emulator
// https://www.pj64-emu.com/
// Copyright(C) 2001-2021 Project64
// Copyright(C) 2014 Bobby Smiles
// GNU/GPLv2 licensed: https://gnu.org/licenses/gpl-2.0.html
#pragma once
#include <stdint.h>
class CHle;
typedef void (*acmd_callback_t)(CHle * hle, uint32_t w1, uint32_t w2);
void alist_process(CHle * hle, const acmd_callback_t abi[], unsigned int abi_size);
uint32_t alist_get_address(CHle * hle, uint32_t so, const uint32_t * segments, size_t n);
void alist_set_address(CHle * hle, uint32_t so, uint32_t * segments, size_t n);
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_save(CHle * hle, uint16_t dmem, uint32_t address, uint16_t count);
void alist_move(CHle * hle, uint16_t dmemo, uint16_t dmemi, uint16_t count);
void alist_copy_every_other_sample(CHle * hle, uint16_t dmemo, uint16_t dmemi, uint16_t count);
void alist_repeat64(CHle * hle, uint16_t dmemo, uint16_t dmemi, uint8_t count);
void alist_copy_blocks(CHle * hle, uint16_t dmemo, uint16_t dmemi, uint16_t block_size, uint8_t count);
void alist_interleave(CHle * hle, uint16_t dmemo, uint16_t left, uint16_t right, uint16_t count);
void alist_envmix_exp(CHle * hle, bool init, bool aux, uint16_t dmem_dl, uint16_t dmem_dr, uint16_t dmem_wl, uint16_t dmem_wr, uint16_t dmemi, uint16_t count, int16_t dry, int16_t wet, const int16_t * vol, const int16_t * target, const int32_t * rate, uint32_t address);
void alist_envmix_ge(CHle * hle, bool init, bool aux, uint16_t dmem_dl, uint16_t dmem_dr, uint16_t dmem_wl, uint16_t dmem_wr, uint16_t dmemi, uint16_t count, int16_t dry, int16_t wet, const int16_t * vol, const int16_t * target, const int32_t * rate, uint32_t address);
void alist_envmix_lin(CHle * hle, bool init, uint16_t dmem_dl, uint16_t dmem_dr, uint16_t dmem_wl, uint16_t dmem_wr, uint16_t dmemi, uint16_t count, int16_t dry, int16_t wet, const int16_t * vol, const int16_t * target, const int32_t * rate, uint32_t address);
void alist_envmix_nead(CHle * hle, bool swap_wet_LR, uint16_t dmem_dl, uint16_t dmem_dr, uint16_t dmem_wl, uint16_t dmem_wr, uint16_t dmemi, unsigned count, uint16_t * env_values, uint16_t * env_steps, const int16_t * xors);
void alist_mix(CHle * hle, uint16_t dmemo, uint16_t dmemi, uint16_t count, int16_t gain);
void alist_multQ44(CHle * hle, uint16_t dmem, uint16_t count, int8_t gain);
void alist_add(CHle * hle, uint16_t dmemo, uint16_t dmemi, uint16_t count);
void alist_adpcm(CHle * hle, bool init, bool loop, bool two_bit_per_sample, uint16_t dmemo, uint16_t dmemi, uint16_t count, const int16_t * codebook, uint32_t loop_address, uint32_t last_frame_address);
void alist_resample(CHle * hle, bool init, bool flag2, uint16_t dmemo, uint16_t dmemi, uint16_t count, uint32_t pitch, uint32_t address);
void alist_polef(CHle * hle, bool init, uint16_t dmemo, uint16_t dmemi, uint16_t count, uint16_t gain, int16_t * table, uint32_t address);
void alist_iirf(CHle * hle, bool init, uint16_t dmemo, uint16_t dmemi, uint16_t count, int16_t * table, uint32_t address);
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);
// Audio flags
#define A_INIT 0x01
#define A_CONTINUE 0x00
#define A_LOOP 0x02
#define A_OUT 0x02
#define A_LEFT 0x02
#define A_RIGHT 0x00
#define A_VOL 0x04
#define A_RATE 0x00
#define A_AUX 0x08
#define A_NOAUX 0x00
#define A_MAIN 0x00
#define A_MIX 0x10

View File

@ -6,16 +6,18 @@
// Copyright(C) 2002 Hacktarux
// GNU/GPLv2 licensed: https://gnu.org/licenses/gpl-2.0.html
#include "stdafx.h"
#include <stdint.h>
#include <string.h>
#include "alist.h"
#include "common.h"
#include "hle.h"
#include "mem.h"
#include "ucodes.h"
enum { DMEM_BASE = 0x5c0 };
enum
{
DMEM_BASE = 0x5c0
};
// Helper functions
@ -31,7 +33,7 @@ static void set_address(CHle * hle, uint32_t so)
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
@ -53,7 +55,7 @@ static void CLEARBUFF(CHle * hle, uint32_t w1, uint32_t w2)
static void ENVMIXER(CHle * hle, uint32_t w1, uint32_t w2)
{
uint8_t flags = (w1 >> 16) & 0xFF;
uint8_t flags = (w1 >> 16) & 0xFF;
uint32_t address = get_address(hle, w2);
alist_envmix_exp(
@ -72,7 +74,7 @@ static void ENVMIXER(CHle * hle, uint32_t w1, uint32_t w2)
static void ENVMIXER_GE(CHle * hle, uint32_t w1, uint32_t w2)
{
uint8_t flags = (w1 >> 16);
uint8_t flags = (w1 >> 16);
uint32_t address = get_address(hle, w2);
alist_envmix_ge(
@ -91,7 +93,7 @@ static void ENVMIXER_GE(CHle * hle, uint32_t w1, uint32_t w2)
static void RESAMPLE(CHle * hle, uint32_t w1, uint32_t w2)
{
uint8_t flags = (w1 >> 16) & 0xFF;
uint8_t flags = (w1 >> 16) & 0xFF;
uint16_t pitch = w1 & 0xFFFF;
uint32_t address = get_address(hle, w2);
@ -138,14 +140,14 @@ static void SETLOOP(CHle * hle, uint32_t UNUSED(w1), uint32_t w2)
static void ADPCM(CHle * hle, uint32_t w1, uint32_t w2)
{
uint8_t flags = (w1 >> 16) & 0xFF;
uint8_t flags = (w1 >> 16) & 0xFF;
uint32_t address = get_address(hle, w2);
alist_adpcm(
hle,
flags & 0x1,
flags & 0x2,
false, // Unsupported in this microcode
false, // Unsupported in this microcode
hle->alist_audio().out,
hle->alist_audio().in,
align(hle->alist_audio().count, 32),
@ -199,7 +201,7 @@ static void DMEMMOVE(CHle * hle, uint32_t w1, uint32_t w2)
{
uint16_t dmemi = (w1 + DMEM_BASE) & 0xFFFF;
uint16_t dmemo = (w2 >> 16) + DMEM_BASE;
uint16_t count = (w2)& 0xFFFF;
uint16_t count = (w2)&0xFFFF;
if (count == 0)
return;
@ -212,7 +214,7 @@ static void LOADADPCM(CHle * hle, uint32_t w1, uint32_t w2)
uint16_t count = (w1 & 0xFFFF);
uint32_t address = get_address(hle, w2);
dram_load_u16(hle, (uint16_t*)hle->alist_audio().table, address, align(count, 8) >> 1);
dram_load_u16(hle, (uint16_t *)hle->alist_audio().table, address, align(count, 8) >> 1);
}
static void INTERLEAVE(CHle * hle, uint32_t UNUSED(w1), uint32_t w2)
@ -228,7 +230,7 @@ static void INTERLEAVE(CHle * hle, uint32_t UNUSED(w1), uint32_t w2)
static void MIXER(CHle * hle, uint32_t w1, uint32_t w2)
{
int16_t gain = (w1)& 0xFFFF;
int16_t gain = (w1)&0xFFFF;
uint16_t dmemi = ((w2 >> 16) + DMEM_BASE) & 0xFFFF;
uint16_t dmemo = (w2 + DMEM_BASE) & 0xFFFF;
@ -245,7 +247,7 @@ static void SEGMENT(CHle * hle, uint32_t UNUSED(w1), uint32_t w2)
static void POLEF(CHle * hle, uint32_t w1, uint32_t w2)
{
uint8_t flags = (w1 >> 16);
uint8_t flags = (w1 >> 16);
uint16_t gain = w1;
uint32_t address = get_address(hle, w2);
@ -271,8 +273,7 @@ void alist_process_audio(CHle * hle)
SPNOOP, ADPCM, CLEARBUFF, ENVMIXER,
LOADBUFF, RESAMPLE, SAVEBUFF, SEGMENT,
SETBUFF, SETVOL, DMEMMOVE, LOADADPCM,
MIXER, INTERLEAVE, POLEF, SETLOOP
};
MIXER, INTERLEAVE, POLEF, SETLOOP};
clear_segments(hle);
alist_process(hle, ABI, 0x10);
@ -281,12 +282,11 @@ void alist_process_audio(CHle * hle)
void alist_process_audio_ge(CHle * hle)
{
static const acmd_callback_t ABI[0x10] =
{
SPNOOP, ADPCM, CLEARBUFF, ENVMIXER_GE,
LOADBUFF, RESAMPLE, SAVEBUFF, SEGMENT,
SETBUFF, SETVOL, DMEMMOVE, LOADADPCM,
MIXER, INTERLEAVE, POLEF, SETLOOP
};
{
SPNOOP, ADPCM, CLEARBUFF, ENVMIXER_GE,
LOADBUFF, RESAMPLE, SAVEBUFF, SEGMENT,
SETBUFF, SETVOL, DMEMMOVE, LOADADPCM,
MIXER, INTERLEAVE, POLEF, SETLOOP};
clear_segments(hle);
alist_process(hle, ABI, 0x10);
@ -295,12 +295,11 @@ void alist_process_audio_ge(CHle * hle)
void alist_process_audio_bc(CHle * hle)
{
static const acmd_callback_t ABI[0x10] =
{
SPNOOP, ADPCM, CLEARBUFF, ENVMIXER_GE,
LOADBUFF, RESAMPLE, SAVEBUFF, SEGMENT,
SETBUFF, SETVOL, DMEMMOVE, LOADADPCM,
MIXER, INTERLEAVE, POLEF, SETLOOP
};
{
SPNOOP, ADPCM, CLEARBUFF, ENVMIXER_GE,
LOADBUFF, RESAMPLE, SAVEBUFF, SEGMENT,
SETBUFF, SETVOL, DMEMMOVE, LOADADPCM,
MIXER, INTERLEAVE, POLEF, SETLOOP};
clear_segments(hle);
alist_process(hle, ABI, 0x10);

View File

@ -6,13 +6,17 @@
// Copyright(C) 2002 Hacktarux
// GNU/GPLv2 licensed: https://gnu.org/licenses/gpl-2.0.html
#include "stdafx.h"
#include <stdint.h>
#include "alist.h"
#include "mem.h"
enum { NAUDIO_COUNT = 0x170 }; // i.e. 184 samples
enum {
enum
{
NAUDIO_COUNT = 0x170
}; // i.e. 184 samples
enum
{
NAUDIO_MAIN = 0x4f0,
NAUDIO_MAIN2 = 0x660,
NAUDIO_DRY_LEFT = 0x9d0,
@ -49,10 +53,10 @@ static void NAUDIO_02B0(CHle * hle, uint32_t UNUSED(w1), uint32_t w2)
static void NAUDIO_14(CHle * hle, uint32_t w1, uint32_t w2)
{
uint8_t flags = (w1 >> 16);
uint16_t gain = w1;
uint8_t select_main = (w2 >> 24);
uint32_t address = (w2 & 0xffffff);
uint8_t flags = (w1 >> 16);
uint16_t gain = w1;
uint8_t select_main = (w2 >> 24);
uint32_t address = (w2 & 0xffffff);
uint16_t dmem = (select_main == 0) ? NAUDIO_MAIN : NAUDIO_MAIN2;
@ -62,7 +66,7 @@ static void NAUDIO_14(CHle * hle, uint32_t w1, uint32_t w2)
}
else
{
alist_iirf( hle, flags & A_INIT, dmem, dmem, NAUDIO_COUNT, hle->alist_naudio().table, address);
alist_iirf(hle, flags & A_INIT, dmem, dmem, NAUDIO_COUNT, hle->alist_naudio().table, address);
}
}
@ -70,13 +74,16 @@ static void SETVOL(CHle * hle, uint32_t w1, uint32_t w2)
{
uint8_t flags = (w1 >> 16);
if (flags & 0x4) {
if (flags & 0x2) {
if (flags & 0x4)
{
if (flags & 0x2)
{
hle->alist_naudio().vol[0] = w1;
hle->alist_naudio().dry = (w2 >> 16);
hle->alist_naudio().wet = w2;
}
else {
else
{
hle->alist_naudio().target[1] = w1;
hle->alist_naudio().rate[1] = w2;
}
@ -90,7 +97,7 @@ static void SETVOL(CHle * hle, uint32_t w1, uint32_t w2)
static void ENVMIXER(CHle * hle, uint32_t w1, uint32_t w2)
{
uint8_t flags = (w1 >> 16);
uint8_t flags = (w1 >> 16);
uint32_t address = (w2 & 0xffffff);
hle->alist_naudio().vol[1] = w1;
@ -122,7 +129,7 @@ static void CLEARBUFF(CHle * hle, uint32_t w1, uint32_t w2)
static void MIXER(CHle * hle, uint32_t w1, uint32_t w2)
{
int16_t gain = w1;
int16_t gain = w1;
uint16_t dmemi = (w2 >> 16) + NAUDIO_MAIN;
uint16_t dmemo = w2 + NAUDIO_MAIN;
@ -152,7 +159,7 @@ static void LOADADPCM(CHle * hle, uint32_t w1, uint32_t w2)
uint16_t count = w1;
uint32_t address = (w2 & 0xffffff);
dram_load_u16(hle, (uint16_t*)hle->alist_naudio().table, address, count >> 1);
dram_load_u16(hle, (uint16_t *)hle->alist_naudio().table, address, count >> 1);
}
static void DMEMMOVE(CHle * hle, uint32_t w1, uint32_t w2)
@ -172,7 +179,7 @@ static void SETLOOP(CHle * hle, uint32_t UNUSED(w1), uint32_t w2)
static void ADPCM(CHle * hle, uint32_t w1, uint32_t w2)
{
uint32_t address = (w1 & 0xffffff);
uint8_t flags = (w2 >> 28);
uint8_t flags = (w2 >> 28);
uint16_t count = (w2 >> 16) & 0xfff;
uint16_t dmemi = ((w2 >> 12) & 0xf) + NAUDIO_MAIN;
uint16_t dmemo = (w2 & 0xfff) + NAUDIO_MAIN;
@ -181,7 +188,7 @@ static void ADPCM(CHle * hle, uint32_t w1, uint32_t w2)
hle,
flags & 0x1,
flags & 0x2,
false, // Unsupported by this microcode
false, // Unsupported by this microcode
dmemo,
dmemi,
(count + 0x1f) & ~0x1f,
@ -193,7 +200,7 @@ static void ADPCM(CHle * hle, uint32_t w1, uint32_t w2)
static void RESAMPLE(CHle * hle, uint32_t w1, uint32_t w2)
{
uint32_t address = (w1 & 0xffffff);
uint8_t flags = (w2 >> 30);
uint8_t flags = (w2 >> 30);
uint16_t pitch = (w2 >> 14);
uint16_t dmemi = ((w2 >> 2) & 0xfff) + NAUDIO_MAIN;
uint16_t dmemo = (w2 & 0x3) ? NAUDIO_MAIN2 : NAUDIO_MAIN;
@ -201,7 +208,7 @@ static void RESAMPLE(CHle * hle, uint32_t w1, uint32_t w2)
alist_resample(
hle,
flags & 0x1,
false, // TODO: check which ABI supports it
false, // TODO: check which ABI supports it
dmemo,
dmemi,
NAUDIO_COUNT,
@ -231,12 +238,11 @@ static void MP3(CHle * hle, uint32_t w1, uint32_t w2)
void alist_process_naudio(CHle * hle)
{
static const acmd_callback_t ABI[0x10] =
{
SPNOOP, ADPCM, CLEARBUFF, ENVMIXER,
LOADBUFF, RESAMPLE, SAVEBUFF, NAUDIO_0000,
NAUDIO_0000, SETVOL, DMEMMOVE, LOADADPCM,
MIXER, INTERLEAVE, NAUDIO_02B0, SETLOOP
};
{
SPNOOP, ADPCM, CLEARBUFF, ENVMIXER,
LOADBUFF, RESAMPLE, SAVEBUFF, NAUDIO_0000,
NAUDIO_0000, SETVOL, DMEMMOVE, LOADADPCM,
MIXER, INTERLEAVE, NAUDIO_02B0, SETLOOP};
alist_process(hle, ABI, 0x10);
}
@ -246,11 +252,10 @@ void alist_process_naudio_bk(CHle * hle)
// TODO: see what differs from alist_process_naudio
static const acmd_callback_t ABI[0x10] = {
SPNOOP, ADPCM, CLEARBUFF, ENVMIXER,
LOADBUFF, RESAMPLE, SAVEBUFF, NAUDIO_0000,
NAUDIO_0000, SETVOL, DMEMMOVE, LOADADPCM,
MIXER, INTERLEAVE, NAUDIO_02B0, SETLOOP
};
SPNOOP, ADPCM, CLEARBUFF, ENVMIXER,
LOADBUFF, RESAMPLE, SAVEBUFF, NAUDIO_0000,
NAUDIO_0000, SETVOL, DMEMMOVE, LOADADPCM,
MIXER, INTERLEAVE, NAUDIO_02B0, SETLOOP};
alist_process(hle, ABI, 0x10);
}
@ -260,11 +265,10 @@ void alist_process_naudio_dk(CHle * hle)
// TODO: see what differs from alist_process_naudio
static const acmd_callback_t ABI[0x10] = {
SPNOOP, ADPCM, CLEARBUFF, ENVMIXER,
LOADBUFF, RESAMPLE, SAVEBUFF, MIXER,
MIXER, SETVOL, DMEMMOVE, LOADADPCM,
MIXER, INTERLEAVE, NAUDIO_02B0, SETLOOP
};
SPNOOP, ADPCM, CLEARBUFF, ENVMIXER,
LOADBUFF, RESAMPLE, SAVEBUFF, MIXER,
MIXER, SETVOL, DMEMMOVE, LOADADPCM,
MIXER, INTERLEAVE, NAUDIO_02B0, SETLOOP};
alist_process(hle, ABI, 0x10);
}
@ -272,11 +276,10 @@ void alist_process_naudio_dk(CHle * hle)
void alist_process_naudio_mp3(CHle * hle)
{
static const acmd_callback_t ABI[0x10] = {
UNKNOWN, ADPCM, CLEARBUFF, ENVMIXER,
LOADBUFF, RESAMPLE, SAVEBUFF, MP3,
MP3ADDY, SETVOL, DMEMMOVE, LOADADPCM,
MIXER, INTERLEAVE, NAUDIO_14, SETLOOP
};
UNKNOWN, ADPCM, CLEARBUFF, ENVMIXER,
LOADBUFF, RESAMPLE, SAVEBUFF, MP3,
MP3ADDY, SETVOL, DMEMMOVE, LOADADPCM,
MIXER, INTERLEAVE, NAUDIO_14, SETLOOP};
alist_process(hle, ABI, 0x10);
}
@ -286,11 +289,10 @@ void alist_process_naudio_cbfd(CHle * hle)
// TODO: see what differs from alist_process_naudio_mp3
static const acmd_callback_t ABI[0x10] = {
UNKNOWN, ADPCM, CLEARBUFF, ENVMIXER,
LOADBUFF, RESAMPLE, SAVEBUFF, MP3,
MP3ADDY, SETVOL, DMEMMOVE, LOADADPCM,
MIXER, INTERLEAVE, NAUDIO_14, SETLOOP
};
UNKNOWN, ADPCM, CLEARBUFF, ENVMIXER,
LOADBUFF, RESAMPLE, SAVEBUFF, MP3,
MP3ADDY, SETVOL, DMEMMOVE, LOADADPCM,
MIXER, INTERLEAVE, NAUDIO_14, SETLOOP};
alist_process(hle, ABI, 0x10);
}

View File

@ -6,7 +6,8 @@
// Copyright(C) 2002 Hacktarux
// GNU/GPLv2 licensed: https://gnu.org/licenses/gpl-2.0.html
#include "stdafx.h"
#include "hle.h"
#include <stdint.h>
#include "alist.h"
#include "mem.h"
@ -25,10 +26,10 @@ static void SPNOOP(CHle * UNUSED(hle), uint32_t UNUSED(w1), uint32_t UNUSED(w2))
static void LOADADPCM(CHle * hle, uint32_t w1, uint32_t w2)
{
uint16_t count = w1;
uint16_t count = w1;
uint32_t address = (w2 & 0xffffff);
dram_load_u16(hle, (uint16_t*)hle->alist_nead().table, address, count >> 1);
dram_load_u16(hle, (uint16_t *)hle->alist_nead().table, address, count >> 1);
}
static void SETLOOP(CHle * hle, uint32_t UNUSED(w1), uint32_t w2)
@ -38,14 +39,14 @@ static void SETLOOP(CHle * hle, uint32_t UNUSED(w1), uint32_t w2)
static void SETBUFF(CHle * hle, uint32_t w1, uint32_t w2)
{
hle->alist_nead().in = w1;
hle->alist_nead().out = (w2 >> 16);
hle->alist_nead().in = w1;
hle->alist_nead().out = (w2 >> 16);
hle->alist_nead().count = w2;
}
static void ADPCM(CHle * hle, uint32_t w1, uint32_t w2)
{
uint8_t flags = (w1 >> 16);
uint8_t flags = (w1 >> 16);
uint32_t address = (w2 & 0xffffff);
alist_adpcm(
@ -63,7 +64,7 @@ static void ADPCM(CHle * hle, uint32_t w1, uint32_t w2)
static void CLEARBUFF(CHle * hle, uint32_t w1, uint32_t w2)
{
uint16_t dmem = w1;
uint16_t dmem = w1;
uint16_t count = w2;
if (count == 0)
@ -74,8 +75,8 @@ static void CLEARBUFF(CHle * hle, uint32_t w1, uint32_t w2)
static void LOADBUFF(CHle * hle, uint32_t w1, uint32_t w2)
{
uint16_t count = (w1 >> 12) & 0xfff;
uint16_t dmem = (w1 & 0xfff);
uint16_t count = (w1 >> 12) & 0xfff;
uint16_t dmem = (w1 & 0xfff);
uint32_t address = (w2 & 0xffffff);
alist_load(hle, dmem, address, count);
@ -83,8 +84,8 @@ static void LOADBUFF(CHle * hle, uint32_t w1, uint32_t w2)
static void SAVEBUFF(CHle * hle, uint32_t w1, uint32_t w2)
{
uint16_t count = (w1 >> 12) & 0xfff;
uint16_t dmem = (w1 & 0xfff);
uint16_t count = (w1 >> 12) & 0xfff;
uint16_t dmem = (w1 & 0xfff);
uint32_t address = (w2 & 0xffffff);
alist_save(hle, dmem, address, count);
@ -93,7 +94,7 @@ static void SAVEBUFF(CHle * hle, uint32_t w1, uint32_t w2)
static void MIXER(CHle * hle, uint32_t w1, uint32_t w2)
{
uint16_t count = (w1 >> 12) & 0xff0;
int16_t gain = w1;
int16_t gain = w1;
uint16_t dmemi = (w2 >> 16);
uint16_t dmemo = w2;
@ -102,14 +103,14 @@ static void MIXER(CHle * hle, uint32_t w1, uint32_t w2)
static void RESAMPLE(CHle * hle, uint32_t w1, uint32_t w2)
{
uint8_t flags = (w1 >> 16);
uint16_t pitch = w1;
uint8_t flags = (w1 >> 16);
uint16_t pitch = w1;
uint32_t address = (w2 & 0xffffff);
alist_resample(
hle,
flags & 0x1,
false, // TODO: check which ABI supports it
false, // TODO: check which ABI supports it
hle->alist_nead().out,
hle->alist_nead().in,
(hle->alist_nead().count + 0xf) & ~0xf,
@ -119,7 +120,7 @@ static void RESAMPLE(CHle * hle, uint32_t w1, uint32_t w2)
static void RESAMPLE_ZOH(CHle * hle, uint32_t w1, uint32_t w2)
{
uint16_t pitch = w1;
uint16_t pitch = w1;
uint16_t pitch_accu = w2;
alist_resample_zoh(
@ -146,17 +147,17 @@ static void DMEMMOVE(CHle * hle, uint32_t w1, uint32_t w2)
static void ENVSETUP1_MK(CHle * hle, uint32_t w1, uint32_t w2)
{
hle->alist_nead().env_values[2] = (w1 >> 8) & 0xff00;
hle->alist_nead().env_steps[2] = 0;
hle->alist_nead().env_steps[0] = (w2 >> 16);
hle->alist_nead().env_steps[1] = w2;
hle->alist_nead().env_steps[2] = 0;
hle->alist_nead().env_steps[0] = (w2 >> 16);
hle->alist_nead().env_steps[1] = w2;
}
static void ENVSETUP1(CHle * hle, uint32_t w1, uint32_t w2)
{
hle->alist_nead().env_values[2] = (w1 >> 8) & 0xff00;
hle->alist_nead().env_steps[2] = w1;
hle->alist_nead().env_steps[0] = (w2 >> 16);
hle->alist_nead().env_steps[1] = w2;
hle->alist_nead().env_steps[2] = w1;
hle->alist_nead().env_steps[0] = (w2 >> 16);
hle->alist_nead().env_steps[1] = w2;
}
static void ENVSETUP2(CHle * hle, uint32_t UNUSED(w1), uint32_t w2)
@ -170,20 +171,20 @@ static void ENVMIXER_MK(CHle * hle, uint32_t w1, uint32_t w2)
int16_t xors[4];
uint16_t dmemi = (w1 >> 12) & 0xff0;
uint8_t count = (w1 >> 8) & 0xff;
uint8_t count = (w1 >> 8) & 0xff;
uint16_t dmem_dl = (w2 >> 20) & 0xff0;
uint16_t dmem_dr = (w2 >> 12) & 0xff0;
uint16_t dmem_wl = (w2 >> 4) & 0xff0;
uint16_t dmem_wr = (w2 << 4) & 0xff0;
uint16_t dmem_wl = (w2 >> 4) & 0xff0;
uint16_t dmem_wr = (w2 << 4) & 0xff0;
xors[2] = 0; // Unsupported by this microcode
xors[3] = 0; // Unsupported by this microcode
xors[2] = 0; // Unsupported by this microcode
xors[3] = 0; // Unsupported by this microcode
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(
hle,
false, // Unsupported by this microcode
false, // Unsupported by this microcode
dmem_dl, dmem_dr,
dmem_wl, dmem_wr,
dmemi, count,
@ -197,17 +198,17 @@ static void ENVMIXER(CHle * hle, uint32_t w1, uint32_t w2)
int16_t xors[4];
uint16_t dmemi = (w1 >> 12) & 0xff0;
uint8_t count = (w1 >> 8) & 0xff;
bool swap_wet_LR = (w1 >> 4) & 0x1;
uint8_t count = (w1 >> 8) & 0xff;
bool swap_wet_LR = (w1 >> 4) & 0x1;
uint16_t dmem_dl = (w2 >> 20) & 0xff0;
uint16_t dmem_dr = (w2 >> 12) & 0xff0;
uint16_t dmem_wl = (w2 >> 4) & 0xff0;
uint16_t dmem_wr = (w2 << 4) & 0xff0;
uint16_t dmem_wl = (w2 >> 4) & 0xff0;
uint16_t dmem_wr = (w2 << 4) & 0xff0;
xors[2] = 0 - (int16_t)((w1 & 0x8) >> 1);
xors[3] = 0 - (int16_t)((w1 & 0x4) >> 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(
hle,
@ -222,7 +223,7 @@ static void ENVMIXER(CHle * hle, uint32_t w1, uint32_t w2)
static void DUPLICATE(CHle * hle, uint32_t w1, uint32_t w2)
{
uint8_t count = (w1 >> 16);
uint8_t count = (w1 >> 16);
uint16_t dmemi = w1;
uint16_t dmemo = (w2 >> 16);
@ -270,23 +271,25 @@ static void ADDMIXER(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 dmem = (w2 >> 16);
uint16_t dmem = (w2 >> 16);
alist_multQ44(hle, dmem, count, gain);
}
static void FILTER(CHle * hle, uint32_t w1, uint32_t w2)
{
uint8_t flags = (w1 >> 16);
uint8_t flags = (w1 >> 16);
uint32_t address = (w2 & 0xffffff);
if (flags > 1) {
hle->alist_nead().filter_count = w1;
if (flags > 1)
{
hle->alist_nead().filter_count = w1;
hle->alist_nead().filter_lut_address[0] = address; // T6
}
else {
else
{
uint16_t dmem = w1;
hle->alist_nead().filter_lut_address[1] = address + 0x10; // T5
@ -300,9 +303,9 @@ static void SEGMENT(CHle * UNUSED(hle), uint32_t UNUSED(w1), uint32_t UNUSED(w2)
static void NEAD_16(CHle * hle, uint32_t w1, uint32_t w2)
{
uint8_t count = (w1 >> 16);
uint16_t dmemi = w1;
uint16_t dmemo = (w2 >> 16);
uint8_t count = (w1 >> 16);
uint16_t dmemi = w1;
uint16_t dmemo = (w2 >> 16);
uint16_t block_size = w2;
alist_copy_blocks(hle, dmemo, dmemi, block_size, count);
@ -310,8 +313,8 @@ static void NEAD_16(CHle * hle, uint32_t w1, uint32_t w2)
static void POLEF(CHle * hle, uint32_t w1, uint32_t w2)
{
uint8_t flags = (w1 >> 16);
uint16_t gain = w1;
uint8_t flags = (w1 >> 16);
uint16_t gain = w1;
uint32_t address = (w2 & 0xffffff);
if (hle->alist_nead().count == 0)
@ -331,15 +334,14 @@ static void POLEF(CHle * hle, uint32_t w1, uint32_t w2)
void alist_process_nead_mk(CHle * hle)
{
static const acmd_callback_t ABI[0x20] = {
SPNOOP, ADPCM, CLEARBUFF, SPNOOP,
SPNOOP, RESAMPLE, SPNOOP, SEGMENT,
SETBUFF, SPNOOP, DMEMMOVE, LOADADPCM,
MIXER, INTERLEAVE_MK, POLEF, SETLOOP,
NEAD_16, INTERL, ENVSETUP1_MK, ENVMIXER_MK,
LOADBUFF, SAVEBUFF, ENVSETUP2, SPNOOP,
SPNOOP, SPNOOP, SPNOOP, SPNOOP,
SPNOOP, SPNOOP, SPNOOP, SPNOOP
};
SPNOOP, ADPCM, CLEARBUFF, SPNOOP,
SPNOOP, RESAMPLE, SPNOOP, SEGMENT,
SETBUFF, SPNOOP, DMEMMOVE, LOADADPCM,
MIXER, INTERLEAVE_MK, POLEF, SETLOOP,
NEAD_16, INTERL, ENVSETUP1_MK, ENVMIXER_MK,
LOADBUFF, SAVEBUFF, ENVSETUP2, SPNOOP,
SPNOOP, SPNOOP, SPNOOP, SPNOOP,
SPNOOP, SPNOOP, SPNOOP, SPNOOP};
alist_process(hle, ABI, 0x20);
}
@ -347,15 +349,14 @@ void alist_process_nead_mk(CHle * hle)
void alist_process_nead_sf(CHle * hle)
{
static const acmd_callback_t ABI[0x20] = {
SPNOOP, ADPCM, CLEARBUFF, SPNOOP,
ADDMIXER, RESAMPLE, RESAMPLE_ZOH, SPNOOP,
SETBUFF, SPNOOP, DMEMMOVE, LOADADPCM,
MIXER, INTERLEAVE_MK, POLEF, SETLOOP,
NEAD_16, INTERL, ENVSETUP1, ENVMIXER,
LOADBUFF, SAVEBUFF, ENVSETUP2, SPNOOP,
HILOGAIN, UNKNOWN, DUPLICATE, SPNOOP,
SPNOOP, SPNOOP, SPNOOP, SPNOOP
};
SPNOOP, ADPCM, CLEARBUFF, SPNOOP,
ADDMIXER, RESAMPLE, RESAMPLE_ZOH, SPNOOP,
SETBUFF, SPNOOP, DMEMMOVE, LOADADPCM,
MIXER, INTERLEAVE_MK, POLEF, SETLOOP,
NEAD_16, INTERL, ENVSETUP1, ENVMIXER,
LOADBUFF, SAVEBUFF, ENVSETUP2, SPNOOP,
HILOGAIN, UNKNOWN, DUPLICATE, SPNOOP,
SPNOOP, SPNOOP, SPNOOP, SPNOOP};
alist_process(hle, ABI, 0x20);
}
@ -363,15 +364,14 @@ void alist_process_nead_sf(CHle * hle)
void alist_process_nead_sfj(CHle * hle)
{
static const acmd_callback_t ABI[0x20] = {
SPNOOP, ADPCM, CLEARBUFF, SPNOOP,
ADDMIXER, RESAMPLE, RESAMPLE_ZOH, SPNOOP,
SETBUFF, SPNOOP, DMEMMOVE, LOADADPCM,
MIXER, INTERLEAVE_MK, POLEF, SETLOOP,
NEAD_16, INTERL, ENVSETUP1, ENVMIXER,
LOADBUFF, SAVEBUFF, ENVSETUP2, UNKNOWN,
HILOGAIN, UNKNOWN, DUPLICATE, SPNOOP,
SPNOOP, SPNOOP, SPNOOP, SPNOOP
};
SPNOOP, ADPCM, CLEARBUFF, SPNOOP,
ADDMIXER, RESAMPLE, RESAMPLE_ZOH, SPNOOP,
SETBUFF, SPNOOP, DMEMMOVE, LOADADPCM,
MIXER, INTERLEAVE_MK, POLEF, SETLOOP,
NEAD_16, INTERL, ENVSETUP1, ENVMIXER,
LOADBUFF, SAVEBUFF, ENVSETUP2, UNKNOWN,
HILOGAIN, UNKNOWN, DUPLICATE, SPNOOP,
SPNOOP, SPNOOP, SPNOOP, SPNOOP};
alist_process(hle, ABI, 0x20);
}
@ -379,15 +379,14 @@ void alist_process_nead_sfj(CHle * hle)
void alist_process_nead_fz(CHle * hle)
{
static const acmd_callback_t ABI[0x20] = {
UNKNOWN, ADPCM, CLEARBUFF, SPNOOP,
ADDMIXER, RESAMPLE, SPNOOP, SPNOOP,
SETBUFF, SPNOOP, DMEMMOVE, LOADADPCM,
MIXER, INTERLEAVE, SPNOOP, SETLOOP,
NEAD_16, INTERL, ENVSETUP1, ENVMIXER,
LOADBUFF, SAVEBUFF, ENVSETUP2, UNKNOWN,
SPNOOP, UNKNOWN, DUPLICATE, SPNOOP,
SPNOOP, SPNOOP, SPNOOP, SPNOOP
};
UNKNOWN, ADPCM, CLEARBUFF, SPNOOP,
ADDMIXER, RESAMPLE, SPNOOP, SPNOOP,
SETBUFF, SPNOOP, DMEMMOVE, LOADADPCM,
MIXER, INTERLEAVE, SPNOOP, SETLOOP,
NEAD_16, INTERL, ENVSETUP1, ENVMIXER,
LOADBUFF, SAVEBUFF, ENVSETUP2, UNKNOWN,
SPNOOP, UNKNOWN, DUPLICATE, SPNOOP,
SPNOOP, SPNOOP, SPNOOP, SPNOOP};
alist_process(hle, ABI, 0x20);
}
@ -395,15 +394,14 @@ void alist_process_nead_fz(CHle * hle)
void alist_process_nead_wrjb(CHle * hle)
{
static const acmd_callback_t ABI[0x20] = {
SPNOOP, ADPCM, CLEARBUFF, UNKNOWN,
ADDMIXER, RESAMPLE, RESAMPLE_ZOH, SPNOOP,
SETBUFF, SPNOOP, DMEMMOVE, LOADADPCM,
MIXER, INTERLEAVE, SPNOOP, SETLOOP,
NEAD_16, INTERL, ENVSETUP1, ENVMIXER,
LOADBUFF, SAVEBUFF, ENVSETUP2, UNKNOWN,
HILOGAIN, UNKNOWN, DUPLICATE, FILTER,
SPNOOP, SPNOOP, SPNOOP, SPNOOP
};
SPNOOP, ADPCM, CLEARBUFF, UNKNOWN,
ADDMIXER, RESAMPLE, RESAMPLE_ZOH, SPNOOP,
SETBUFF, SPNOOP, DMEMMOVE, LOADADPCM,
MIXER, INTERLEAVE, SPNOOP, SETLOOP,
NEAD_16, INTERL, ENVSETUP1, ENVMIXER,
LOADBUFF, SAVEBUFF, ENVSETUP2, UNKNOWN,
HILOGAIN, UNKNOWN, DUPLICATE, FILTER,
SPNOOP, SPNOOP, SPNOOP, SPNOOP};
alist_process(hle, ABI, 0x20);
}
@ -411,13 +409,12 @@ void alist_process_nead_wrjb(CHle * hle)
void alist_process_nead_ys(CHle * hle)
{
static const acmd_callback_t ABI[0x18] = {
UNKNOWN, ADPCM, CLEARBUFF, UNKNOWN,
ADDMIXER, RESAMPLE, RESAMPLE_ZOH, FILTER,
SETBUFF, DUPLICATE, DMEMMOVE, LOADADPCM,
MIXER, INTERLEAVE, HILOGAIN, SETLOOP,
NEAD_16, INTERL, ENVSETUP1, ENVMIXER,
LOADBUFF, SAVEBUFF, ENVSETUP2, UNKNOWN
};
UNKNOWN, ADPCM, CLEARBUFF, UNKNOWN,
ADDMIXER, RESAMPLE, RESAMPLE_ZOH, FILTER,
SETBUFF, DUPLICATE, DMEMMOVE, LOADADPCM,
MIXER, INTERLEAVE, HILOGAIN, SETLOOP,
NEAD_16, INTERL, ENVSETUP1, ENVMIXER,
LOADBUFF, SAVEBUFF, ENVSETUP2, UNKNOWN};
alist_process(hle, ABI, 0x18);
}
@ -425,13 +422,12 @@ void alist_process_nead_ys(CHle * hle)
void alist_process_nead_1080(CHle * hle)
{
static const acmd_callback_t ABI[0x18] = {
UNKNOWN, ADPCM, CLEARBUFF, UNKNOWN,
ADDMIXER, RESAMPLE, RESAMPLE_ZOH, FILTER,
SETBUFF, DUPLICATE, DMEMMOVE, LOADADPCM,
MIXER, INTERLEAVE, HILOGAIN, SETLOOP,
NEAD_16, INTERL, ENVSETUP1, ENVMIXER,
LOADBUFF, SAVEBUFF, ENVSETUP2, UNKNOWN
};
UNKNOWN, ADPCM, CLEARBUFF, UNKNOWN,
ADDMIXER, RESAMPLE, RESAMPLE_ZOH, FILTER,
SETBUFF, DUPLICATE, DMEMMOVE, LOADADPCM,
MIXER, INTERLEAVE, HILOGAIN, SETLOOP,
NEAD_16, INTERL, ENVSETUP1, ENVMIXER,
LOADBUFF, SAVEBUFF, ENVSETUP2, UNKNOWN};
alist_process(hle, ABI, 0x18);
}
@ -439,13 +435,12 @@ void alist_process_nead_1080(CHle * hle)
void alist_process_nead_oot(CHle * hle)
{
static const acmd_callback_t ABI[0x18] = {
UNKNOWN, ADPCM, CLEARBUFF, UNKNOWN,
ADDMIXER, RESAMPLE, RESAMPLE_ZOH, FILTER,
SETBUFF, DUPLICATE, DMEMMOVE, LOADADPCM,
MIXER, INTERLEAVE, HILOGAIN, SETLOOP,
NEAD_16, INTERL, ENVSETUP1, ENVMIXER,
LOADBUFF, SAVEBUFF, ENVSETUP2, UNKNOWN
};
UNKNOWN, ADPCM, CLEARBUFF, UNKNOWN,
ADDMIXER, RESAMPLE, RESAMPLE_ZOH, FILTER,
SETBUFF, DUPLICATE, DMEMMOVE, LOADADPCM,
MIXER, INTERLEAVE, HILOGAIN, SETLOOP,
NEAD_16, INTERL, ENVSETUP1, ENVMIXER,
LOADBUFF, SAVEBUFF, ENVSETUP2, UNKNOWN};
alist_process(hle, ABI, 0x18);
}
@ -453,13 +448,12 @@ void alist_process_nead_oot(CHle * hle)
void alist_process_nead_mm(CHle * hle)
{
static const acmd_callback_t ABI[0x18] = {
UNKNOWN, ADPCM, CLEARBUFF, SPNOOP,
ADDMIXER, RESAMPLE, RESAMPLE_ZOH, FILTER,
SETBUFF, DUPLICATE, DMEMMOVE, LOADADPCM,
MIXER, INTERLEAVE, HILOGAIN, SETLOOP,
NEAD_16, INTERL, ENVSETUP1, ENVMIXER,
LOADBUFF, SAVEBUFF, ENVSETUP2, UNKNOWN
};
UNKNOWN, ADPCM, CLEARBUFF, SPNOOP,
ADDMIXER, RESAMPLE, RESAMPLE_ZOH, FILTER,
SETBUFF, DUPLICATE, DMEMMOVE, LOADADPCM,
MIXER, INTERLEAVE, HILOGAIN, SETLOOP,
NEAD_16, INTERL, ENVSETUP1, ENVMIXER,
LOADBUFF, SAVEBUFF, ENVSETUP2, UNKNOWN};
alist_process(hle, ABI, 0x18);
}
@ -467,13 +461,12 @@ void alist_process_nead_mm(CHle * hle)
void alist_process_nead_mmb(CHle * hle)
{
static const acmd_callback_t ABI[0x18] = {
SPNOOP, ADPCM, CLEARBUFF, SPNOOP,
ADDMIXER, RESAMPLE, RESAMPLE_ZOH, FILTER,
SETBUFF, DUPLICATE, DMEMMOVE, LOADADPCM,
MIXER, INTERLEAVE, HILOGAIN, SETLOOP,
NEAD_16, INTERL, ENVSETUP1, ENVMIXER,
LOADBUFF, SAVEBUFF, ENVSETUP2, UNKNOWN
};
SPNOOP, ADPCM, CLEARBUFF, SPNOOP,
ADDMIXER, RESAMPLE, RESAMPLE_ZOH, FILTER,
SETBUFF, DUPLICATE, DMEMMOVE, LOADADPCM,
MIXER, INTERLEAVE, HILOGAIN, SETLOOP,
NEAD_16, INTERL, ENVSETUP1, ENVMIXER,
LOADBUFF, SAVEBUFF, ENVSETUP2, UNKNOWN};
alist_process(hle, ABI, 0x18);
}
@ -481,13 +474,12 @@ void alist_process_nead_mmb(CHle * hle)
void alist_process_nead_ac(CHle * hle)
{
static const acmd_callback_t ABI[0x18] = {
UNKNOWN, ADPCM, CLEARBUFF, SPNOOP,
ADDMIXER, RESAMPLE, RESAMPLE_ZOH, FILTER,
SETBUFF, DUPLICATE, DMEMMOVE, LOADADPCM,
MIXER, INTERLEAVE, HILOGAIN, SETLOOP,
NEAD_16, INTERL, ENVSETUP1, ENVMIXER,
LOADBUFF, SAVEBUFF, ENVSETUP2, UNKNOWN
};
UNKNOWN, ADPCM, CLEARBUFF, SPNOOP,
ADDMIXER, RESAMPLE, RESAMPLE_ZOH, FILTER,
SETBUFF, DUPLICATE, DMEMMOVE, LOADADPCM,
MIXER, INTERLEAVE, HILOGAIN, SETLOOP,
NEAD_16, INTERL, ENVSETUP1, ENVMIXER,
LOADBUFF, SAVEBUFF, ENVSETUP2, UNKNOWN};
alist_process(hle, ABI, 0x18);
}

View File

@ -16,5 +16,5 @@ static inline int16_t clamp_s16(int_fast32_t x)
static inline int32_t vmulf(int16_t x, int16_t y)
{
return (((int32_t)(x))*((int32_t)(y))+0x4000)>>15;
return (((int32_t)(x)) * ((int32_t)(y)) + 0x4000) >> 15;
}

View File

@ -0,0 +1,114 @@
// Project64 - A Nintendo 64 emulator
// https://www.pj64-emu.com/
// Copyright(C) 2001-2021 Project64
// Copyright(C) 2014 Bobby Smiles
// GNU/GPLv2 licensed: https://gnu.org/licenses/gpl-2.0.html
#include "audio.h"
#include <assert.h>
#include <stdint.h>
#include "arithmetics.h"
const int16_t RESAMPLE_LUT[64 * 4] =
{
(int16_t)0x0c39u, (int16_t)0x66adu, (int16_t)0x0d46u, (int16_t)0xffdfu,
(int16_t)0x0b39u, (int16_t)0x6696u, (int16_t)0x0e5fu, (int16_t)0xffd8u,
(int16_t)0x0a44u, (int16_t)0x6669u, (int16_t)0x0f83u, (int16_t)0xffd0u,
(int16_t)0x095au, (int16_t)0x6626u, (int16_t)0x10b4u, (int16_t)0xffc8u,
(int16_t)0x087du, (int16_t)0x65cdu, (int16_t)0x11f0u, (int16_t)0xffbfu,
(int16_t)0x07abu, (int16_t)0x655eu, (int16_t)0x1338u, (int16_t)0xffb6u,
(int16_t)0x06e4u, (int16_t)0x64d9u, (int16_t)0x148cu, (int16_t)0xffacu,
(int16_t)0x0628u, (int16_t)0x643fu, (int16_t)0x15ebu, (int16_t)0xffa1u,
(int16_t)0x0577u, (int16_t)0x638fu, (int16_t)0x1756u, (int16_t)0xff96u,
(int16_t)0x04d1u, (int16_t)0x62cbu, (int16_t)0x18cbu, (int16_t)0xff8au,
(int16_t)0x0435u, (int16_t)0x61f3u, (int16_t)0x1a4cu, (int16_t)0xff7eu,
(int16_t)0x03a4u, (int16_t)0x6106u, (int16_t)0x1bd7u, (int16_t)0xff71u,
(int16_t)0x031cu, (int16_t)0x6007u, (int16_t)0x1d6cu, (int16_t)0xff64u,
(int16_t)0x029fu, (int16_t)0x5ef5u, (int16_t)0x1f0bu, (int16_t)0xff56u,
(int16_t)0x022au, (int16_t)0x5dd0u, (int16_t)0x20b3u, (int16_t)0xff48u,
(int16_t)0x01beu, (int16_t)0x5c9au, (int16_t)0x2264u, (int16_t)0xff3au,
(int16_t)0x015bu, (int16_t)0x5b53u, (int16_t)0x241eu, (int16_t)0xff2cu,
(int16_t)0x0101u, (int16_t)0x59fcu, (int16_t)0x25e0u, (int16_t)0xff1eu,
(int16_t)0x00aeu, (int16_t)0x5896u, (int16_t)0x27a9u, (int16_t)0xff10u,
(int16_t)0x0063u, (int16_t)0x5720u, (int16_t)0x297au, (int16_t)0xff02u,
(int16_t)0x001fu, (int16_t)0x559du, (int16_t)0x2b50u, (int16_t)0xfef4u,
(int16_t)0xffe2u, (int16_t)0x540du, (int16_t)0x2d2cu, (int16_t)0xfee8u,
(int16_t)0xffacu, (int16_t)0x5270u, (int16_t)0x2f0du, (int16_t)0xfedbu,
(int16_t)0xff7cu, (int16_t)0x50c7u, (int16_t)0x30f3u, (int16_t)0xfed0u,
(int16_t)0xff53u, (int16_t)0x4f14u, (int16_t)0x32dcu, (int16_t)0xfec6u,
(int16_t)0xff2eu, (int16_t)0x4d57u, (int16_t)0x34c8u, (int16_t)0xfebdu,
(int16_t)0xff0fu, (int16_t)0x4b91u, (int16_t)0x36b6u, (int16_t)0xfeb6u,
(int16_t)0xfef5u, (int16_t)0x49c2u, (int16_t)0x38a5u, (int16_t)0xfeb0u,
(int16_t)0xfedfu, (int16_t)0x47edu, (int16_t)0x3a95u, (int16_t)0xfeacu,
(int16_t)0xfeceu, (int16_t)0x4611u, (int16_t)0x3c85u, (int16_t)0xfeabu,
(int16_t)0xfec0u, (int16_t)0x4430u, (int16_t)0x3e74u, (int16_t)0xfeacu,
(int16_t)0xfeb6u, (int16_t)0x424au, (int16_t)0x4060u, (int16_t)0xfeafu,
(int16_t)0xfeafu, (int16_t)0x4060u, (int16_t)0x424au, (int16_t)0xfeb6u,
(int16_t)0xfeacu, (int16_t)0x3e74u, (int16_t)0x4430u, (int16_t)0xfec0u,
(int16_t)0xfeabu, (int16_t)0x3c85u, (int16_t)0x4611u, (int16_t)0xfeceu,
(int16_t)0xfeacu, (int16_t)0x3a95u, (int16_t)0x47edu, (int16_t)0xfedfu,
(int16_t)0xfeb0u, (int16_t)0x38a5u, (int16_t)0x49c2u, (int16_t)0xfef5u,
(int16_t)0xfeb6u, (int16_t)0x36b6u, (int16_t)0x4b91u, (int16_t)0xff0fu,
(int16_t)0xfebdu, (int16_t)0x34c8u, (int16_t)0x4d57u, (int16_t)0xff2eu,
(int16_t)0xfec6u, (int16_t)0x32dcu, (int16_t)0x4f14u, (int16_t)0xff53u,
(int16_t)0xfed0u, (int16_t)0x30f3u, (int16_t)0x50c7u, (int16_t)0xff7cu,
(int16_t)0xfedbu, (int16_t)0x2f0du, (int16_t)0x5270u, (int16_t)0xffacu,
(int16_t)0xfee8u, (int16_t)0x2d2cu, (int16_t)0x540du, (int16_t)0xffe2u,
(int16_t)0xfef4u, (int16_t)0x2b50u, (int16_t)0x559du, (int16_t)0x001fu,
(int16_t)0xff02u, (int16_t)0x297au, (int16_t)0x5720u, (int16_t)0x0063u,
(int16_t)0xff10u, (int16_t)0x27a9u, (int16_t)0x5896u, (int16_t)0x00aeu,
(int16_t)0xff1eu, (int16_t)0x25e0u, (int16_t)0x59fcu, (int16_t)0x0101u,
(int16_t)0xff2cu, (int16_t)0x241eu, (int16_t)0x5b53u, (int16_t)0x015bu,
(int16_t)0xff3au, (int16_t)0x2264u, (int16_t)0x5c9au, (int16_t)0x01beu,
(int16_t)0xff48u, (int16_t)0x20b3u, (int16_t)0x5dd0u, (int16_t)0x022au,
(int16_t)0xff56u, (int16_t)0x1f0bu, (int16_t)0x5ef5u, (int16_t)0x029fu,
(int16_t)0xff64u, (int16_t)0x1d6cu, (int16_t)0x6007u, (int16_t)0x031cu,
(int16_t)0xff71u, (int16_t)0x1bd7u, (int16_t)0x6106u, (int16_t)0x03a4u,
(int16_t)0xff7eu, (int16_t)0x1a4cu, (int16_t)0x61f3u, (int16_t)0x0435u,
(int16_t)0xff8au, (int16_t)0x18cbu, (int16_t)0x62cbu, (int16_t)0x04d1u,
(int16_t)0xff96u, (int16_t)0x1756u, (int16_t)0x638fu, (int16_t)0x0577u,
(int16_t)0xffa1u, (int16_t)0x15ebu, (int16_t)0x643fu, (int16_t)0x0628u,
(int16_t)0xffacu, (int16_t)0x148cu, (int16_t)0x64d9u, (int16_t)0x06e4u,
(int16_t)0xffb6u, (int16_t)0x1338u, (int16_t)0x655eu, (int16_t)0x07abu,
(int16_t)0xffbfu, (int16_t)0x11f0u, (int16_t)0x65cdu, (int16_t)0x087du,
(int16_t)0xffc8u, (int16_t)0x10b4u, (int16_t)0x6626u, (int16_t)0x095au,
(int16_t)0xffd0u, (int16_t)0x0f83u, (int16_t)0x6669u, (int16_t)0x0a44u,
(int16_t)0xffd8u, (int16_t)0x0e5fu, (int16_t)0x6696u, (int16_t)0x0b39u,
(int16_t)0xffdfu, (int16_t)0x0d46u, (int16_t)0x66adu, (int16_t)0x0c39u};
int32_t rdot(size_t n, const int16_t * x, const int16_t * y)
{
int32_t accu = 0;
y += n;
while (n != 0)
{
accu += *(x++) * *(--y);
--n;
}
return accu;
}
void adpcm_compute_residuals(int16_t * dst, const int16_t * src,
const int16_t * cb_entry, const int16_t * last_samples, size_t count)
{
const int16_t * const book1 = cb_entry;
const int16_t * const book2 = cb_entry + 8;
const int16_t l1 = last_samples[0];
const int16_t l2 = last_samples[1];
size_t i;
assert(count <= 8);
for (i = 0; i < count; ++i)
{
int32_t accu = (int32_t)src[i] << 11;
accu += book1[i] * l1 + book2[i] * l2 + rdot(i, book2, src);
dst[i] = clamp_s16(accu >> 11);
}
}

View File

@ -5,18 +5,19 @@
// GNU/GPLv2 licensed: https://gnu.org/licenses/gpl-2.0.html
#pragma once
#include <stdint.h>
extern const int16_t RESAMPLE_LUT[64 * 4];
int32_t rdot(size_t n, const int16_t *x, const int16_t *y);
int32_t rdot(size_t n, const int16_t * x, const int16_t * y);
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;
sample >>= rshift; // Signed
return sample;
}
void adpcm_compute_residuals(int16_t* dst, const int16_t* src,
const int16_t* cb_entry, const int16_t* last_samples, size_t count);
void adpcm_compute_residuals(int16_t * dst, const int16_t * src,
const int16_t * cb_entry, const int16_t * last_samples, size_t count);

View File

@ -6,9 +6,11 @@
// Copyright(C) 2002 Hacktarux
// GNU/GPLv2 licensed: https://gnu.org/licenses/gpl-2.0.html
#include "stdafx.h"
#include <stdint.h>
#include <string.h>
#include "hle.h"
/*
During IPL3 stage of CIC x105 games, the RSP performs some checks and transactions
necessary for booting the game.
@ -22,8 +24,8 @@ void cicx105_ucode(CHle * hle)
{
// memcpy is okay to use because access constraints are met (alignment, size)
unsigned int i;
unsigned char *dst = hle->dram() + 0x2fb1f0;
unsigned char *src = hle->imem() + 0x120;
unsigned char * dst = hle->dram() + 0x2fb1f0;
unsigned char * src = hle->imem() + 0x120;
// dma_read(0x1120, 0x1e8, 0x1e8)
memcpy(hle->imem() + 0x120, hle->dram() + 0x1e8, 0x1f0);

View File

@ -6,19 +6,20 @@
// Copyright(C) 2002 Hacktarux
// GNU/GPLv2 licensed: https://gnu.org/licenses/gpl-2.0.html
#include "stdafx.h"
#if defined (_WIN32) && defined(_DEBUG)
#include "hle.h"
#include <stdint.h>
#if defined(_WIN32) && defined(_DEBUG)
#include <Windows.h>
#endif
#include "mem.h"
#include "ucodes.h"
#include <memory.h>
#define min(a,b) (((a) < (b)) ? (a) : (b))
#define min(a, b) (((a) < (b)) ? (a) : (b))
// 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) :
m_dram(Rsp_Info.RDRAM),
@ -98,7 +99,7 @@ void CHle::hle_execute(void)
static unsigned int sum_bytes(const uint8_t * bytes, unsigned int size)
{
unsigned int sum = 0;
const unsigned char *const bytes_end = bytes + size;
const unsigned char * const bytes_end = bytes + size;
while (bytes != bytes_end)
{
@ -265,7 +266,8 @@ void CHle::normal_task_dispatching(void)
const unsigned int sum =
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]
case 0x278:
// Nothing to emulate
@ -320,7 +322,7 @@ void CHle::non_task_dispatching(void)
#endif
}
void CHle::VerboseMessage(const char *message, ...)
void CHle::VerboseMessage(const char * /*message*/, ...)
{
#if defined(_WIN32) && defined(_DEBUG)
// These can get annoying
@ -330,7 +332,7 @@ void CHle::VerboseMessage(const char *message, ...)
#endif
}
void CHle::WarnMessage(const char *message, ...)
void CHle::WarnMessage(const char * message, ...)
{
#if defined(_WIN32) && defined(_DEBUG)
MessageBoxA(NULL, message, "HLE warning message", MB_OK);

View File

@ -0,0 +1,138 @@
// Project64 - A Nintendo 64 emulator
// https://www.pj64-emu.com/
// Copyright(C) 2001-2021 Project64
// Copyright(C) 2014 Bobby Smiles
// GNU/GPLv2 licensed: https://gnu.org/licenses/gpl-2.0.html
#pragma once
#include "ucodes.h"
#include <Project64-rsp-core/RSPInfo.h>
#include <Project64-rsp-core/cpu/RSPRegisters.h>
#include <stdint.h>
// Macro for unused variable warning suppression
#ifdef __GNUC__
#define UNUSED(x) UNUSED_##x __attribute__((__unused__))
#else
#define UNUSED(x) /* x */
#endif
class CHle
{
public:
CHle(const RSP_INFO & Rsp_Info);
~CHle();
uint8_t * dram()
{
return m_dram;
}
uint8_t * dmem()
{
return m_dmem;
}
uint8_t * imem()
{
return m_imem;
}
bool AudioHle()
{
return m_AudioHle;
}
bool GraphicsHle()
{
return m_GraphicsHle;
}
struct alist_audio_t & alist_audio()
{
return m_alist_audio;
}
struct alist_naudio_t & alist_naudio()
{
return m_alist_naudio;
}
struct alist_nead_t & alist_nead()
{
return m_alist_nead;
}
uint8_t * mp3_buffer()
{
return &m_mp3_buffer[0];
}
uint8_t * alist_buffer()
{
return &m_alist_buffer[0];
}
void VerboseMessage(const char * message, ...);
void WarnMessage(const char * message, ...);
void ErrorMessage(const char * message, ...);
void rsp_break(uint32_t setbits);
void hle_execute(void);
bool try_fast_audio_dispatching(void);
private:
CHle(void);
CHle(const CHle &);
CHle & operator=(const CHle &);
bool is_task(void);
bool try_fast_task_dispatching(void);
void normal_task_dispatching(void);
void non_task_dispatching(void);
uint8_t * m_dram;
uint8_t * m_dmem;
uint8_t * m_imem;
uint32_t * m_mi_intr;
uint32_t * m_sp_mem_addr;
uint32_t * m_sp_dram_addr;
uint32_t * m_sp_rd_length;
uint32_t * m_sp_wr_length;
uint32_t * m_sp_status;
uint32_t * m_sp_dma_full;
uint32_t * m_sp_dma_busy;
uint32_t * m_sp_pc;
uint32_t * m_sp_semaphore;
uint32_t * m_dpc_start;
uint32_t * m_dpc_end;
uint32_t * m_dpc_current;
uint32_t * m_dpc_status;
uint32_t * m_dpc_clock;
uint32_t * m_dpc_bufbusy;
uint32_t * m_dpc_pipebusy;
uint32_t * m_dpc_tmem;
void (*m_CheckInterrupts)(void);
void (*m_ProcessDList)(void);
void (*m_ProcessAList)(void);
void (*m_ProcessRdpList)(void);
void (*m_ShowCFB)(void);
// alist.cpp
uint8_t m_alist_buffer[0x1000];
// alist_audio.cpp
struct alist_audio_t m_alist_audio;
// alist_naudio.cpp
struct alist_naudio_t m_alist_naudio;
// alist_nead.cpp
struct alist_nead_t m_alist_nead;
// mp3.cpp
uint8_t m_mp3_buffer[0x1000];
bool m_AudioHle;
bool m_GraphicsHle;
bool m_ForwardAudio;
bool m_ForwardGFX;
};

View File

@ -6,7 +6,7 @@
// Copyright(C) 2002 Hacktarux
// GNU/GPLv2 licensed: https://gnu.org/licenses/gpl-2.0.html
#include "stdafx.h"
#include <stdint.h>
#include <stdlib.h>
#include "arithmetics.h"
@ -14,15 +14,15 @@
#define SUBBLOCK_SIZE 64
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 (*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);
// Standard JPEG microcode decoder
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);
const char * const version,
const subblock_transform_t transform_luma,
const subblock_transform_t transform_chroma,
const tile_line_emitter_t emit_line);
// Helper functions
static uint8_t clamp_u8(int16_t x);
@ -34,30 +34,30 @@ 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);
// Tile line emitters
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 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);
// 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,
const subblock_transform_t transform_chroma,
int16_t *macroblock,
unsigned int subblock_count,
const int16_t qtables[3][SUBBLOCK_SIZE]);
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);
const subblock_transform_t transform_chroma,
int16_t * macroblock,
unsigned int subblock_count,
const int16_t qtables[3][SUBBLOCK_SIZE]);
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);
// Sub blocks operations
static void TransposeSubBlock(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 MultSubBlocks(int16_t *dst, const int16_t *src1, const int16_t *src2, unsigned int shift);
static void ScaleSubBlock(int16_t *dst, const int16_t *src, int16_t scale);
static void RShiftSubBlock(int16_t *dst, const int16_t *src, unsigned int shift);
static void InverseDCT1D(const float *const x, float *dst, unsigned int stride);
static void InverseDCTSubBlock(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 TransposeSubBlock(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 MultSubBlocks(int16_t * dst, const int16_t * src1, const int16_t * src2, unsigned int shift);
static void ScaleSubBlock(int16_t * dst, const int16_t * src, int16_t scale);
static void RShiftSubBlock(int16_t * dst, const int16_t * src, unsigned int shift);
static void InverseDCT1D(const float * const x, float * dst, unsigned int stride);
static void InverseDCTSubBlock(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);
// Transposed dequantization table
static const int16_t DEFAULT_QTABLE[SUBBLOCK_SIZE] = {
@ -68,8 +68,7 @@ static const int16_t DEFAULT_QTABLE[SUBBLOCK_SIZE] = {
24, 26, 40, 51, 68, 81, 103, 112,
40, 58, 57, 87, 109, 104, 121, 100,
51, 60, 69, 80, 103, 113, 120, 103,
61, 55, 56, 62, 77, 92, 101, 99
};
61, 55, 56, 62, 77, 92, 101, 99};
// Zig-zag indices
static const unsigned int ZIGZAG_TABLE[SUBBLOCK_SIZE] = {
@ -80,8 +79,7 @@ static const unsigned int ZIGZAG_TABLE[SUBBLOCK_SIZE] = {
10, 19, 23, 32, 39, 45, 52, 54,
20, 22, 33, 38, 46, 51, 55, 60,
21, 34, 37, 47, 50, 56, 59, 61,
35, 36, 48, 49, 57, 58, 62, 63
};
35, 36, 48, 49, 57, 58, 62, 63};
// Transposition indices
static const unsigned int TRANSPOSE_TABLE[SUBBLOCK_SIZE] = {
@ -92,24 +90,23 @@ static const unsigned int TRANSPOSE_TABLE[SUBBLOCK_SIZE] = {
4, 12, 20, 28, 36, 44, 52, 60,
5, 13, 21, 29, 37, 45, 53, 61,
6, 14, 22, 30, 38, 46, 54, 62,
7, 15, 23, 31, 39, 47, 55, 63
};
7, 15, 23, 31, 39, 47, 55, 63};
/* IDCT related constants
* Cn = alpha * cos(n * PI / 16) (alpha is chosen such as C4 = 1) */
static const float IDCT_C3 = 1.175875602f;
static const float IDCT_C6 = 0.541196100f;
static const float IDCT_K[10] = {
0.765366865f, // C2-C6
-1.847759065f, // -C2-C6
-0.390180644f, // C5-C3
-1.961570561f, // -C5-C3
1.501321110f, // C1+C3-C5-C7
2.053119869f, // C1+C3-C5+C7
3.072711027f, // C1+C3+C5-C7
0.298631336f, // -C1+C3+C5-C7
-0.899976223f, // C7-C3
-2.562915448f // -C1-C3
0.765366865f, // C2-C6
-1.847759065f, // -C2-C6
-0.390180644f, // C5-C3
-1.961570561f, // -C5-C3
1.501321110f, // C1+C3-C5-C7
2.053119869f, // C1+C3-C5+C7
3.072711027f, // C1+C3+C5-C7
0.298631336f, // -C1+C3+C5-C7
-0.899976223f, // C7-C3
-2.562915448f // -C1-C3
};
// Global functions
@ -128,7 +125,6 @@ void jpeg_decode_PS(CHle * hle)
jpeg_decode_std(hle, "PS", NULL, NULL, EmitRGBATileLine);
}
// JPEG decoding microcode found in Ogre Battle and Bottom of the 9th
void jpeg_decode_OB(CHle * hle)
@ -140,9 +136,9 @@ void jpeg_decode_OB(CHle * hle)
int32_t u_dc = 0;
int32_t v_dc = 0;
uint32_t address = *dmem_u32(hle, TASK_DATA_PTR);
uint32_t address = *dmem_u32(hle, TASK_DATA_PTR);
const unsigned int macroblock_count = *dmem_u32(hle, TASK_DATA_SIZE);
const int qscale = *dmem_u32(hle, TASK_YIELD_DATA_SIZE);
const int qscale = *dmem_u32(hle, TASK_YIELD_DATA_SIZE);
hle->VerboseMessage("jpeg_decode_OB: *buffer=%x, #MB=%d, qscale=%d", address, macroblock_count, qscale);
@ -172,7 +168,7 @@ void jpeg_decode_OB(CHle * hle)
// 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];
unsigned int mb;
@ -268,9 +264,9 @@ static uint16_t clamp_RGBA_component(int16_t x)
static uint32_t GetUYVY(int16_t y1, int16_t y2, int16_t u, int16_t v)
{
return (uint32_t)clamp_u8(u) << 24 |
(uint32_t)clamp_u8(y1) << 16 |
(uint32_t)clamp_u8(v) << 8 |
(uint32_t)clamp_u8(y2);
(uint32_t)clamp_u8(y1) << 16 |
(uint32_t)clamp_u8(v) << 8 |
(uint32_t)clamp_u8(y2);
}
static uint16_t GetRGBA(int16_t y, int16_t u, int16_t v)
@ -286,12 +282,12 @@ static uint16_t GetRGBA(int16_t y, int16_t u, int16_t v)
return (r << 4) | (g >> 1) | (b >> 6) | 1;
}
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)
{
uint32_t uyvy[8];
const int16_t *const v = u + SUBBLOCK_SIZE;
const int16_t *const y2 = y + SUBBLOCK_SIZE;
const int16_t * const v = u + SUBBLOCK_SIZE;
const int16_t * const y2 = y + SUBBLOCK_SIZE;
uyvy[0] = GetUYVY(y[0], y[1], u[0], v[0]);
uyvy[1] = GetUYVY(y[2], y[3], u[1], v[1]);
@ -305,12 +301,12 @@ static void EmitYUVTileLine(CHle * hle, const int16_t *y, const int16_t *u, uint
dram_store_u32(hle, uyvy, address, 8);
}
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)
{
uint16_t rgba[16];
const int16_t *const v = u + SUBBLOCK_SIZE;
const int16_t *const y2 = y + SUBBLOCK_SIZE;
const int16_t * const v = u + SUBBLOCK_SIZE;
const int16_t * const y2 = y + SUBBLOCK_SIZE;
rgba[0] = GetRGBA(y[0], u[0], v[0]);
rgba[1] = GetRGBA(y[1], u[0], v[0]);
@ -332,14 +328,15 @@ static void EmitRGBATileLine(CHle * hle, const int16_t *y, const int16_t *u, uin
dram_store_u16(hle, rgba, address, 16);
}
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)
{
unsigned int i;
unsigned int y_offset = 0;
unsigned int u_offset = 2 * SUBBLOCK_SIZE;
for (i = 0; i < 8; ++i) {
for (i = 0; i < 8; ++i)
{
emit_line(hle, &macroblock[y_offset], &macroblock[u_offset], address);
y_offset += 8;
@ -348,7 +345,7 @@ static void EmitTilesMode0(CHle * hle, const tile_line_emitter_t emit_line, cons
}
}
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)
{
unsigned int i;
@ -366,16 +363,18 @@ static void EmitTilesMode2(CHle * hle, const tile_line_emitter_t emit_line, cons
}
}
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)
{
int sb;
for (sb = 0; sb < 6; ++sb) {
for (sb = 0; sb < 6; ++sb)
{
int16_t tmp_sb[SUBBLOCK_SIZE];
// Update decode
int32_t dc = (int32_t)macroblock[0];
switch (sb) {
switch (sb)
{
case 0:
case 1:
case 2:
@ -406,10 +405,10 @@ static void decode_macroblock_ob(int16_t *macroblock, int32_t *y_dc, int32_t *u_
}
static void decode_macroblock_std(const subblock_transform_t transform_luma,
const subblock_transform_t transform_chroma,
int16_t *macroblock,
unsigned int subblock_count,
const int16_t qtables[3][SUBBLOCK_SIZE])
const subblock_transform_t transform_chroma,
int16_t * macroblock,
unsigned int subblock_count,
const int16_t qtables[3][SUBBLOCK_SIZE])
{
unsigned int sb;
unsigned int q = 0;
@ -446,17 +445,17 @@ static void decode_macroblock_std(const subblock_transform_t transform_luma,
}
}
static void TransposeSubBlock(int16_t *dst, const int16_t *src)
static void TransposeSubBlock(int16_t * dst, const int16_t * src)
{
ReorderSubBlock(dst, src, TRANSPOSE_TABLE);
}
static void ZigZagSubBlock(int16_t *dst, const int16_t *src)
static void ZigZagSubBlock(int16_t * dst, const int16_t * src)
{
ReorderSubBlock(dst, src, ZIGZAG_TABLE);
}
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)
{
unsigned int i;
@ -467,7 +466,7 @@ static void ReorderSubBlock(int16_t *dst, const int16_t *src, const unsigned int
dst[i] = src[table[i]];
}
static void MultSubBlocks(int16_t *dst, const int16_t *src1, const int16_t *src2, unsigned int shift)
static void MultSubBlocks(int16_t * dst, const int16_t * src1, const int16_t * src2, unsigned int shift)
{
unsigned int i;
@ -478,17 +477,18 @@ static void MultSubBlocks(int16_t *dst, const int16_t *src1, const int16_t *src2
}
}
static void ScaleSubBlock(int16_t *dst, const int16_t *src, int16_t scale)
static void ScaleSubBlock(int16_t * dst, const int16_t * src, int16_t scale)
{
unsigned int i;
for (i = 0; i < SUBBLOCK_SIZE; ++i) {
for (i = 0; i < SUBBLOCK_SIZE; ++i)
{
int32_t v = src[i] * scale;
dst[i] = clamp_s16(v);
}
}
static void RShiftSubBlock(int16_t *dst, const int16_t *src, unsigned int shift)
static void RShiftSubBlock(int16_t * dst, const int16_t * src, unsigned int shift)
{
unsigned int i;
@ -504,7 +504,7 @@ 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 f[4];
@ -514,8 +514,8 @@ static void InverseDCT1D(const float *const x, float *dst, unsigned int stride)
x37 = IDCT_K[3] * (x[3] + x[7]);
x17 = IDCT_K[8] * (x[1] + x[7]);
x35 = IDCT_K[9] * (x[3] + x[5]);
x1357 = IDCT_C3 * (x[1] + x[3] + x[5] + x[7]);
x26 = IDCT_C6 * (x[2] + x[6]);
x1357 = IDCT_C3 * (x[1] + x[3] + x[5] + x[7]);
x26 = IDCT_C6 * (x[2] + x[6]);
f[0] = x[0] + x[4];
f[1] = x[0] - x[4];
@ -544,7 +544,7 @@ static void InverseDCT1D(const float *const x, float *dst, unsigned int stride)
*dst = f[0] + f[2] - e[0];
}
static void InverseDCTSubBlock(int16_t *dst, const int16_t *src)
static void InverseDCTSubBlock(int16_t * dst, const int16_t * src)
{
float x[8];
float block[SUBBLOCK_SIZE];
@ -572,7 +572,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)
{
unsigned int i;
@ -581,7 +581,7 @@ static void RescaleYSubBlock(int16_t *dst, const int16_t *src)
dst[i] = (((uint32_t)(clamp_s12(src[i]) + 0x800) * 0xdb0) >> 16) + 0x10;
}
}
static void RescaleUVSubBlock(int16_t *dst, const int16_t *src)
static void RescaleUVSubBlock(int16_t * dst, const int16_t * src)
{
unsigned int i;

View File

@ -4,13 +4,14 @@
// Copyright(C) 2012 Bobby Smiles
// GNU/GPLv2 licensed: https://gnu.org/licenses/gpl-2.0.html
#include "stdafx.h"
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "mem.h"
// 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)
{
@ -20,7 +21,7 @@ void load_u8(uint8_t* dst, const unsigned char* buffer, unsigned address, size_t
}
}
void store_u16(unsigned char* buffer, unsigned address, const uint16_t* src, size_t count)
void store_u16(unsigned char * buffer, unsigned address, const uint16_t * src, size_t count)
{
while (count != 0)
{
@ -30,13 +31,13 @@ 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
memcpy(dst, u32(buffer, address), count * sizeof(uint32_t));
}
void load_u16(uint16_t* dst, const unsigned char* buffer, unsigned address, size_t count)
void load_u16(uint16_t * dst, const unsigned char * buffer, unsigned address, size_t count)
{
while (count != 0)
{
@ -46,7 +47,7 @@ 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
memcpy(u32(buffer, address), src, count * sizeof(uint32_t));

View File

@ -0,0 +1,113 @@
// Project64 - A Nintendo 64 emulator
// https://www.pj64-emu.com/
// Copyright(C) 2001-2021 Project64
// Copyright(C) 2014 Bobby Smiles
// GNU/GPLv2 licensed: https://gnu.org/licenses/gpl-2.0.html
#pragma once
#include "hle.h"
#include <assert.h>
#define S 1
#define S16 2
#define S8 3
enum
{
TASK_TYPE = 0xfc0,
TASK_FLAGS = 0xfc4,
TASK_UCODE_BOOT = 0xfc8,
TASK_UCODE_BOOT_SIZE = 0xfcc,
TASK_UCODE = 0xfd0,
TASK_UCODE_SIZE = 0xfd4,
TASK_UCODE_DATA = 0xfd8,
TASK_UCODE_DATA_SIZE = 0xfdc,
TASK_DRAM_STACK = 0xfe0,
TASK_DRAM_STACK_SIZE = 0xfe4,
TASK_OUTPUT_BUFF = 0xfe8,
TASK_OUTPUT_BUFF_SIZE = 0xfec,
TASK_DATA_PTR = 0xff0,
TASK_DATA_SIZE = 0xff4,
TASK_YIELD_DATA_PTR = 0xff8,
TASK_YIELD_DATA_SIZE = 0xffc
};
static inline unsigned int align(unsigned int x, unsigned amount)
{
--amount;
return (x + amount) & ~amount;
}
static inline uint8_t * u8(const unsigned char * buffer, unsigned address)
{
return (uint8_t *)(buffer + (address ^ S8));
}
static inline uint16_t * u16(const unsigned char * buffer, unsigned address)
{
assert((address & 1) == 0);
return (uint16_t *)(buffer + (address ^ S16));
}
static inline uint32_t * u32(const unsigned char * buffer, unsigned address)
{
assert((address & 3) == 0);
return (uint32_t *)(buffer + address);
}
void load_u8(uint8_t * dst, const unsigned char * buffer, unsigned address, size_t count);
void load_u16(uint16_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);
void store_u16(unsigned char * buffer, unsigned address, const uint16_t * src, size_t count);
void store_u32(unsigned char * buffer, unsigned address, const uint32_t * src, size_t count);
static inline uint32_t * dmem_u32(CHle * hle, uint16_t address)
{
return u32(hle->dmem(), address & 0xfff);
}
static inline void dmem_store_u32(CHle * hle, const uint32_t * src, uint16_t address, size_t count)
{
store_u32(hle->dmem(), address & 0xfff, src, count);
}
// Convenient functions DRAM access
static inline uint8_t * dram_u8(CHle * hle, uint32_t address)
{
return u8(hle->dram(), address & 0xffffff);
}
static inline uint16_t * dram_u16(CHle * hle, uint32_t address)
{
return u16(hle->dram(), address & 0xffffff);
}
static inline uint32_t * dram_u32(CHle * hle, uint32_t address)
{
return u32(hle->dram(), address & 0xffffff);
}
static inline void dram_load_u8(CHle * hle, uint8_t * dst, uint32_t address, size_t count)
{
load_u8(dst, hle->dram(), address & 0xffffff, count);
}
static inline void dram_load_u16(CHle * hle, uint16_t * dst, uint32_t address, size_t count)
{
load_u16(dst, hle->dram(), address & 0xffffff, count);
}
static inline void dram_load_u32(CHle * hle, uint32_t * dst, uint32_t address, size_t count)
{
load_u32(dst, hle->dram(), address & 0xffffff, count);
}
static inline void dram_store_u16(CHle * hle, const uint16_t * src, uint32_t address, size_t count)
{
store_u16(hle->dram(), address & 0xffffff, src, count);
}
static inline void dram_store_u32(CHle * hle, const uint32_t * src, uint32_t address, size_t count)
{
store_u32(hle->dram(), address & 0xffffff, src, count);
}

View File

@ -6,7 +6,7 @@
// Copyright(C) 2002 Hacktarux
// GNU/GPLv2 licensed: https://gnu.org/licenses/gpl-2.0.html
#include "stdafx.h"
#include <stdint.h>
#include <string.h>
#include "arithmetics.h"
@ -14,7 +14,7 @@
static void InnerLoop(CHle * hle, uint32_t outPtr, uint32_t inPtr, uint32_t t6, uint32_t t5, uint32_t t4);
static const uint16_t DeWindowLUT [0x420] = {
static const uint16_t DeWindowLUT[0x420] = {
0x0000, 0xFFF3, 0x005D, 0xFF38, 0x037A, 0xF736, 0x0B37, 0xC00E,
0x7FFF, 0x3FF2, 0x0B37, 0x08CA, 0x037A, 0x00C8, 0x005D, 0x000D,
0x0000, 0xFFF3, 0x005D, 0xFF38, 0x037A, 0xF736, 0x0B37, 0xC00E,
@ -146,18 +146,16 @@ static const uint16_t DeWindowLUT [0x420] = {
0x005D, 0x00C8, 0x037A, 0x08CA, 0x0B37, 0x3FF2, 0x7FFF, 0xC00E,
0x0B37, 0xF736, 0x037A, 0xFF38, 0x005D, 0xFFF3, 0x0000, 0x000D,
0x005D, 0x00C8, 0x037A, 0x08CA, 0x0B37, 0x3FF2, 0x7FFF, 0xC00E,
0x0B37, 0xF736, 0x037A, 0xFF38, 0x005D, 0xFFF3, 0x0000, 0x0000
};
0x0B37, 0xF736, 0x037A, 0xFF38, 0x005D, 0xFFF3, 0x0000, 0x0000};
static void MP3AB0(int32_t* v)
static void MP3AB0(int32_t * v)
{
// Part 2 - 100% accurate
static const uint16_t LUT2[8] =
{
0xFEC4, 0xF4FA, 0xC5E4, 0xE1C4,
0x1916, 0x4A50, 0xA268, 0x78AE
};
static const uint16_t LUT3[4] = { 0xFB14, 0xD4DC, 0x31F2, 0x8E3A };
{
0xFEC4, 0xF4FA, 0xC5E4, 0xE1C4,
0x1916, 0x4A50, 0xA268, 0x78AE};
static const uint16_t LUT3[4] = {0xFB14, 0xD4DC, 0x31F2, 0x8E3A};
int i;
for (i = 0; i < 8; i++)
@ -170,10 +168,10 @@ static void MP3AB0(int32_t* v)
for (i = 0; i < 4; i++)
{
v[0 + i] = v[16 + i] + v[20 + i];
v[4 + i] = ((v[16 + i] - v[20 + i]) * LUT3[i]) >> 0x10;
v[0 + i] = v[16 + i] + v[20 + i];
v[4 + i] = ((v[16 + i] - v[20 + i]) * LUT3[i]) >> 0x10;
v[8 + i] = v[24 + i] + v[28 + i];
v[8 + i] = v[24 + i] + v[28 + i];
v[12 + i] = ((v[24 + i] - v[28 + i]) * LUT3[i]) >> 0x10;
}
@ -192,12 +190,12 @@ static void MP3AB0(int32_t* v)
void mp3_task(CHle * hle, unsigned int index, uint32_t address)
{
uint32_t inPtr, outPtr;
uint32_t t6;// = 0x08A0; - I think these are temporary storage buffers
uint32_t t5;// = 0x0AC0;
uint32_t t4;// = (w1 & 0x1E);
uint32_t t6; // = 0x08A0; - I think these are temporary storage buffers
uint32_t t5; // = 0x0AC0;
uint32_t t4; // = (w1 & 0x1E);
// Initialization code
uint32_t readPtr; // S5
uint32_t readPtr; // S5
uint32_t writePtr; // S6
uint32_t tmp;
int cnt, cnt2;
@ -217,7 +215,7 @@ void mp3_task(CHle * hle, unsigned int index, uint32_t address)
{
// DMA: 0xCF0 <- RDRAM[s5] : 0x180
memcpy(hle->mp3_buffer() + 0xCF0, hle->dram() + readPtr, 0x180);
inPtr = 0xCF0; // S7
inPtr = 0xCF0; // S7
outPtr = 0xE70; // S3
// Inner loop start
for (cnt2 = 0; cnt2 < 0x180; cnt2 += 0x40)
@ -237,7 +235,7 @@ void mp3_task(CHle * hle, unsigned int index, uint32_t address)
// Inner loop end
memcpy(hle->dram() + writePtr, hle->mp3_buffer() + 0xe70, 0x180);
writePtr += 0x180;
readPtr += 0x180;
readPtr += 0x180;
}
}
@ -247,12 +245,11 @@ static void InnerLoop(CHle * hle, uint32_t outPtr, uint32_t inPtr, uint32_t t6,
// 0, 1, 3, 2, 7, 6, 4, 5, 7, 6, 4, 5, 0, 1, 3, 2
static const uint16_t LUT6[16] =
{
0xFFB2, 0xFD3A, 0xF10A, 0xF854,
0xBDAE, 0xCDA0, 0xE76C, 0xDB94,
0x1920, 0x4B20, 0xAC7C, 0x7C68,
0xABEC, 0x9880, 0xDAE8, 0x839C
};
{
0xFFB2, 0xFD3A, 0xF10A, 0xF854,
0xBDAE, 0xCDA0, 0xE76C, 0xDB94,
0x1920, 0x4B20, 0xAC7C, 0x7C68,
0xABEC, 0x9880, 0xDAE8, 0x839C};
int i;
uint32_t t0;
uint32_t t1;
@ -351,7 +348,7 @@ static void InnerLoop(CHle * hle, uint32_t outPtr, uint32_t inPtr, uint32_t t6,
v[2] = -v[2];
// ** Store v[2] -> (T2 + 0)**
*(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)**
*(int16_t *)(hle->mp3_buffer() + ((t0 + (short)0x0))) = (short)v[3];
// 0x1400 - Verified...
@ -497,7 +494,7 @@ static void InnerLoop(CHle * hle, uint32_t outPtr, uint32_t inPtr, uint32_t t6,
v[7] = (((v[22] - v[23]) * 0x2D413) >> 0x10) + v[0] + v[1] + v[3];
// 0x16A8
// 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[9] = ((v[24] - v[25]) * 0x16A09) >> 0x10;
v[10] = ((v[26] + v[27]) << 1) + v[8];
@ -571,20 +568,20 @@ static void InnerLoop(CHle * hle, uint32_t outPtr, uint32_t inPtr, uint32_t t6,
for (i = 7; i >= 0; i--)
{
v2 += ((int) * (int16_t *)(hle->mp3_buffer() + (addptr) + 0x00) * (short)DeWindowLUT[offset + 0x00] + 0x4000) >> 0xF;
v4 += ((int) * (int16_t *)(hle->mp3_buffer() + (addptr) + 0x10) * (short)DeWindowLUT[offset + 0x08] + 0x4000) >> 0xF;
v6 += ((int) * (int16_t *)(hle->mp3_buffer() + (addptr) + 0x20) * (short)DeWindowLUT[offset + 0x20] + 0x4000) >> 0xF;
v8 += ((int) * (int16_t *)(hle->mp3_buffer() + (addptr) + 0x30) * (short)DeWindowLUT[offset + 0x28] + 0x4000) >> 0xF;
v2 += ((int)*(int16_t *)(hle->mp3_buffer() + (addptr) + 0x00) * (short)DeWindowLUT[offset + 0x00] + 0x4000) >> 0xF;
v4 += ((int)*(int16_t *)(hle->mp3_buffer() + (addptr) + 0x10) * (short)DeWindowLUT[offset + 0x08] + 0x4000) >> 0xF;
v6 += ((int)*(int16_t *)(hle->mp3_buffer() + (addptr) + 0x20) * (short)DeWindowLUT[offset + 0x20] + 0x4000) >> 0xF;
v8 += ((int)*(int16_t *)(hle->mp3_buffer() + (addptr) + 0x30) * (short)DeWindowLUT[offset + 0x28] + 0x4000) >> 0xF;
addptr += 2;
offset++;
}
v0 = v2 + v4;
v0 = v2 + v4;
v18 = v6 + v8;
// Clamp(v0);
// Clamp(v18);
// Clamp?
*(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;
addptr += 0x30;
offset += 0x38;
@ -594,12 +591,12 @@ static void InnerLoop(CHle * hle, uint32_t outPtr, uint32_t inPtr, uint32_t t6,
v2 = v4 = 0;
for (i = 0; i < 4; i++)
{
v2 += ((int) * (int16_t *)(hle->mp3_buffer() + (addptr) + 0x00) * (short)DeWindowLUT[offset + 0x00] + 0x4000) >> 0xF;
v2 += ((int) * (int16_t *)(hle->mp3_buffer() + (addptr) + 0x10) * (short)DeWindowLUT[offset + 0x08] + 0x4000) >> 0xF;
v2 += ((int)*(int16_t *)(hle->mp3_buffer() + (addptr) + 0x00) * (short)DeWindowLUT[offset + 0x00] + 0x4000) >> 0xF;
v2 += ((int)*(int16_t *)(hle->mp3_buffer() + (addptr) + 0x10) * (short)DeWindowLUT[offset + 0x08] + 0x4000) >> 0xF;
addptr += 2;
offset++;
v4 += ((int) * (int16_t *)(hle->mp3_buffer() + (addptr) + 0x00) * (short)DeWindowLUT[offset + 0x00] + 0x4000) >> 0xF;
v4 += ((int) * (int16_t *)(hle->mp3_buffer() + (addptr) + 0x10) * (short)DeWindowLUT[offset + 0x08] + 0x4000) >> 0xF;
v4 += ((int)*(int16_t *)(hle->mp3_buffer() + (addptr) + 0x00) * (short)DeWindowLUT[offset + 0x00] + 0x4000) >> 0xF;
v4 += ((int)*(int16_t *)(hle->mp3_buffer() + (addptr) + 0x10) * (short)DeWindowLUT[offset + 0x08] + 0x4000) >> 0xF;
addptr += 2;
offset++;
}
@ -607,12 +604,12 @@ static void InnerLoop(CHle * hle, uint32_t outPtr, uint32_t inPtr, uint32_t t6,
mult4 = *(int32_t *)(hle->mp3_buffer() + 0xCEC);
if (t4 & 0x2)
{
v2 = (v2 **(uint32_t *)(hle->mp3_buffer() + 0xCE8)) >> 0x10;
v2 = (v2 * *(uint32_t *)(hle->mp3_buffer() + 0xCE8)) >> 0x10;
*(int16_t *)(hle->mp3_buffer() + (outPtr ^ S16)) = v2;
}
else
{
v4 = (v4 **(uint32_t *)(hle->mp3_buffer() + 0xCE8)) >> 0x10;
v4 = (v4 * *(uint32_t *)(hle->mp3_buffer() + 0xCE8)) >> 0x10;
*(int16_t *)(hle->mp3_buffer() + (outPtr ^ S16)) = v4;
mult4 = *(uint32_t *)(hle->mp3_buffer() + 0xCE8);
}
@ -628,24 +625,24 @@ static void InnerLoop(CHle * hle, uint32_t outPtr, uint32_t inPtr, uint32_t t6,
for (i = 0; i < 4; i++)
{
v2 += ((int) * (int16_t *)(hle->mp3_buffer() + (addptr) + 0x20) * (short)DeWindowLUT[offset + 0x00] + 0x4000) >> 0xF;
v2 -= ((int) * (int16_t *)(hle->mp3_buffer() + ((addptr + 2)) + 0x20) * (short)DeWindowLUT[offset + 0x01] + 0x4000) >> 0xF;
v4 += ((int) * (int16_t *)(hle->mp3_buffer() + (addptr) + 0x30) * (short)DeWindowLUT[offset + 0x08] + 0x4000) >> 0xF;
v4 -= ((int) * (int16_t *)(hle->mp3_buffer() + ((addptr + 2)) + 0x30) * (short)DeWindowLUT[offset + 0x09] + 0x4000) >> 0xF;
v6 += ((int) * (int16_t *)(hle->mp3_buffer() + (addptr) + 0x00) * (short)DeWindowLUT[offset + 0x20] + 0x4000) >> 0xF;
v6 -= ((int) * (int16_t *)(hle->mp3_buffer() + ((addptr + 2)) + 0x00) * (short)DeWindowLUT[offset + 0x21] + 0x4000) >> 0xF;
v8 += ((int) * (int16_t *)(hle->mp3_buffer() + (addptr) + 0x10) * (short)DeWindowLUT[offset + 0x28] + 0x4000) >> 0xF;
v8 -= ((int) * (int16_t *)(hle->mp3_buffer() + ((addptr + 2)) + 0x10) * (short)DeWindowLUT[offset + 0x29] + 0x4000) >> 0xF;
v2 += ((int)*(int16_t *)(hle->mp3_buffer() + (addptr) + 0x20) * (short)DeWindowLUT[offset + 0x00] + 0x4000) >> 0xF;
v2 -= ((int)*(int16_t *)(hle->mp3_buffer() + ((addptr + 2)) + 0x20) * (short)DeWindowLUT[offset + 0x01] + 0x4000) >> 0xF;
v4 += ((int)*(int16_t *)(hle->mp3_buffer() + (addptr) + 0x30) * (short)DeWindowLUT[offset + 0x08] + 0x4000) >> 0xF;
v4 -= ((int)*(int16_t *)(hle->mp3_buffer() + ((addptr + 2)) + 0x30) * (short)DeWindowLUT[offset + 0x09] + 0x4000) >> 0xF;
v6 += ((int)*(int16_t *)(hle->mp3_buffer() + (addptr) + 0x00) * (short)DeWindowLUT[offset + 0x20] + 0x4000) >> 0xF;
v6 -= ((int)*(int16_t *)(hle->mp3_buffer() + ((addptr + 2)) + 0x00) * (short)DeWindowLUT[offset + 0x21] + 0x4000) >> 0xF;
v8 += ((int)*(int16_t *)(hle->mp3_buffer() + (addptr) + 0x10) * (short)DeWindowLUT[offset + 0x28] + 0x4000) >> 0xF;
v8 -= ((int)*(int16_t *)(hle->mp3_buffer() + ((addptr + 2)) + 0x10) * (short)DeWindowLUT[offset + 0x29] + 0x4000) >> 0xF;
addptr += 4;
offset += 2;
}
v0 = v2 + v4;
v0 = v2 + v4;
v18 = v6 + v8;
// Clamp(v0);
// Clamp(v18);
// Clamp?
*(int16_t *)(hle->mp3_buffer() + ((outPtr + 2)^S16)) = v0;
*(int16_t *)(hle->mp3_buffer() + ((outPtr + 4)^S16)) = v18;
*(int16_t *)(hle->mp3_buffer() + ((outPtr + 2) ^ S16)) = v0;
*(int16_t *)(hle->mp3_buffer() + ((outPtr + 4) ^ S16)) = v18;
outPtr += 4;
addptr -= 0x50;
}
@ -659,20 +656,20 @@ static void InnerLoop(CHle * hle, uint32_t outPtr, uint32_t inPtr, uint32_t t6,
for (i = 0; i < 8; i++)
{
// v0
vt = (*(int16_t *)(hle->mp3_buffer() + ((tmp - 0x40)^S16)) * hi0);
*(int16_t *)((uint8_t *)hle->mp3_buffer() + ((tmp - 0x40)^S16)) = clamp_s16(vt);
vt = (*(int16_t *)(hle->mp3_buffer() + ((tmp - 0x40) ^ S16)) * hi0);
*(int16_t *)((uint8_t *)hle->mp3_buffer() + ((tmp - 0x40) ^ S16)) = clamp_s16(vt);
// v17
vt = (*(int16_t *)(hle->mp3_buffer() + ((tmp - 0x30)^S16)) * hi0);
*(int16_t *)((uint8_t *)hle->mp3_buffer() + ((tmp - 0x30)^S16)) = clamp_s16(vt);
vt = (*(int16_t *)(hle->mp3_buffer() + ((tmp - 0x30) ^ S16)) * hi0);
*(int16_t *)((uint8_t *)hle->mp3_buffer() + ((tmp - 0x30) ^ S16)) = clamp_s16(vt);
// v2
vt = (*(int16_t *)(hle->mp3_buffer() + ((tmp - 0x1E)^S16)) * hi1);
*(int16_t *)((uint8_t *)hle->mp3_buffer() + ((tmp - 0x1E)^S16)) = clamp_s16(vt);
vt = (*(int16_t *)(hle->mp3_buffer() + ((tmp - 0x1E) ^ S16)) * hi1);
*(int16_t *)((uint8_t *)hle->mp3_buffer() + ((tmp - 0x1E) ^ S16)) = clamp_s16(vt);
// v4
vt = (*(int16_t *)(hle->mp3_buffer() + ((tmp - 0xE)^S16)) * hi1);
*(int16_t *)((uint8_t *)hle->mp3_buffer() + ((tmp - 0xE)^S16)) = clamp_s16(vt);
vt = (*(int16_t *)(hle->mp3_buffer() + ((tmp - 0xE) ^ S16)) * hi1);
*(int16_t *)((uint8_t *)hle->mp3_buffer() + ((tmp - 0xE) ^ S16)) = clamp_s16(vt);
tmp += 2;
}

View File

@ -4,7 +4,7 @@
// Copyright(C) 2013 Bobby Smiles
// GNU/GPLv2 licensed: https://gnu.org/licenses/gpl-2.0.html
#include "stdafx.h"
#include <stdint.h>
#include <string.h>
#include "arithmetics.h"
@ -13,86 +13,95 @@
// Various constants
enum { SUBFRAME_SIZE = 192 };
enum { MAX_VOICES = 32 };
enum { SAMPLE_BUFFER_SIZE = 0x200 };
enum
{
SUBFRAME_SIZE = 192
};
enum
{
MAX_VOICES = 32
};
enum
{
SFD_SFX_INDEX = 0x2,
SFD_VOICE_BITMASK = 0x4,
SFD_STATE_PTR = 0x8,
SFD_SFX_PTR = 0xc,
SFD_VOICES = 0x10,
SAMPLE_BUFFER_SIZE = 0x200
};
enum
{
SFD_SFX_INDEX = 0x2,
SFD_VOICE_BITMASK = 0x4,
SFD_STATE_PTR = 0x8,
SFD_SFX_PTR = 0xc,
SFD_VOICES = 0x10,
// v2 only
SFD2_10_PTR = 0x10,
SFD2_14_BITMASK = 0x14,
SFD2_15_BITMASK = 0x15,
SFD2_16_BITMASK = 0x16,
SFD2_18_PTR = 0x18,
SFD2_1C_PTR = 0x1c,
SFD2_20_PTR = 0x20,
SFD2_24_PTR = 0x24,
SFD2_VOICES = 0x28
SFD2_10_PTR = 0x10,
SFD2_14_BITMASK = 0x14,
SFD2_15_BITMASK = 0x15,
SFD2_16_BITMASK = 0x16,
SFD2_18_PTR = 0x18,
SFD2_1C_PTR = 0x1c,
SFD2_20_PTR = 0x20,
SFD2_24_PTR = 0x24,
SFD2_VOICES = 0x28
};
enum
{
VOICE_ENV_BEGIN = 0x00,
VOICE_ENV_STEP = 0x10,
VOICE_PITCH_Q16 = 0x20,
VOICE_PITCH_SHIFT = 0x22,
VOICE_CATSRC_0 = 0x24,
VOICE_CATSRC_1 = 0x30,
VOICE_ADPCM_FRAMES = 0x3c,
VOICE_SKIP_SAMPLES = 0x3e,
VOICE_ENV_BEGIN = 0x00,
VOICE_ENV_STEP = 0x10,
VOICE_PITCH_Q16 = 0x20,
VOICE_PITCH_SHIFT = 0x22,
VOICE_CATSRC_0 = 0x24,
VOICE_CATSRC_1 = 0x30,
VOICE_ADPCM_FRAMES = 0x3c,
VOICE_SKIP_SAMPLES = 0x3e,
// For PCM16
VOICE_U16_40 = 0x40,
VOICE_U16_42 = 0x42,
VOICE_U16_40 = 0x40,
VOICE_U16_42 = 0x42,
// For ADPCM
VOICE_ADPCM_TABLE_PTR = 0x40,
VOICE_ADPCM_TABLE_PTR = 0x40,
VOICE_INTERLEAVED_PTR = 0x44,
VOICE_END_POINT = 0x48,
VOICE_RESTART_POINT = 0x4a,
VOICE_U16_4E = 0x4e,
VOICE_INTERLEAVED_PTR = 0x44,
VOICE_END_POINT = 0x48,
VOICE_RESTART_POINT = 0x4a,
VOICE_U16_4E = 0x4e,
VOICE_SIZE = 0x50
VOICE_SIZE = 0x50
};
enum
{
CATSRC_PTR1 = 0x00,
CATSRC_PTR2 = 0x04,
CATSRC_SIZE1 = 0x08,
CATSRC_SIZE2 = 0x0a
CATSRC_PTR1 = 0x00,
CATSRC_PTR2 = 0x04,
CATSRC_SIZE1 = 0x08,
CATSRC_SIZE2 = 0x0a
};
enum
{
STATE_LAST_SAMPLE = 0x0,
STATE_BASE_VOL = 0x100,
STATE_CC0 = 0x110,
STATE_740_LAST4_V1 = 0x290,
STATE_LAST_SAMPLE = 0x0,
STATE_BASE_VOL = 0x100,
STATE_CC0 = 0x110,
STATE_740_LAST4_V1 = 0x290,
STATE_740_LAST4_V2 = 0x110
STATE_740_LAST4_V2 = 0x110
};
enum
{
SFX_CBUFFER_PTR = 0x00,
SFX_CBUFFER_LENGTH = 0x04,
SFX_TAP_COUNT = 0x08,
SFX_FIR4_HGAIN = 0x0a,
SFX_TAP_DELAYS = 0x0c,
SFX_TAP_GAINS = 0x2c,
SFX_U16_3C = 0x3c,
SFX_U16_3E = 0x3e,
SFX_FIR4_HCOEFFS = 0x40
SFX_CBUFFER_PTR = 0x00,
SFX_CBUFFER_LENGTH = 0x04,
SFX_TAP_COUNT = 0x08,
SFX_FIR4_HGAIN = 0x0a,
SFX_TAP_DELAYS = 0x0c,
SFX_TAP_GAINS = 0x2c,
SFX_U16_3C = 0x3c,
SFX_U16_3E = 0x3e,
SFX_FIR4_HCOEFFS = 0x40
};
// Struct definition
@ -112,38 +121,38 @@ typedef struct
int16_t subframe_740_last4[4];
} 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
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 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 init_subframes_v1(musyx_t *musyx);
static void init_subframes_v2(musyx_t *musyx);
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 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 init_subframes_v1(musyx_t * musyx);
static void init_subframes_v2(musyx_t * musyx);
static uint32_t voice_stage(CHle * hle, musyx_t *musyx, uint32_t voice_ptr, uint32_t last_sample_ptr);
static void dma_cat8(CHle * hle, uint8_t *dst, uint32_t catsrc_ptr);
static void dma_cat16(CHle * hle, uint16_t *dst, uint32_t catsrc_ptr);
static void sfx_stage(CHle * hle, mix_sfx_with_main_subframes_t mix_sfx_with_main_subframes, musyx_t *musyx, uint32_t sfx_ptr, uint16_t idx);
static void load_samples_PCM16(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);
static void mix_voice_samples(CHle * hle, musyx_t *musyx, uint32_t voice_ptr, const int16_t *samples, unsigned segbase, unsigned offset, uint32_t last_sample_ptr);
static void adpcm_decode_frames(CHle * hle, int16_t *dst, const uint8_t *src, const int16_t *table, uint8_t count, uint8_t skip_samples);
static void adpcm_predict_frame(int16_t *dst, const uint8_t *src, const uint8_t *nibbles, unsigned int rshift);
static uint32_t voice_stage(CHle * hle, musyx_t * musyx, uint32_t voice_ptr, uint32_t last_sample_ptr);
static void dma_cat8(CHle * hle, uint8_t * dst, uint32_t catsrc_ptr);
static void dma_cat16(CHle * hle, uint16_t * dst, uint32_t catsrc_ptr);
static void sfx_stage(CHle * hle, mix_sfx_with_main_subframes_t mix_sfx_with_main_subframes, musyx_t * musyx, uint32_t sfx_ptr, uint16_t idx);
static void load_samples_PCM16(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);
static void mix_voice_samples(CHle * hle, musyx_t * musyx, uint32_t voice_ptr, const int16_t * samples, unsigned segbase, unsigned offset, uint32_t last_sample_ptr);
static void adpcm_decode_frames(CHle * hle, int16_t * dst, const uint8_t * src, const int16_t * table, uint8_t count, uint8_t skip_samples);
static void adpcm_predict_frame(int16_t * dst, const uint8_t * src, const uint8_t * nibbles, unsigned int rshift);
static void mix_sfx_with_main_subframes_v1(musyx_t *musyx, const int16_t *subframe, const uint16_t* gains);
static void mix_sfx_with_main_subframes_v2(musyx_t *musyx, const int16_t *subframe, const uint16_t* gains);
static void mix_sfx_with_main_subframes_v1(musyx_t * musyx, const int16_t * subframe, const uint16_t * gains);
static void mix_sfx_with_main_subframes_v2(musyx_t * musyx, const int16_t * subframe, const uint16_t * gains);
static void mix_samples(int16_t *y, int16_t x, int16_t hgain);
static void mix_subframes(int16_t *y, const int16_t *x, int16_t hgain);
static void mix_fir4(int16_t *y, const int16_t *x, int16_t hgain, const int16_t *hcoeffs);
static void mix_samples(int16_t * y, int16_t x, int16_t hgain);
static void mix_subframes(int16_t * y, const int16_t * x, int16_t hgain);
static void mix_fir4(int16_t * y, const int16_t * x, int16_t hgain, const int16_t * hcoeffs);
static void interleave_stage_v1(CHle * hle, musyx_t *musyx, uint32_t output_ptr);
static void interleave_stage_v1(CHle * hle, musyx_t * musyx, uint32_t output_ptr);
static void interleave_stage_v2(CHle * hle, musyx_t *musyx, uint16_t mask_16, uint32_t ptr_18, uint32_t ptr_1c, uint32_t output_ptr);
static void interleave_stage_v2(CHle * hle, musyx_t * musyx, uint16_t mask_16, uint32_t ptr_18, uint32_t ptr_1c, uint32_t output_ptr);
static int32_t dot4(const int16_t *x, const int16_t *y)
static int32_t dot4(const int16_t * x, const int16_t * y)
{
int32_t accu = 0;
@ -158,12 +167,12 @@ static int32_t dot4(const int16_t *x, const int16_t *y)
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);
uint32_t sfd_count = *dmem_u32(hle, TASK_DATA_SIZE);
uint32_t state_ptr;
musyx_t musyx;
hle->VerboseMessage("musyx_v1_task: *data=%x, #SF=%d", sfd_ptr,sfd_count);
hle->VerboseMessage("musyx_v1_task: *data=%x, #SF=%d", sfd_ptr, sfd_count);
state_ptr = *dram_u32(hle, sfd_ptr + SFD_STATE_PTR);
@ -175,10 +184,10 @@ void musyx_v1_task(CHle * hle)
for (;;)
{
// Parse SFD structure
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 sfx_ptr = *dram_u32(hle, sfd_ptr + SFD_SFX_PTR);
uint32_t voice_ptr = sfd_ptr + SFD_VOICES;
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 sfx_ptr = *dram_u32(hle, sfd_ptr + SFD_SFX_PTR);
uint32_t voice_ptr = sfd_ptr + SFD_VOICES;
uint32_t last_sample_ptr = state_ptr + STATE_LAST_SAMPLE;
uint32_t output_ptr;
@ -215,7 +224,7 @@ void musyx_v1_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);
uint32_t sfd_count = *dmem_u32(hle, TASK_DATA_SIZE);
musyx_t musyx;
@ -224,20 +233,20 @@ void musyx_v2_task(CHle * hle)
for (;;)
{
// Parse SFD structure
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 state_ptr = *dram_u32(hle, sfd_ptr + SFD_STATE_PTR);
uint32_t sfx_ptr = *dram_u32(hle, sfd_ptr + SFD_SFX_PTR);
uint32_t voice_ptr = sfd_ptr + SFD2_VOICES;
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 state_ptr = *dram_u32(hle, sfd_ptr + SFD_STATE_PTR);
uint32_t sfx_ptr = *dram_u32(hle, sfd_ptr + SFD_SFX_PTR);
uint32_t voice_ptr = sfd_ptr + SFD2_VOICES;
uint32_t ptr_10 = *dram_u32(hle, sfd_ptr + SFD2_10_PTR);
uint8_t mask_14 = *dram_u8 (hle, sfd_ptr + SFD2_14_BITMASK);
uint8_t mask_15 = *dram_u8 (hle, sfd_ptr + SFD2_15_BITMASK);
uint16_t mask_16 = *dram_u16(hle, sfd_ptr + SFD2_16_BITMASK);
uint32_t ptr_18 = *dram_u32(hle, sfd_ptr + SFD2_18_PTR);
uint32_t ptr_1c = *dram_u32(hle, sfd_ptr + SFD2_1C_PTR);
uint32_t ptr_20 = *dram_u32(hle, sfd_ptr + SFD2_20_PTR);
uint32_t ptr_24 = *dram_u32(hle, sfd_ptr + SFD2_24_PTR);
uint32_t ptr_10 = *dram_u32(hle, sfd_ptr + SFD2_10_PTR);
uint8_t mask_14 = *dram_u8(hle, sfd_ptr + SFD2_14_BITMASK);
uint8_t mask_15 = *dram_u8(hle, sfd_ptr + SFD2_15_BITMASK);
uint16_t mask_16 = *dram_u16(hle, sfd_ptr + SFD2_16_BITMASK);
uint32_t ptr_18 = *dram_u32(hle, sfd_ptr + SFD2_18_PTR);
uint32_t ptr_1c = *dram_u32(hle, sfd_ptr + SFD2_1C_PTR);
uint32_t ptr_20 = *dram_u32(hle, sfd_ptr + SFD2_20_PTR);
uint32_t ptr_24 = *dram_u32(hle, sfd_ptr + SFD2_24_PTR);
uint32_t last_sample_ptr = state_ptr + STATE_LAST_SAMPLE;
uint32_t output_ptr;
@ -261,13 +270,13 @@ void musyx_v2_task(CHle * hle)
// Apply delay-based effects (optional)
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.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.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.cc0, output_ptr + 4 * SUBFRAME_SIZE, SUBFRAME_SIZE);
// Store state
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);
if (mask_16)
{
@ -284,15 +293,15 @@ void musyx_v2_task(CHle * hle)
}
}
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)
{
base_vol[0] = ((uint32_t)(*dram_u16(hle, address)) << 16) | (*dram_u16(hle, address + 8));
base_vol[0] = ((uint32_t)(*dram_u16(hle, address)) << 16) | (*dram_u16(hle, address + 8));
base_vol[1] = ((uint32_t)(*dram_u16(hle, address + 2)) << 16) | (*dram_u16(hle, address + 10));
base_vol[2] = ((uint32_t)(*dram_u16(hle, address + 4)) << 16) | (*dram_u16(hle, address + 12));
base_vol[3] = ((uint32_t)(*dram_u16(hle, address + 6)) << 16) | (*dram_u16(hle, address + 14));
}
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)
{
unsigned k;
@ -309,7 +318,7 @@ 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,
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)
{
@ -339,14 +348,14 @@ static void update_base_vol(CHle * hle, int32_t *base_vol,
// Optimization: skip contributions entirely if mask_15 is empty
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)
{
if ((mask_15 & mask) == 0)
{
continue;
}
for(k = 0; k < 4; ++k)
for (k = 0; k < 4; ++k)
{
base_vol[k] += (int16_t)*dram_u16(hle, ptr_24 + k * 2);
}
@ -361,34 +370,34 @@ static void update_base_vol(CHle * hle, int32_t *base_vol,
hle->VerboseMessage("AFTER: base_vol = %08x %08x %08x %08x", base_vol[0], base_vol[1], base_vol[2], base_vol[3]);
}
static void init_subframes_v1(musyx_t *musyx)
static void init_subframes_v1(musyx_t * musyx)
{
unsigned i;
int16_t base_cc0 = clamp_s16(musyx->base_vol[2]);
int16_t base_e50 = clamp_s16(musyx->base_vol[3]);
int16_t *left = musyx->left;
int16_t *right = musyx->right;
int16_t *cc0 = musyx->cc0;
int16_t *e50 = musyx->e50;
int16_t * left = musyx->left;
int16_t * right = musyx->right;
int16_t * cc0 = musyx->cc0;
int16_t * e50 = musyx->e50;
for (i = 0; i < SUBFRAME_SIZE; ++i)
{
*(e50++) = base_e50;
*(left++) = clamp_s16(*cc0 + base_cc0);
*(right++) = clamp_s16(-*cc0 - base_cc0);
*(cc0++) = 0;
*(e50++) = base_e50;
*(left++) = clamp_s16(*cc0 + base_cc0);
*(right++) = clamp_s16(-*cc0 - base_cc0);
*(cc0++) = 0;
}
}
static void init_subframes_v2(musyx_t *musyx)
static void init_subframes_v2(musyx_t * musyx)
{
unsigned i,k;
unsigned i, k;
int16_t values[4];
int16_t* subframes[4];
int16_t * subframes[4];
for(k = 0; k < 4; ++k)
for (k = 0; k < 4; ++k)
{
values[k] = clamp_s16(musyx->base_vol[k]);
}
@ -400,7 +409,7 @@ static void init_subframes_v2(musyx_t *musyx)
for (i = 0; i < SUBFRAME_SIZE; ++i)
{
for(k = 0; k < 4; ++k)
for (k = 0; k < 4; ++k)
{
*(subframes[k]++) = values[k];
}
@ -409,7 +418,7 @@ static void init_subframes_v2(musyx_t *musyx)
// 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;
int i = 0;
@ -460,10 +469,10 @@ static uint32_t voice_stage(CHle * hle, musyx_t *musyx, uint32_t voice_ptr, uint
return output_ptr;
}
static void dma_cat8(CHle * hle, uint8_t *dst, uint32_t catsrc_ptr)
static void dma_cat8(CHle * hle, uint8_t * dst, uint32_t catsrc_ptr)
{
uint32_t ptr1 = *dram_u32(hle, catsrc_ptr + CATSRC_PTR1);
uint32_t ptr2 = *dram_u32(hle, catsrc_ptr + CATSRC_PTR2);
uint32_t ptr1 = *dram_u32(hle, catsrc_ptr + CATSRC_PTR1);
uint32_t ptr2 = *dram_u32(hle, catsrc_ptr + CATSRC_PTR2);
uint16_t size1 = *dram_u16(hle, catsrc_ptr + CATSRC_SIZE1);
uint16_t size2 = *dram_u16(hle, catsrc_ptr + CATSRC_SIZE2);
@ -482,10 +491,10 @@ static void dma_cat8(CHle * hle, uint8_t *dst, uint32_t catsrc_ptr)
dram_load_u8(hle, dst + count1, ptr2, count2);
}
static void dma_cat16(CHle * hle, uint16_t *dst, uint32_t catsrc_ptr)
static void dma_cat16(CHle * hle, uint16_t * dst, uint32_t catsrc_ptr)
{
uint32_t ptr1 = *dram_u32(hle, catsrc_ptr + CATSRC_PTR1);
uint32_t ptr2 = *dram_u32(hle, catsrc_ptr + CATSRC_PTR2);
uint32_t ptr1 = *dram_u32(hle, catsrc_ptr + CATSRC_PTR1);
uint32_t ptr2 = *dram_u32(hle, catsrc_ptr + CATSRC_PTR2);
uint16_t size1 = *dram_u16(hle, catsrc_ptr + CATSRC_SIZE1);
uint16_t size2 = *dram_u16(hle, catsrc_ptr + CATSRC_SIZE2);
@ -503,9 +512,9 @@ static void dma_cat16(CHle * hle, uint16_t *dst, uint32_t catsrc_ptr)
dram_load_u16(hle, dst + count1, ptr2, count2);
}
static void load_samples_PCM16(CHle * hle, uint32_t voice_ptr, int16_t *samples, unsigned *segbase, unsigned *offset)
static void load_samples_PCM16(CHle * hle, uint32_t voice_ptr, int16_t * samples, unsigned * segbase, unsigned * offset)
{
uint8_t u8_3e = *dram_u8(hle, voice_ptr + VOICE_SKIP_SAMPLES);
uint8_t u8_3e = *dram_u8(hle, voice_ptr + VOICE_SKIP_SAMPLES);
uint16_t u16_40 = *dram_u16(hle, voice_ptr + VOICE_U16_40);
uint16_t u16_42 = *dram_u16(hle, voice_ptr + VOICE_U16_42);
@ -514,7 +523,7 @@ static void load_samples_PCM16(CHle * hle, uint32_t voice_ptr, int16_t *samples,
hle->VerboseMessage("Format: PCM16");
*segbase = SAMPLE_BUFFER_SIZE - count;
*offset = u8_3e;
*offset = u8_3e;
dma_cat16(hle, (uint16_t *)samples + *segbase, voice_ptr + VOICE_CATSRC_0);
@ -524,16 +533,16 @@ 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
// ADPCM has a compression ratio of 5/16
uint8_t buffer[SAMPLE_BUFFER_SIZE * 2 * 5 / 16];
int16_t adpcm_table[128];
uint8_t u8_3c = *dram_u8(hle, voice_ptr + VOICE_ADPCM_FRAMES );
uint8_t u8_3c = *dram_u8(hle, voice_ptr + VOICE_ADPCM_FRAMES);
uint8_t u8_3d = *dram_u8(hle, voice_ptr + VOICE_ADPCM_FRAMES + 1);
uint8_t u8_3e = *dram_u8(hle, voice_ptr + VOICE_SKIP_SAMPLES );
uint8_t u8_3e = *dram_u8(hle, voice_ptr + VOICE_SKIP_SAMPLES);
uint8_t u8_3f = *dram_u8(hle, voice_ptr + VOICE_SKIP_SAMPLES + 1);
uint32_t adpcm_table_ptr = *dram_u32(hle, voice_ptr + VOICE_ADPCM_TABLE_PTR);
unsigned count;
@ -546,7 +555,7 @@ static void load_samples_ADPCM(CHle * hle, uint32_t voice_ptr, int16_t *samples,
count = u8_3c << 5;
*segbase = SAMPLE_BUFFER_SIZE - count;
*offset = u8_3e & 0x1f;
*offset = u8_3e & 0x1f;
dma_cat8(hle, buffer, voice_ptr + VOICE_CATSRC_0);
adpcm_decode_frames(hle, samples + *segbase, buffer, adpcm_table, u8_3c, u8_3e);
@ -558,10 +567,10 @@ static void load_samples_ADPCM(CHle * hle, uint32_t voice_ptr, int16_t *samples,
}
}
static void adpcm_decode_frames(CHle * hle, int16_t *dst, const uint8_t *src, const int16_t *table, uint8_t count, uint8_t skip_samples)
static void adpcm_decode_frames(CHle * hle, int16_t * dst, const uint8_t * src, const int16_t * table, uint8_t count, uint8_t skip_samples)
{
int16_t frame[32];
const uint8_t *nibbles = src + 8;
const uint8_t * nibbles = src + 8;
unsigned i;
bool jump_gap = false;
@ -578,14 +587,14 @@ static void adpcm_decode_frames(CHle * hle, int16_t *dst, const uint8_t *src, co
{
uint8_t c2 = nibbles[0];
const int16_t *book = (c2 & 0xf0) + table;
const int16_t * book = (c2 & 0xf0) + table;
unsigned int rshift = (c2 & 0x0f);
adpcm_predict_frame(frame, src, nibbles, rshift);
memcpy(dst, frame, 2 * sizeof(frame[0]));
adpcm_compute_residuals(dst + 2, frame + 2, book, dst , 6);
adpcm_compute_residuals(dst + 8, frame + 8, book, dst + 6, 8);
adpcm_compute_residuals(dst + 2, frame + 2, book, dst, 6);
adpcm_compute_residuals(dst + 8, frame + 8, book, dst + 6, 8);
adpcm_compute_residuals(dst + 16, frame + 16, book, dst + 14, 8);
adpcm_compute_residuals(dst + 24, frame + 24, book, dst + 22, 8);
@ -602,7 +611,7 @@ static void adpcm_decode_frames(CHle * hle, int16_t *dst, const uint8_t *src, co
}
}
static void adpcm_predict_frame(int16_t *dst, const uint8_t *src, const uint8_t *nibbles, unsigned int rshift)
static void adpcm_predict_frame(int16_t * dst, const uint8_t * src, const uint8_t * nibbles, unsigned int rshift)
{
unsigned int i;
@ -613,52 +622,58 @@ static void adpcm_predict_frame(int16_t *dst, const uint8_t *src, const uint8_t
{
uint8_t byte = nibbles[i];
*(dst++) = adpcm_predict_sample(byte, 0xf0, 8, rshift);
*(dst++) = adpcm_predict_sample(byte, 0xf0, 8, rshift);
*(dst++) = adpcm_predict_sample(byte, 0x0f, 12, rshift);
}
}
static void mix_voice_samples(CHle * hle, musyx_t *musyx, uint32_t voice_ptr, const int16_t *samples, unsigned segbase, unsigned offset, uint32_t last_sample_ptr)
static void mix_voice_samples(CHle * hle, musyx_t * musyx, uint32_t voice_ptr, const int16_t * samples, unsigned segbase, unsigned offset, uint32_t last_sample_ptr)
{
int i, k;
// 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 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 u16_4e = *dram_u16(hle, voice_ptr + VOICE_U16_4E);
// Initialize values and pointers
const int16_t *sample = samples + segbase + offset + u16_4e;
const int16_t *const sample_end = samples + segbase + end_point;
const int16_t *const sample_restart = samples + (restart_point & 0x7fff) +
(((restart_point & 0x8000) != 0) ? 0x000 : segbase);
const int16_t * sample = samples + segbase + offset + u16_4e;
const int16_t * const sample_end = samples + segbase + end_point;
const int16_t * const sample_restart = samples + (restart_point & 0x7fff) +
(((restart_point & 0x8000) != 0) ? 0x000 : segbase);
uint32_t pitch_accu = pitch_q16;
uint32_t pitch_step = pitch_shift << 4;
int32_t v4_env[4];
int32_t v4_env_step[4];
int16_t *v4_dst[4];
int16_t v4[4];
int32_t v4_env[4];
int32_t v4_env_step[4];
int16_t * v4_dst[4];
int16_t v4[4];
dram_load_u32(hle, (uint32_t *)v4_env, voice_ptr + VOICE_ENV_BEGIN, 4);
dram_load_u32(hle, (uint32_t *)v4_env_step, voice_ptr + VOICE_ENV_STEP, 4);
dram_load_u32(hle, (uint32_t *)v4_env, voice_ptr + VOICE_ENV_BEGIN, 4);
dram_load_u32(hle, (uint32_t *)v4_env_step, voice_ptr + VOICE_ENV_STEP, 4);
v4_dst[0] = musyx->left;
v4_dst[1] = musyx->right;
v4_dst[2] = musyx->cc0;
v4_dst[3] = musyx->e50;
hle->VerboseMessage("Voice debug: segbase=%d" "\tu16_4e=%04x\n" "\tpitch: frac0=%04x shift=%04x\n" "\tend_point=%04x restart_point=%04x\n" "\tenv = %08x %08x %08x %08x\n" "\tenv_step = %08x %08x %08x %08x\n", segbase, u16_4e, pitch_q16, pitch_shift, end_point, restart_point, v4_env[0], v4_env[1], v4_env[2], v4_env[3], v4_env_step[0], v4_env_step[1], v4_env_step[2], v4_env_step[3]);
hle->VerboseMessage("Voice debug: segbase=%d"
"\tu16_4e=%04x\n"
"\tpitch: frac0=%04x shift=%04x\n"
"\tend_point=%04x restart_point=%04x\n"
"\tenv = %08x %08x %08x %08x\n"
"\tenv_step = %08x %08x %08x %08x\n",
segbase, u16_4e, pitch_q16, pitch_shift, end_point, restart_point, v4_env[0], v4_env[1], v4_env[2], v4_env[3], v4_env_step[0], v4_env_step[1], v4_env_step[2], v4_env_step[3]);
for (i = 0; i < SUBFRAME_SIZE; ++i)
{
// 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;
int16_t v;
@ -695,12 +710,12 @@ static void mix_voice_samples(CHle * hle, musyx_t *musyx, uint32_t voice_ptr, co
hle->VerboseMessage("last_sample = %04x %04x %04x %04x", v4[0], v4[1], v4[2], v4[3]);
}
static void sfx_stage(CHle * hle, mix_sfx_with_main_subframes_t mix_sfx_with_main_subframes, musyx_t *musyx, uint32_t sfx_ptr, uint16_t idx)
static void sfx_stage(CHle * hle, mix_sfx_with_main_subframes_t mix_sfx_with_main_subframes, musyx_t * musyx, uint32_t sfx_ptr, uint16_t idx)
{
unsigned int i;
int16_t buffer[SUBFRAME_SIZE + 4];
int16_t *subframe = buffer + 4;
int16_t * subframe = buffer + 4;
uint32_t tap_delays[8];
int16_t tap_gains[8];
@ -725,23 +740,26 @@ static void sfx_stage(CHle * hle, mix_sfx_with_main_subframes_t mix_sfx_with_mai
}
// 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);
tap_count = *dram_u16(hle, sfx_ptr + SFX_TAP_COUNT);
tap_count = *dram_u16(hle, sfx_ptr + SFX_TAP_COUNT);
dram_load_u32(hle, tap_delays, sfx_ptr + SFX_TAP_DELAYS, 8);
dram_load_u16(hle, (uint16_t *)tap_gains, sfx_ptr + SFX_TAP_GAINS, 8);
dram_load_u16(hle, (uint16_t *)tap_gains, sfx_ptr + SFX_TAP_GAINS, 8);
fir4_hgain = *dram_u16(hle, sfx_ptr + SFX_FIR4_HGAIN);
fir4_hgain = *dram_u16(hle, sfx_ptr + SFX_FIR4_HGAIN);
dram_load_u16(hle, (uint16_t *)fir4_hcoeffs, sfx_ptr + SFX_FIR4_HCOEFFS, 4);
sfx_gains[0] = *dram_u16(hle, sfx_ptr + SFX_U16_3C);
sfx_gains[1] = *dram_u16(hle, sfx_ptr + SFX_U16_3E);
sfx_gains[0] = *dram_u16(hle, sfx_ptr + SFX_U16_3C);
sfx_gains[1] = *dram_u16(hle, sfx_ptr + SFX_U16_3E);
hle->VerboseMessage("cbuffer: ptr=%08x length=%x", cbuffer_ptr, cbuffer_length);
hle->VerboseMessage("fir4: hgain=%04x hcoeff=%04x %04x %04x %04x", fir4_hgain, fir4_hcoeffs[0], fir4_hcoeffs[1], fir4_hcoeffs[2], fir4_hcoeffs[3]);
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]);
// Mix up to 8 delayed sub-frames
@ -776,19 +794,19 @@ static void sfx_stage(CHle * hle, mix_sfx_with_main_subframes_t mix_sfx_with_mai
dram_store_u16(hle, (uint16_t *)musyx->e50, cbuffer_ptr + pos * 2, SUBFRAME_SIZE);
}
static void mix_sfx_with_main_subframes_v1(musyx_t *musyx, const int16_t *subframe, const uint16_t* UNUSED(gains))
static void mix_sfx_with_main_subframes_v1(musyx_t * musyx, const int16_t * subframe, const uint16_t * UNUSED(gains))
{
unsigned i;
for (i = 0; i < SUBFRAME_SIZE; ++i)
{
int16_t v = subframe[i];
musyx->left[i] = clamp_s16(musyx->left[i] + v);
musyx->left[i] = clamp_s16(musyx->left[i] + v);
musyx->right[i] = clamp_s16(musyx->right[i] + v);
}
}
static void mix_sfx_with_main_subframes_v2(musyx_t *musyx, const int16_t *subframe, const uint16_t* gains)
static void mix_sfx_with_main_subframes_v2(musyx_t * musyx, const int16_t * subframe, const uint16_t * gains)
{
unsigned i;
@ -798,18 +816,18 @@ static void mix_sfx_with_main_subframes_v2(musyx_t *musyx, const int16_t *subfra
int16_t v1 = (int32_t)(v * gains[0]) >> 16;
int16_t v2 = (int32_t)(v * gains[1]) >> 16;
musyx->left[i] = clamp_s16(musyx->left[i] + v1);
musyx->left[i] = clamp_s16(musyx->left[i] + v1);
musyx->right[i] = clamp_s16(musyx->right[i] + v1);
musyx->cc0[i] = clamp_s16(musyx->cc0[i] + v2);
musyx->cc0[i] = clamp_s16(musyx->cc0[i] + v2);
}
}
static void mix_samples(int16_t *y, int16_t x, int16_t hgain)
static void mix_samples(int16_t * y, int16_t x, int16_t hgain)
{
*y = clamp_s16(*y + ((x * hgain + 0x4000) >> 15));
}
static void mix_subframes(int16_t *y, const int16_t *x, int16_t hgain)
static void mix_subframes(int16_t * y, const int16_t * x, int16_t hgain)
{
for (unsigned int i = 0; i < SUBFRAME_SIZE; ++i)
{
@ -817,7 +835,7 @@ static void mix_subframes(int16_t *y, const int16_t *x, int16_t hgain)
}
}
static void mix_fir4(int16_t *y, const int16_t *x, int16_t hgain, const int16_t *hcoeffs)
static void mix_fir4(int16_t * y, const int16_t * x, int16_t hgain, const int16_t * hcoeffs)
{
unsigned int i;
int32_t h[4];
@ -834,50 +852,50 @@ static void mix_fir4(int16_t *y, const int16_t *x, int16_t hgain, const int16_t
}
}
static void interleave_stage_v1(CHle * hle, musyx_t *musyx, uint32_t output_ptr)
static void interleave_stage_v1(CHle * hle, musyx_t * musyx, uint32_t output_ptr)
{
size_t i;
int16_t base_left;
int16_t base_right;
int16_t *left;
int16_t *right;
uint32_t *dst;
int16_t * left;
int16_t * right;
uint32_t * dst;
hle->VerboseMessage("Interleave: %08x", output_ptr);
base_left = clamp_s16(musyx->base_vol[0]);
base_left = clamp_s16(musyx->base_vol[0]);
base_right = clamp_s16(musyx->base_vol[1]);
left = musyx->left;
left = musyx->left;
right = musyx->right;
dst = dram_u32(hle, output_ptr);
dst = dram_u32(hle, output_ptr);
for (i = 0; i < SUBFRAME_SIZE; ++i)
{
uint16_t l = clamp_s16(*(left++) + base_left);
uint16_t l = clamp_s16(*(left++) + base_left);
uint16_t r = clamp_s16(*(right++) + base_right);
*(dst++) = (l << 16) | r;
}
}
static void interleave_stage_v2(CHle * hle, musyx_t *musyx, uint16_t mask_16, uint32_t ptr_18, uint32_t ptr_1c, uint32_t output_ptr)
static void interleave_stage_v2(CHle * hle, musyx_t * musyx, uint16_t mask_16, uint32_t ptr_18, uint32_t ptr_1c, uint32_t output_ptr)
{
unsigned i, k;
int16_t subframe[SUBFRAME_SIZE];
uint32_t *dst;
uint32_t * dst;
uint16_t mask;
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 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)
{
int16_t v = *dram_u16(hle, ptr_1c + i*2);
int16_t v = *dram_u16(hle, ptr_1c + i * 2);
musyx->left[i] = v;
musyx->right[i] = clamp_s16(-v);
}
@ -893,19 +911,19 @@ static void interleave_stage_v2(CHle * hle, musyx_t *musyx, uint16_t mask_16, ui
}
address = *dram_u32(hle, ptr_18);
hgain = *dram_u16(hle, ptr_18 + 4);
hgain = *dram_u16(hle, ptr_18 + 4);
for(i = 0; i < SUBFRAME_SIZE; ++i, address += 2)
for (i = 0; i < SUBFRAME_SIZE; ++i, address += 2)
{
mix_samples(&musyx->left[i], *dram_u16(hle, address), hgain);
mix_samples(&musyx->right[i], *dram_u16(hle, address + 2*SUBFRAME_SIZE), hgain);
mix_samples(&subframe[i], *dram_u16(hle, address + 4*SUBFRAME_SIZE), hgain);
mix_samples(&musyx->left[i], *dram_u16(hle, address), hgain);
mix_samples(&musyx->right[i], *dram_u16(hle, address + 2 * SUBFRAME_SIZE), hgain);
mix_samples(&subframe[i], *dram_u16(hle, address + 4 * SUBFRAME_SIZE), hgain);
}
}
// Interleave L_total and R_total
dst = dram_u32(hle, output_ptr);
for(i = 0; i < SUBFRAME_SIZE; ++i)
for (i = 0; i < SUBFRAME_SIZE; ++i)
{
uint16_t l = musyx->left[i];
uint16_t r = musyx->right[i];
@ -913,5 +931,5 @@ static void interleave_stage_v2(CHle * hle, musyx_t *musyx, uint16_t mask_16, ui
}
// Writeback sub-frame @ptr_1c
dram_store_u16(hle, (uint16_t*)subframe, ptr_1c, SUBFRAME_SIZE);
dram_store_u16(hle, (uint16_t *)subframe, ptr_1c, SUBFRAME_SIZE);
}

View File

@ -5,6 +5,7 @@
// GNU/GPLv2 licensed: https://gnu.org/licenses/gpl-2.0.html
#pragma once
#include <stdint.h>
class CHle;
@ -14,7 +15,10 @@ void cicx105_ucode(CHle * hle);
// Audio list microcodes
enum { N_SEGMENTS = 16 };
enum
{
N_SEGMENTS = 16
};
struct alist_audio_t
{

View File

@ -51,6 +51,17 @@
<ClCompile Include="cpu\RSPRegisterHandler.cpp" />
<ClCompile Include="cpu\RSPRegisterHandlerPlugin.cpp" />
<ClCompile Include="cpu\RspTypes.cpp" />
<ClCompile Include="Hle\alist.cpp" />
<ClCompile Include="Hle\alist_audio.cpp" />
<ClCompile Include="Hle\alist_naudio.cpp" />
<ClCompile Include="Hle\alist_nead.cpp" />
<ClCompile Include="Hle\audio.cpp" />
<ClCompile Include="Hle\cicx105.cpp" />
<ClCompile Include="Hle\hle.cpp" />
<ClCompile Include="Hle\jpeg.cpp" />
<ClCompile Include="Hle\mem.cpp" />
<ClCompile Include="Hle\mp3.cpp" />
<ClCompile Include="Hle\musyx.cpp" />
<ClCompile Include="Recompiler\Mmx.cpp" />
<ClCompile Include="Recompiler\RspProfiling.cpp" />
<ClCompile Include="Recompiler\RspRecompilerAnalysis.cpp" />
@ -76,6 +87,12 @@
<ClInclude Include="cpu\RSPRegisterHandlerPlugin.h" />
<ClInclude Include="cpu\RSPRegisters.h" />
<ClInclude Include="cpu\RspTypes.h" />
<ClInclude Include="Hle\alist.h" />
<ClInclude Include="Hle\arithmetics.h" />
<ClInclude Include="Hle\audio.h" />
<ClInclude Include="Hle\hle.h" />
<ClInclude Include="Hle\mem.h" />
<ClInclude Include="Hle\ucodes.h" />
<ClInclude Include="Recompiler\RspProfiling.h" />
<ClInclude Include="Recompiler\RspRecompilerCPU.h" />
<ClInclude Include="Recompiler\RspRecompilerOps.h" />

View File

@ -31,6 +31,12 @@
<Filter Include="Source Files\Recompiler">
<UniqueIdentifier>{bb961984-d173-4bd2-8a8b-f9a0416188f4}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\hle">
<UniqueIdentifier>{77e5dadf-84ad-45b1-a66b-f88004e0fcea}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\hle">
<UniqueIdentifier>{615a5abd-6592-4b84-8611-cc432c2148ea}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="cpu\RSPiInstruction.cpp">
@ -99,6 +105,39 @@
<ClCompile Include="cpu\RSPRegisterHandlerPlugin.cpp">
<Filter>Source Files\cpu</Filter>
</ClCompile>
<ClCompile Include="Hle\alist.cpp">
<Filter>Source Files\hle</Filter>
</ClCompile>
<ClCompile Include="Hle\audio.cpp">
<Filter>Source Files\hle</Filter>
</ClCompile>
<ClCompile Include="Hle\mem.cpp">
<Filter>Source Files\hle</Filter>
</ClCompile>
<ClCompile Include="Hle\hle.cpp">
<Filter>Source Files\hle</Filter>
</ClCompile>
<ClCompile Include="Hle\alist_audio.cpp">
<Filter>Source Files\hle</Filter>
</ClCompile>
<ClCompile Include="Hle\alist_naudio.cpp">
<Filter>Source Files\hle</Filter>
</ClCompile>
<ClCompile Include="Hle\alist_nead.cpp">
<Filter>Source Files\hle</Filter>
</ClCompile>
<ClCompile Include="Hle\cicx105.cpp">
<Filter>Source Files\hle</Filter>
</ClCompile>
<ClCompile Include="Hle\mp3.cpp">
<Filter>Source Files\hle</Filter>
</ClCompile>
<ClCompile Include="Hle\musyx.cpp">
<Filter>Source Files\hle</Filter>
</ClCompile>
<ClCompile Include="Hle\jpeg.cpp">
<Filter>Source Files\hle</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="cpu\RSPInstruction.h">
@ -161,5 +200,23 @@
<ClInclude Include="cpu\RSPRegisterHandlerPlugin.h">
<Filter>Header Files\cpu</Filter>
</ClInclude>
<ClInclude Include="Hle\alist.h">
<Filter>Header Files\hle</Filter>
</ClInclude>
<ClInclude Include="Hle\arithmetics.h">
<Filter>Header Files\hle</Filter>
</ClInclude>
<ClInclude Include="Hle\audio.h">
<Filter>Header Files\hle</Filter>
</ClInclude>
<ClInclude Include="Hle\mem.h">
<Filter>Header Files\hle</Filter>
</ClInclude>
<ClInclude Include="Hle\hle.h">
<Filter>Header Files\hle</Filter>
</ClInclude>
<ClInclude Include="Hle\ucodes.h">
<Filter>Header Files\hle</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -1,13 +1,118 @@
#include "RSPInfo.h"
#include <Project64-rsp-core/Hle/hle.h>
#include <Project64-rsp-core/Recompiler/RspProfiling.h>
#include <Project64-rsp-core/Recompiler/RspRecompilerCPU.h>
#include <Project64-rsp-core/Settings/RspSettings.h>
#include <Project64-rsp-core/Settings/RspSettingsID.h>
#include <Project64-rsp-core/cpu/RSPCpu.h>
#include <Project64-rsp-core/cpu/RSPRegisters.h>
#include <Project64-rsp-core/cpu/RspLog.h>
#include <Project64-rsp-core/cpu/RspMemory.h>
#include <Settings/Settings.h>
#if defined(_MSC_VER)
#include <Windows.h>
#endif
RSP_INFO RSPInfo;
uint32_t RdramSize = 0;
CHle * g_hle = nullptr;
void ClearAllx86Code(void);
void DetectCpuSpecs(void)
{
uint32_t Intel_Features = 0;
uint32_t AMD_Features = 0;
#if defined(_MSC_VER)
__try
{
#ifdef _M_IX86
_asm {
// Intel features
mov eax, 1
cpuid
mov[Intel_Features], edx
// AMD features
mov eax, 80000001h
cpuid
or [AMD_Features], edx
}
#else
int cpuInfo[4];
__cpuid(cpuInfo, 1);
Intel_Features = cpuInfo[3];
__cpuid(cpuInfo, 0x80000001);
AMD_Features = cpuInfo[3];
#endif
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
AMD_Features = Intel_Features = 0;
}
#else
/*
TODO: With GCC, there is <cpuid.h>, but __cpuid() there is a macro and
needs five arguments, not two. Also, GCC lacks SEH.
*/
AMD_Features = Intel_Features = 0;
#endif
if (Intel_Features & 0x02000000)
{
Compiler.mmx2 = true;
Compiler.sse = true;
}
if (Intel_Features & 0x00800000)
{
Compiler.mmx = true;
}
if (AMD_Features & 0x40000000)
{
Compiler.mmx2 = true;
}
if (Intel_Features & 0x00008000)
{
ConditionalMove = true;
}
else
{
ConditionalMove = false;
}
}
void RspPluginLoaded(void)
{
BreakOnStart = false;
#ifndef _M_X64
g_CPUCore = RecompilerCPU;
#else
g_CPUCore = InterpreterCPU;
#endif
LogRDP = false;
LogX86Code = false;
Profiling = false;
IndvidualBlock = false;
ShowErrors = false;
memset(&Compiler, 0, sizeof(Compiler));
Compiler.bDest = true;
Compiler.bAlignVector = false;
Compiler.bFlags = true;
Compiler.bReOrdering = true;
Compiler.bSections = true;
Compiler.bAccum = true;
Compiler.bGPRConstants = true;
DetectCpuSpecs();
InitializeRspSetting();
SetCPU(g_CPUCore);
}
void InitilizeRSP(RSP_INFO & Rsp_Info)
{
@ -22,4 +127,51 @@ void InitilizeRSP(RSP_INFO & Rsp_Info)
#ifdef GenerateLog
Start_Log();
#endif
if (g_hle != nullptr)
{
delete g_hle;
g_hle = nullptr;
}
}
void RspRomOpened(void)
{
ClearAllx86Code();
JumpTableSize = GetSetting(Set_JumpTableSize);
Mfc0Count = GetSetting(Set_Mfc0Count);
SemaphoreExit = GetSetting(Set_SemaphoreExit);
RdramSize = Set_AllocatedRdramSize != 0 ? GetSystemSetting(Set_AllocatedRdramSize) : 0;
if (RdramSize == 0)
{
RdramSize = 0x00400000;
}
g_RSPRegisterHandler.reset(new RSPRegisterHandlerPlugin(RSPInfo, RdramSize));
}
void RspRomClosed(void)
{
if (Profiling)
{
StopTimer();
GenerateTimerResults();
}
g_RSPRegisterHandler.reset(nullptr);
ClearAllx86Code();
StopRDPLog();
StopCPULog();
#ifdef GenerateLog
Stop_Log();
#endif
}
void FreeRSP(void)
{
FreeMemory();
if (g_hle != nullptr)
{
delete g_hle;
g_hle = nullptr;
}
}

View File

@ -1,6 +1,13 @@
#include <Project64-plugin-spec/Rsp.h>
class CHle;
extern RSP_INFO RSPInfo;
extern uint32_t RdramSize;
extern CHle * g_hle;
void InitilizeRSP(RSP_INFO & Rsp_Info);
void RspPluginLoaded(void);
void RspRomOpened(void);
void RspRomClosed(void);
void FreeRSP(void);

View File

@ -27,6 +27,7 @@ bool ChangedPC;
RSP_BLOCK CurrentBlock;
RSP_CODE RspCode;
RSP_COMPILER Compiler;
uint8_t *pLastSecondary = NULL, *pLastPrimary = NULL;

View File

@ -5,7 +5,7 @@
#include <Settings/Settings.h>
uint16_t Set_AudioHle = 0, Set_GraphicsHle = 0, Set_AllocatedRdramSize = 0;
bool GraphicsHle = true, AudioHle, ConditionalMove;
bool GraphicsHle = true, AudioHle, ConditionalMove, HleAlistTask = false;
bool DebuggingEnabled = false, Profiling, IndvidualBlock, ShowErrors, BreakOnStart = false, LogRDP = false, LogX86Code = false;
void InitializeRspSetting(void)
@ -22,6 +22,7 @@ void InitializeRspSetting(void)
RegisterSetting(Set_Profiling, Data_DWORD_General, "Profiling", NULL, Profiling, NULL);
RegisterSetting(Set_IndvidualBlock, Data_DWORD_General, "Individual Block", NULL, IndvidualBlock, NULL);
RegisterSetting(Set_ShowErrors, Data_DWORD_General, "Show Errors", NULL, ShowErrors, NULL);
RegisterSetting(Set_HleAlistTask, Data_DWORD_General, "Hle Alist Task", NULL, HleAlistTask, NULL);
// Compiler settings
RegisterSetting(Set_CheckDest, Data_DWORD_General, "Check Destination Vector", NULL, Compiler.bDest, NULL);

View File

@ -4,5 +4,5 @@
void InitializeRspSetting(void);
extern uint16_t Set_AudioHle, Set_GraphicsHle, Set_AllocatedRdramSize;
extern bool GraphicsHle, AudioHle, ConditionalMove;
extern bool GraphicsHle, AudioHle, ConditionalMove, HleAlistTask;
extern bool DebuggingEnabled, Profiling, IndvidualBlock, ShowErrors, BreakOnStart, LogRDP, LogX86Code;

View File

@ -9,6 +9,7 @@ enum
Set_Profiling,
Set_IndvidualBlock,
Set_ShowErrors,
Set_HleAlistTask,
// Compiler settings
Set_CheckDest,

View File

@ -1,5 +1,6 @@
#include "RSPCpu.h"
#include <Common/CriticalSection.h>
#include <Project64-rsp-core/Hle/hle.h>
#include <Project64-rsp-core/RSPDebugger.h>
#include <Project64-rsp-core/RSPInfo.h>
#include <Project64-rsp-core/Settings/RspSettings.h>
@ -54,7 +55,10 @@ void Build_RSP(void)
SQrootResult.UW = 0;
SetCPU(g_CPUCore);
g_RSPDebugger->ResetTimerList();
if (g_RSPDebugger != nullptr)
{
g_RSPDebugger->ResetTimerList();
}
EleSpec[0].DW = 0x0001020304050607; // None
EleSpec[1].DW = 0x0001020304050607; // None
@ -144,13 +148,30 @@ uint32_t DoRspCycles(uint32_t Cycles)
*RSPInfo.DPC_STATUS_REG &= ~0x0002;
return Cycles;
}
else if (TaskType == 2 && HleAlistTask)
{
if (g_hle == nullptr)
{
g_hle = new CHle(RSPInfo);
}
if (g_hle != nullptr)
{
g_hle->try_fast_audio_dispatching();
*RSPInfo.SP_STATUS_REG |= SP_STATUS_SIG2 | SP_STATUS_BROKE | SP_STATUS_HALT;
if ((*RSPInfo.SP_STATUS_REG & SP_STATUS_INTR_BREAK) != 0)
{
*RSPInfo.MI_INTR_REG |= MI_INTR_SP;
RSPInfo.CheckInterrupts();
}
}
}
else if (TaskType == 2 && AudioHle)
{
if (RSPInfo.ProcessAList != NULL)
{
RSPInfo.ProcessAList();
}
*RSPInfo.SP_STATUS_REG |= (0x0203);
*RSPInfo.SP_STATUS_REG |= SP_STATUS_SIG2 | SP_STATUS_BROKE | SP_STATUS_HALT;
if ((*RSPInfo.SP_STATUS_REG & SP_STATUS_INTR_BREAK) != 0)
{
*RSPInfo.MI_INTR_REG |= MI_INTR_SP;
@ -163,17 +184,10 @@ uint32_t DoRspCycles(uint32_t Cycles)
RSPInfo.ShowCFB();
}
/*
*RSPInfo.SP_STATUS_REG |= (0x0203 );
if ((*RSPInfo.SP_STATUS_REG & SP_STATUS_INTR_BREAK) != 0 )
{
*RSPInfo.MI_INTR_REG |= MI_INTR_SP;
RSPInfo.CheckInterrupts();
}
//return Cycles;
*/
g_RSPDebugger->RspCyclesStart();
if (g_RSPDebugger != nullptr)
{
g_RSPDebugger->RspCyclesStart();
}
CGuard Guard(g_CPUCriticalSection);
switch (g_CPUCore)
@ -185,6 +199,9 @@ uint32_t DoRspCycles(uint32_t Cycles)
RunInterpreterCPU(Cycles);
break;
}
g_RSPDebugger->RspCyclesStop();
if (g_RSPDebugger != nullptr)
{
g_RSPDebugger->RspCyclesStop();
}
return Cycles;
}

View File

@ -375,13 +375,18 @@ uint32_t RunInterpreterCPU(uint32_t Cycles)
{
uint32_t CycleCount;
RSP_Running = true;
g_RSPDebugger->StartingCPU();
if (g_RSPDebugger != nullptr)
{
g_RSPDebugger->StartingCPU();
}
CycleCount = 0;
while (RSP_Running)
{
g_RSPDebugger->BeforeExecuteOp();
if (g_RSPDebugger != nullptr)
{
g_RSPDebugger->BeforeExecuteOp();
}
RSPOpC.Value = *(uint32_t *)(RSPInfo.IMEM + (*PrgCount & 0xFFC));
RSP_Opcode[RSPOpC.op]();
RSP_GPR[0].W = 0x00000000; // MIPS $zero hard-wired to 0

View File

@ -413,7 +413,10 @@ void RSP_Opcode_BGEZAL(void)
void RSP_Cop0_MF(void)
{
g_RSPDebugger->RDP_LogMF0(*PrgCount, RSPOpC.rd);
if (g_RSPDebugger != nullptr)
{
g_RSPDebugger->RDP_LogMF0(*PrgCount, RSPOpC.rd);
}
switch (RSPOpC.rd)
{
case 0: RSP_GPR[RSPOpC.rt].UW = g_RSPRegisterHandler->ReadReg(RSPRegister_MEM_ADDR); break;
@ -1678,5 +1681,8 @@ void RSP_Opcode_SWV(void)
void rsp_UnknownOpcode(void)
{
g_RSPDebugger->UnknownOpcode();
if (g_RSPDebugger != nullptr)
{
g_RSPDebugger->UnknownOpcode();
}
}

View File

@ -33,7 +33,6 @@
#include <Project64-rsp-core/cpu/RspMemory.h>
#include <Project64-rsp-core/cpu/RspTypes.h>
void ClearAllx86Code(void);
void ProcessMenuItem(int32_t ID);
#ifdef _WIN32
BOOL CALLBACK CompilerDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
@ -131,7 +130,7 @@ Output: None
EXPORT void CloseDLL(void)
{
FreeMemory();
FreeRSP();
}
/*
@ -178,6 +177,7 @@ void FixMenuState(void)
CheckMenuItem(hRSPMenu, ID_CPUMETHOD_INTERPT, MF_BYCOMMAND | (g_CPUCore == InterpreterCPU ? MFS_CHECKED : MF_UNCHECKED));
CheckMenuItem(hRSPMenu, ID_BREAKONSTARTOFTASK, MF_BYCOMMAND | (BreakOnStart ? MFS_CHECKED : MF_UNCHECKED));
CheckMenuItem(hRSPMenu, ID_LOGRDPCOMMANDS, MF_BYCOMMAND | (LogRDP ? MFS_CHECKED : MF_UNCHECKED));
CheckMenuItem(hRSPMenu, ID_SETTINGS_HLEALISTTASK, MF_BYCOMMAND | (HleAlistTask ? MFS_CHECKED : MF_UNCHECKED));
CheckMenuItem(hRSPMenu, ID_SETTINGS_LOGX86CODE, MF_BYCOMMAND | (LogX86Code ? MFS_CHECKED : MF_UNCHECKED));
CheckMenuItem(hRSPMenu, ID_SETTINGS_MULTITHREADED, MF_BYCOMMAND | (MultiThreadedDefault ? MFS_CHECKED : MF_UNCHECKED));
CheckMenuItem(hRSPMenu, ID_PROFILING_ON, MF_BYCOMMAND | (Profiling ? MFS_CHECKED : MF_UNCHECKED));
@ -255,74 +255,6 @@ CycleCount is the number of cycles between switching
control between the RSP and r4300i core.
Output: None
*/
RSP_COMPILER Compiler;
void DetectCpuSpecs(void)
{
DWORD Intel_Features = 0;
DWORD AMD_Features = 0;
#if defined(_MSC_VER)
__try
{
#ifdef _M_IX86
_asm {
// Intel features
mov eax, 1
cpuid
mov [Intel_Features], edx
// AMD features
mov eax, 80000001h
cpuid
or [AMD_Features], edx
}
#else
int cpuInfo[4];
__cpuid(cpuInfo, 1);
Intel_Features = cpuInfo[3];
__cpuid(cpuInfo, 0x80000001);
AMD_Features = cpuInfo[3];
#endif
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
AMD_Features = Intel_Features = 0;
}
#else
/*
TODO: With GCC, there is <cpuid.h>, but __cpuid() there is a macro and
needs five arguments, not two. Also, GCC lacks SEH.
*/
AMD_Features = Intel_Features = 0;
#endif
if (Intel_Features & 0x02000000)
{
Compiler.mmx2 = true;
Compiler.sse = true;
}
if (Intel_Features & 0x00800000)
{
Compiler.mmx = true;
}
if (AMD_Features & 0x40000000)
{
Compiler.mmx2 = true;
}
if (Intel_Features & 0x00008000)
{
ConditionalMove = true;
}
else
{
ConditionalMove = false;
}
}
EXPORT void InitiateRSP(RSP_INFO Rsp_Info, uint32_t * CycleCount)
{
g_RSPDebuggerUI.reset(new RSPDebuggerUI);
@ -446,6 +378,13 @@ void ProcessMenuItem(int32_t ID)
}
break;
}
case ID_SETTINGS_HLEALISTTASK:
{
bool Checked = (GetMenuState(hRSPMenu, ID_SETTINGS_HLEALISTTASK, MF_BYCOMMAND) & MFS_CHECKED) != 0;
CheckMenuItem(hRSPMenu, ID_SETTINGS_HLEALISTTASK, MF_BYCOMMAND | (Checked ? MFS_UNCHECKED : MFS_CHECKED));
SetSetting(Set_HleAlistTask, !Checked);
break;
}
case ID_SETTINGS_MULTITHREADED:
{
bool Checked = (GetMenuState(hRSPMenu, ID_SETTINGS_MULTITHREADED, MF_BYCOMMAND) & MFS_CHECKED) != 0;
@ -482,21 +421,11 @@ Output: None
EXPORT void RomOpen(void)
{
ClearAllx86Code();
RspRomOpened();
if (DebuggingEnabled)
{
EnableDebugging(true);
}
JumpTableSize = GetSetting(Set_JumpTableSize);
Mfc0Count = GetSetting(Set_Mfc0Count);
SemaphoreExit = GetSetting(Set_SemaphoreExit);
RdramSize = Set_AllocatedRdramSize != 0 ? GetSystemSetting(Set_AllocatedRdramSize) : 0;
if (RdramSize == 0)
{
RdramSize = 0x00400000;
}
g_RSPRegisterHandler.reset(new RSPRegisterHandlerPlugin(RSPInfo, RdramSize));
}
/*
@ -508,19 +437,7 @@ Output: None
EXPORT void RomClosed(void)
{
if (Profiling)
{
StopTimer();
GenerateTimerResults();
}
g_RSPRegisterHandler.reset(nullptr);
ClearAllx86Code();
StopRDPLog();
StopCPULog();
#ifdef GenerateLog
Stop_Log();
#endif
RspRomClosed();
}
#ifdef _WIN32
@ -672,6 +589,7 @@ EXPORT void EnableDebugging(int Enabled)
Profiling = GetSetting(Set_Profiling) != 0;
IndvidualBlock = GetSetting(Set_IndvidualBlock) != 0;
ShowErrors = GetSetting(Set_ShowErrors) != 0;
HleAlistTask = GetSetting(Set_HleAlistTask) != 0;
Compiler.bDest = GetSetting(Set_CheckDest) != 0;
Compiler.bAccum = GetSetting(Set_Accum) != 0;
@ -702,31 +620,7 @@ EXPORT void EnableDebugging(int Enabled)
EXPORT void PluginLoaded(void)
{
BreakOnStart = false;
#ifndef _M_X64
g_CPUCore = RecompilerCPU;
#else
g_CPUCore = InterpreterCPU;
#endif
LogRDP = false;
LogX86Code = false;
Profiling = false;
IndvidualBlock = false;
ShowErrors = false;
memset(&Compiler, 0, sizeof(Compiler));
Compiler.bDest = true;
Compiler.bAlignVector = false;
Compiler.bFlags = true;
Compiler.bReOrdering = true;
Compiler.bSections = true;
Compiler.bAccum = true;
Compiler.bGPRConstants = true;
DetectCpuSpecs();
InitializeRspSetting();
SetCPU(g_CPUCore);
RspPluginLoaded();
}
#ifdef _WIN32

View File

@ -190,6 +190,7 @@ BEGIN
END
POPUP "Settings"
BEGIN
MENUITEM "HLE alist task", ID_SETTINGS_HLEALISTTASK
MENUITEM "Show Compiler Errors", ID_SHOWCOMPILERERRORS
MENUITEM "Break on start of task", ID_BREAKONSTARTOFTASK
MENUITEM "Log RDP Commands", ID_LOGRDPCOMMANDS

View File

@ -67,9 +67,6 @@
<ProjectReference Include="..\Settings\Settings.vcxproj">
<Project>{8b9961b1-88d9-4ea3-a752-507a00dd9f3d}</Project>
</ProjectReference>
<ProjectReference Include="..\UpdateVersion\UpdateVersion.vcxproj">
<Project>{1968162c-0793-491d-91a1-81645a24d399}</Project>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Project64-rsp.rc" />

View File

@ -38,13 +38,14 @@
#define ID_CPUMETHOD_INTERPT 5017
#define ID_SETTINGS_LOGX86CODE 5019
#define ID_SETTINGS_MULTITHREADED 5020
#define ID_SETTINGS_HLEALISTTASK 5021
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 108
#define _APS_NEXT_COMMAND_VALUE 5021
#define _APS_NEXT_COMMAND_VALUE 5022
#define _APS_NEXT_CONTROL_VALUE 1032
#define _APS_NEXT_SYMED_VALUE 101
#endif

View File

@ -12,6 +12,7 @@ set ScanDir[2]="%base_dir%\Source\Project64-core"
set ScanDir[3]="%base_dir%\Source\Project64-rsp"
set ScanDir[4]="%base_dir%\Source\Project64-rsp-core"
set ScanDir[5]="%base_dir%\Source\Android\Bridge"
set ScanDir[6]="%base_dir%\Source\Android\PluginRSP"
set ScanFiles[0]="*.cpp"
set ScanFiles[1]="*.h"