Import upstream version 2.5.9+git20220411.1.2ae723c
Debian Janitor
2 years ago
0 | name: HLE RSP | |
1 | ||
2 | on: | |
3 | push: | |
4 | paths-ignore: | |
5 | - '**/*.md' | |
6 | - '.{gitattributes,gitignore,travis.yml}' | |
7 | - 'appveyor.yml,README' | |
8 | pull_request: | |
9 | paths-ignore: | |
10 | - '**/*.md' | |
11 | - '.{gitattributes,gitignore,travis.yml}' | |
12 | - 'appveyor.yml,README' | |
13 | workflow_dispatch: | |
14 | jobs: | |
15 | ||
16 | Linux: | |
17 | strategy: | |
18 | fail-fast: false | |
19 | matrix: | |
20 | include: | |
21 | - cc: GCC | |
22 | - cc: Clang | |
23 | name: Linux / ${{ matrix.cc }} / x64 | x86 | |
24 | runs-on: ubuntu-20.04 | |
25 | steps: | |
26 | - uses: actions/checkout@v2 | |
27 | - name: Get build dependencies and arrange the environment | |
28 | run: | | |
29 | sudo apt-get update | |
30 | sudo apt-get --reinstall -y install gcc-multilib g++-multilib libc6 libc6-dev-i386 | |
31 | sudo ldconfig | |
32 | - name: Build and related stuff | |
33 | run: | | |
34 | if [[ "${{ matrix.cc }}" == "GCC" ]]; then | |
35 | CC="gcc" | |
36 | CXX="g++" | |
37 | else | |
38 | CC="clang" | |
39 | CXX="clang++" | |
40 | fi | |
41 | ${CC} --version | |
42 | echo "" | |
43 | git clone --depth 1 https://github.com/mupen64plus/mupen64plus-core.git ../mupen64plus-core | |
44 | for BITS in 64 32 | |
45 | do | |
46 | if [[ ${BITS} -eq 32 ]]; then MSG="x86"; else MSG="x64"; fi | |
47 | echo "" | |
48 | echo ":: ${{ matrix.cc }} ${MSG} ::" | |
49 | echo "" | |
50 | make -C projects/unix clean | |
51 | echo "" | |
52 | make CC="${CC}" CXX="${CXX}" BITS="${BITS}" -C projects/unix all | |
53 | echo "" | |
54 | ls -gG projects/unix/*.so | |
55 | ldd projects/unix/mupen64plus-rsp-hle.so | |
56 | done | |
57 | ||
58 | MSYS2: | |
59 | strategy: | |
60 | fail-fast: false | |
61 | matrix: | |
62 | include: | |
63 | - cc: GCC | |
64 | platform: x64 | |
65 | cross: x86_64 | |
66 | bits: 64 | |
67 | - cc: GCC | |
68 | platform: x86 | |
69 | cross: i686 | |
70 | bits: 32 | |
71 | name: Windows / MSYS2 ${{ matrix.cc }} / ${{ matrix.platform }} | |
72 | runs-on: windows-2019 | |
73 | defaults: | |
74 | run: | |
75 | shell: msys2 {0} | |
76 | steps: | |
77 | - uses: actions/checkout@v2 | |
78 | - uses: msys2/setup-msys2@v2 | |
79 | with: | |
80 | msystem: MINGW${{ matrix.bits }} | |
81 | update: true | |
82 | install: >- | |
83 | git | |
84 | make | |
85 | mingw-w64-${{ matrix.cross }}-gcc | |
86 | mingw-w64-${{ matrix.cross }}-toolchain | |
87 | - name: Build and related stuff | |
88 | run: | | |
89 | export OPTFLAGS="-O2 -flto" | |
90 | echo "G_REV=$(git rev-parse --short HEAD)" >> "${GITHUB_ENV}" | |
91 | CC="gcc" | |
92 | CXX="g++" | |
93 | ${CC} --version | |
94 | echo "" | |
95 | git clone --depth 1 https://github.com/mupen64plus/mupen64plus-core.git ../mupen64plus-core | |
96 | echo "" | |
97 | echo ":: ${{ matrix.cc }} ${{ matrix.platform }} ::" | |
98 | echo "" | |
99 | make -C projects/unix clean | |
100 | echo "" | |
101 | make CC="${CC}" CXX="${CXX}" BITS="${{ matrix.bits }}" -C projects/unix all | |
102 | echo "" | |
103 | ls -gG projects/unix/*.dll | |
104 | ldd projects/unix/mupen64plus-rsp-hle.dll | |
105 | - name: Copy binaries, dependencies, etc... | |
106 | run: | | |
107 | mkdir pkg | |
108 | cd projects/unix | |
109 | for BIN in *.dll | |
110 | do | |
111 | echo ":: Copying ${BIN}" | |
112 | cp "${BIN}" ../../pkg/ | |
113 | done | |
114 | - name: Upload artifact | |
115 | uses: actions/upload-artifact@v2 | |
116 | with: | |
117 | name: mupen64plus-rsp-hle-msys2-${{ matrix.platform }}-g${{ env.G_REV }} | |
118 | path: pkg/* | |
119 | ||
120 | MSVC: | |
121 | strategy: | |
122 | fail-fast: false | |
123 | matrix: | |
124 | include: | |
125 | - toolset: v142 | |
126 | platform: x64 | |
127 | - toolset: v141_xp | |
128 | platform: x86 | |
129 | name: Windows / MSVC ${{ matrix.toolset }} / ${{ matrix.platform }} | |
130 | runs-on: windows-2019 | |
131 | defaults: | |
132 | run: | |
133 | shell: cmd | |
134 | steps: | |
135 | - uses: actions/checkout@v2 | |
136 | - uses: microsoft/setup-msbuild@v1.0.3 | |
137 | # with: | |
138 | # vs-version: 16.11 | |
139 | - name: Build and related stuff | |
140 | run: | | |
141 | for /f "tokens=1" %%R in ('git rev-parse --short HEAD') do set "G_REV=%%R" | |
142 | echo G_REV=%G_REV%>> "%GITHUB_ENV%" | |
143 | set "ARCH=${{ matrix.platform }}" | |
144 | if [%ARCH%] == [x86] set "ARCH=Win32" | |
145 | echo. | |
146 | msbuild --version | |
147 | echo. | |
148 | git clone --depth 1 https://github.com/mupen64plus/mupen64plus-core.git ..\mupen64plus-core | |
149 | echo. | |
150 | msbuild projects\msvc\mupen64plus-rsp-hle.vcxproj /p:Configuration=Release;Platform=%ARCH%;PlatformToolset=${{ matrix.toolset }} | |
151 | echo. | |
152 | md backup | |
153 | copy projects\msvc\%ARCH%\Release\mupen64plus-rsp-hle.dll backup\ | |
154 | dir backup\*.dll | |
155 | - name: Copy binaries, dependencies, etc... | |
156 | run: | | |
157 | md pkg | |
158 | cd pkg | |
159 | xcopy "..\backup" . | |
160 | - name: Upload artifact | |
161 | uses: actions/upload-artifact@v2 | |
162 | with: | |
163 | name: mupen64plus-rsp-hle-msvc-${{ matrix.platform }}-g${{ env.G_REV }} | |
164 | path: pkg/* | |
165 | ||
166 | Nightly-build: | |
167 | runs-on: ubuntu-latest | |
168 | needs: [MSYS2, MSVC] | |
169 | if: github.ref == 'refs/heads/master' | |
170 | steps: | |
171 | - uses: actions/checkout@v2 | |
172 | - name: Download artifacts | |
173 | uses: actions/download-artifact@v2 | |
174 | with: | |
175 | path: binaries | |
176 | - name: Get some tools | |
177 | run: | | |
178 | sudo apt-get update | |
179 | sudo apt-get -y install hashdeep | |
180 | - name: Creating new artifacts and update nightly-build | |
181 | run: | | |
182 | mkdir pkg | |
183 | cd binaries | |
184 | for BIN in * | |
185 | do | |
186 | echo ":: Creating ${BIN}.zip" | |
187 | cd "${BIN}" | |
188 | zip -r "../../pkg/${BIN}.zip" * | |
189 | cd .. | |
190 | done | |
191 | cd ../pkg | |
192 | echo "" | |
193 | for BIN in *.zip | |
194 | do | |
195 | ls -gG ${BIN} | |
196 | tigerdeep -l ${BIN} >> ${BIN:0:19}.tiger.txt | |
197 | sha256sum ${BIN} >> ${BIN:0:19}.sha256.txt | |
198 | sha512sum ${BIN} >> ${BIN:0:19}.sha512.txt | |
199 | done | |
200 | echo "" | |
201 | echo "TIGER:" | |
202 | cat *.tiger.txt | |
203 | echo "" | |
204 | echo "SHA256:" | |
205 | cat *.sha256.txt | |
206 | echo "" | |
207 | echo "SHA512:" | |
208 | cat *.sha512.txt | |
209 | echo "" | |
210 | git tag -f nightly-build | |
211 | git push -f origin nightly-build | |
212 | - name: Nightly-build | |
213 | uses: ncipollo/release-action@v1 | |
214 | with: | |
215 | prerelease: true | |
216 | allowUpdates: true | |
217 | removeArtifacts: true | |
218 | replacesArtifacts: false | |
219 | tag: nightly-build | |
220 | artifacts: pkg/* |
0 | sudo: required | |
1 | dist: xenial | |
0 | 2 | language: cpp |
1 | 3 | compiler: |
2 | 4 | - gcc |
3 | 5 | - clang |
6 | addons: | |
7 | apt: | |
8 | packages: | |
9 | - git | |
4 | 10 | before_install: |
5 | - sudo apt-get update -qq | |
6 | - sudo apt-get install -y git | |
7 | 11 | - git clone --depth=1 --branch=master git://github.com/mupen64plus/mupen64plus-core.git deps/mupen64plus-core |
8 | 12 | env: |
9 | 13 | - DUMP=0 |
10 | 14 | - DUMP=1 |
11 | 15 | script: |
12 | 16 | - make -C projects/unix APIDIR="$(pwd)/deps/mupen64plus-core/src/api/" V=1 clean && LDFLAGS="-Wl,--no-add-needed -Wl,--no-undefined" OPTFLAGS="-O2" make CC="${CC}" CXX="${CXX}" -j$(nproc) -C projects/unix APIDIR="$(pwd)/deps/mupen64plus-core/src/api/" V=1 all |
17 | ||
18 | # extra mxe build entries | |
19 | matrix: | |
20 | include: | |
21 | - env: | |
22 | - MXE_CPU=i686 | |
23 | - PATH="/usr/lib/mxe/usr/bin/:$PATH" | |
24 | before_install: | |
25 | - curl -sSL "https://mirror.mxe.cc/repos/apt/client-conf/mxeapt.gpg" | sudo -E apt-key add - | |
26 | - echo "deb https://mirror.mxe.cc/repos/apt xenial main" | sudo tee -a /etc/apt/sources.list | |
27 | - sudo apt-get update -qq | |
28 | - sudo apt-get -y --allow-unauthenticated install mxe-i686-w64-mingw32.shared-gcc | |
29 | - git clone --depth=1 --branch=master git://github.com/mupen64plus/mupen64plus-core.git deps/mupen64plus-core | |
30 | script: | |
31 | - make UNAME=MINGW CROSS_COMPILE="${MXE_CPU}-w64-mingw32.shared-" CC="${MXE_CPU}-w64-mingw32.shared-gcc" CXX="${MXE_CPU}-w64-mingw32.shared-g++" HOST_CPU="${MXE_CPU}" -C projects/unix APIDIR="$(pwd)/deps/mupen64plus-core/src/api/" V=1 clean && | |
32 | make UNAME=MINGW CROSS_COMPILE="${MXE_CPU}-w64-mingw32.shared-" CC="${MXE_CPU}-w64-mingw32.shared-gcc" CXX="${MXE_CPU}-w64-mingw32.shared-g++" HOST_CPU="${MXE_CPU}" -C projects/unix APIDIR="$(pwd)/deps/mupen64plus-core/src/api/" V=1 -j$(nproc) all | |
33 | ||
34 | - env: | |
35 | - MXE_CPU=x86_64 | |
36 | - PATH="/usr/lib/mxe/usr/bin/:$PATH" | |
37 | before_install: | |
38 | - curl -sSL "https://mirror.mxe.cc/repos/apt/client-conf/mxeapt.gpg" | sudo -E apt-key add - | |
39 | - echo "deb https://mirror.mxe.cc/repos/apt xenial main" | sudo tee -a /etc/apt/sources.list | |
40 | - sudo apt-get update -qq | |
41 | - sudo apt-get -y --allow-unauthenticated install mxe-x86-64-w64-mingw32.shared-gcc | |
42 | - git clone --depth=1 --branch=master git://github.com/mupen64plus/mupen64plus-core.git deps/mupen64plus-core | |
43 | script: | |
44 | - make UNAME=MINGW CROSS_COMPILE="${MXE_CPU}-w64-mingw32.shared-" CC="${MXE_CPU}-w64-mingw32.shared-gcc" CXX="${MXE_CPU}-w64-mingw32.shared-g++" HOST_CPU="${MXE_CPU}" -C projects/unix APIDIR="$(pwd)/deps/mupen64plus-core/src/api/" V=1 clean && | |
45 | make UNAME=MINGW CROSS_COMPILE="${MXE_CPU}-w64-mingw32.shared-" CC="${MXE_CPU}-w64-mingw32.shared-gcc" CXX="${MXE_CPU}-w64-mingw32.shared-g++" HOST_CPU="${MXE_CPU}" -C projects/unix APIDIR="$(pwd)/deps/mupen64plus-core/src/api/" V=1 -j$(nproc) all |
29 | 29 | Version 2, June 1991 |
30 | 30 | |
31 | 31 | Copyright (C) 1989, 1991 Free Software Foundation, Inc. |
32 | 675 Mass Ave, Cambridge, MA 02139, USA | |
32 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
33 | 33 | Everyone is permitted to copy and distribute verbatim copies |
34 | 34 | of this license document, but changing it is not allowed. |
35 | 35 |
0 | 0 | RSP High-Level Emulation plugin for Mupen64Plus |
1 | 1 | ----------------------------------------------- |
2 | ||
3 | Mupen64Plus-rsp-hle v2.5.9 - February 10, 2019 | |
4 | ---------------------------------------------- | |
5 | - *** BETA RELEASE *** For Testing Only *** | |
2 | 6 | |
3 | 7 | Mupen64Plus-rsp-hle v2.5 - April 26, 2015 |
4 | 8 | ------------------------------------------------- |
0 | version: 1.0.{build} | |
1 | ||
2 | configuration: | |
3 | - Release | |
4 | platform: | |
5 | - Win32 | |
6 | - x64 | |
7 | ||
8 | before_build: | |
9 | - git clone --depth 1 https://github.com/mupen64plus/mupen64plus-core.git ..\mupen64plus-core | |
10 | ||
11 | build_script: | |
12 | - msbuild projects\msvc\mupen64plus-rsp-hle.vcxproj /p:Configuration=%configuration%;Platform=%platform% | |
13 | ||
14 | after_build: | |
15 | - ps: $env:rev1 = git describe --tags | |
16 | - set rev2=%platform% | |
17 | - if "%rev2%"=="Win32" set rev2=x86 | |
18 | - set filepkg=mupen64plus-rsp-hle_v%rev1%_%rev2% | |
19 | - cd projects\msvc\%platform%\%configuration% | |
20 | - 7z a -t7z ..\..\..\..\build\%filepkg%.7z *.dll | |
21 | ||
22 | artifacts: | |
23 | - path: build\$(filepkg).7z | |
24 | name: $(filepkg) |
0 | <?xml version="1.0" encoding="utf-8"?> | |
1 | <Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | |
2 | <ItemGroup Label="ProjectConfigurations"> | |
3 | <ProjectConfiguration Include="Debug|Win32"> | |
4 | <Configuration>Debug</Configuration> | |
5 | <Platform>Win32</Platform> | |
6 | </ProjectConfiguration> | |
7 | <ProjectConfiguration Include="Release|Win32"> | |
8 | <Configuration>Release</Configuration> | |
9 | <Platform>Win32</Platform> | |
10 | </ProjectConfiguration> | |
11 | </ItemGroup> | |
12 | <PropertyGroup Label="Globals"> | |
13 | <ProjectGuid>{2EC7CEE3-C7A7-4F2E-B2C8-4DF6AFEC3E9A}</ProjectGuid> | |
14 | <RootNamespace>mupen64plusrsphle</RootNamespace> | |
15 | <Keyword>Win32Proj</Keyword> | |
16 | </PropertyGroup> | |
17 | <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> | |
18 | <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> | |
19 | <ConfigurationType>DynamicLibrary</ConfigurationType> | |
20 | <CharacterSet>MultiByte</CharacterSet> | |
21 | <WholeProgramOptimization>true</WholeProgramOptimization> | |
22 | <PlatformToolset>v120</PlatformToolset> | |
23 | </PropertyGroup> | |
24 | <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> | |
25 | <ConfigurationType>DynamicLibrary</ConfigurationType> | |
26 | <CharacterSet>MultiByte</CharacterSet> | |
27 | <PlatformToolset>v120</PlatformToolset> | |
28 | </PropertyGroup> | |
29 | <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> | |
30 | <ImportGroup Label="ExtensionSettings"> | |
31 | </ImportGroup> | |
32 | <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> | |
33 | <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | |
34 | </ImportGroup> | |
35 | <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> | |
36 | <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | |
37 | </ImportGroup> | |
38 | <PropertyGroup Label="UserMacros" /> | |
39 | <PropertyGroup> | |
40 | <_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion> | |
41 | <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\</OutDir> | |
42 | <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir> | |
43 | <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental> | |
44 | <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\</OutDir> | |
45 | <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir> | |
46 | <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental> | |
47 | <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet> | |
48 | <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" /> | |
49 | <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" /> | |
50 | <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet> | |
51 | <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" /> | |
52 | <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" /> | |
53 | </PropertyGroup> | |
54 | <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> | |
55 | <ClCompile> | |
56 | <Optimization>Disabled</Optimization> | |
57 | <AdditionalIncludeDirectories>..\..\..\mupen64plus-core\src\api;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> | |
58 | <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;inline=__inline;%(PreprocessorDefinitions)</PreprocessorDefinitions> | |
59 | <MinimalRebuild>true</MinimalRebuild> | |
60 | <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> | |
61 | <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> | |
62 | <PrecompiledHeader> | |
63 | </PrecompiledHeader> | |
64 | <WarningLevel>Level3</WarningLevel> | |
65 | <DebugInformationFormat>EditAndContinue</DebugInformationFormat> | |
66 | <CompileAs>Default</CompileAs> | |
67 | </ClCompile> | |
68 | <Link> | |
69 | <GenerateDebugInformation>true</GenerateDebugInformation> | |
70 | <SubSystem>Windows</SubSystem> | |
71 | <TargetMachine>MachineX86</TargetMachine> | |
72 | </Link> | |
73 | </ItemDefinitionGroup> | |
74 | <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> | |
75 | <ClCompile> | |
76 | <AdditionalIncludeDirectories>..\..\..\mupen64plus-core\src\api;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> | |
77 | <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;inline=__inline;%(PreprocessorDefinitions)</PreprocessorDefinitions> | |
78 | <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> | |
79 | <PrecompiledHeader> | |
80 | </PrecompiledHeader> | |
81 | <WarningLevel>Level3</WarningLevel> | |
82 | <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> | |
83 | <CompileAs>Default</CompileAs> | |
84 | </ClCompile> | |
85 | <Link> | |
86 | <GenerateDebugInformation>true</GenerateDebugInformation> | |
87 | <SubSystem>Windows</SubSystem> | |
88 | <OptimizeReferences>true</OptimizeReferences> | |
89 | <EnableCOMDATFolding>true</EnableCOMDATFolding> | |
90 | <TargetMachine>MachineX86</TargetMachine> | |
91 | </Link> | |
92 | </ItemDefinitionGroup> | |
93 | <ItemGroup> | |
94 | <ClCompile Include="..\..\src\alist.c" /> | |
95 | <ClCompile Include="..\..\src\alist_audio.c" /> | |
96 | <ClCompile Include="..\..\src\alist_naudio.c" /> | |
97 | <ClCompile Include="..\..\src\alist_nead.c" /> | |
98 | <ClCompile Include="..\..\src\audio.c" /> | |
99 | <ClCompile Include="..\..\src\cicx105.c" /> | |
100 | <ClCompile Include="..\..\src\hle.c" /> | |
101 | <ClCompile Include="..\..\src\jpeg.c" /> | |
102 | <ClCompile Include="..\..\src\memory.c" /> | |
103 | <ClCompile Include="..\..\src\mp3.c" /> | |
104 | <ClCompile Include="..\..\src\musyx.c" /> | |
105 | <ClCompile Include="..\..\src\plugin.c" /> | |
106 | </ItemGroup> | |
107 | <ItemGroup> | |
108 | <ClInclude Include="..\..\src\alist.h" /> | |
109 | <ClInclude Include="..\..\src\arithmetics.h" /> | |
110 | <ClInclude Include="..\..\src\audio.h" /> | |
111 | <ClInclude Include="..\..\src\common.h" /> | |
112 | <ClInclude Include="..\..\src\hle.h" /> | |
113 | <ClInclude Include="..\..\src\hle_external.h" /> | |
114 | <ClInclude Include="..\..\src\hle_internal.h" /> | |
115 | <ClInclude Include="..\..\src\memory.h" /> | |
116 | <ClInclude Include="..\..\src\ucodes.h" /> | |
117 | </ItemGroup> | |
118 | <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> | |
119 | <ImportGroup Label="ExtensionTargets"> | |
120 | </ImportGroup> | |
121 | </Project>⏎ |
0 | <?xml version="1.0" encoding="utf-8"?> | |
1 | <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | |
2 | <ItemGroup Label="ProjectConfigurations"> | |
3 | <ProjectConfiguration Include="Debug|Win32"> | |
4 | <Configuration>Debug</Configuration> | |
5 | <Platform>Win32</Platform> | |
6 | </ProjectConfiguration> | |
7 | <ProjectConfiguration Include="Debug|x64"> | |
8 | <Configuration>Debug</Configuration> | |
9 | <Platform>x64</Platform> | |
10 | </ProjectConfiguration> | |
11 | <ProjectConfiguration Include="Release|Win32"> | |
12 | <Configuration>Release</Configuration> | |
13 | <Platform>Win32</Platform> | |
14 | </ProjectConfiguration> | |
15 | <ProjectConfiguration Include="Release|x64"> | |
16 | <Configuration>Release</Configuration> | |
17 | <Platform>x64</Platform> | |
18 | </ProjectConfiguration> | |
19 | </ItemGroup> | |
20 | <PropertyGroup Label="Globals"> | |
21 | <ProjectGuid>{2EC7CEE3-C7A7-4F2E-B2C8-4DF6AFEC3E9A}</ProjectGuid> | |
22 | <RootNamespace>mupen64plusrsphle</RootNamespace> | |
23 | </PropertyGroup> | |
24 | <PropertyGroup Condition="'$(WindowsTargetPlatformVersion)'=='' and '$(VisualStudioVersion)' != '14.0'"> | |
25 | <LatestTargetPlatformVersion>$([Microsoft.Build.Utilities.ToolLocationHelper]::GetLatestSDKTargetPlatformVersion('Windows', '10.0'))</LatestTargetPlatformVersion> | |
26 | <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion> | |
27 | <TargetPlatformVersion>$(WindowsTargetPlatformVersion)</TargetPlatformVersion> | |
28 | </PropertyGroup> | |
29 | <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> | |
30 | <PropertyGroup Condition="'$(PlatformToolset)'=='' or '$(PlatformToolset)'=='v100'" Label="Configuration"> | |
31 | <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> | |
32 | </PropertyGroup> | |
33 | <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> | |
34 | <ConfigurationType>DynamicLibrary</ConfigurationType> | |
35 | <CharacterSet>MultiByte</CharacterSet> | |
36 | <WholeProgramOptimization>true</WholeProgramOptimization> | |
37 | <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir> | |
38 | <IntDir>$(Platform)\$(Configuration)\</IntDir> | |
39 | </PropertyGroup> | |
40 | <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> | |
41 | <ConfigurationType>DynamicLibrary</ConfigurationType> | |
42 | <CharacterSet>MultiByte</CharacterSet> | |
43 | <WholeProgramOptimization>true</WholeProgramOptimization> | |
44 | <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir> | |
45 | <IntDir>$(Platform)\$(Configuration)\</IntDir> | |
46 | </PropertyGroup> | |
47 | <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> | |
48 | <ConfigurationType>DynamicLibrary</ConfigurationType> | |
49 | <CharacterSet>MultiByte</CharacterSet> | |
50 | <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir> | |
51 | <IntDir>$(Platform)\$(Configuration)\</IntDir> | |
52 | </PropertyGroup> | |
53 | <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> | |
54 | <ConfigurationType>DynamicLibrary</ConfigurationType> | |
55 | <CharacterSet>MultiByte</CharacterSet> | |
56 | <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir> | |
57 | <IntDir>$(Platform)\$(Configuration)\</IntDir> | |
58 | </PropertyGroup> | |
59 | <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> | |
60 | <ImportGroup Label="ExtensionSettings"> | |
61 | </ImportGroup> | |
62 | <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> | |
63 | <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | |
64 | </ImportGroup> | |
65 | <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> | |
66 | <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | |
67 | </ImportGroup> | |
68 | <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> | |
69 | <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | |
70 | </ImportGroup> | |
71 | <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> | |
72 | <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | |
73 | </ImportGroup> | |
74 | <PropertyGroup Label="UserMacros" /> | |
75 | <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> | |
76 | <ClCompile> | |
77 | <Optimization>Disabled</Optimization> | |
78 | <AdditionalIncludeDirectories>..\..\..\mupen64plus-core\src\api;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> | |
79 | <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;inline=__inline;%(PreprocessorDefinitions)</PreprocessorDefinitions> | |
80 | <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> | |
81 | <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> | |
82 | <WarningLevel>Level3</WarningLevel> | |
83 | </ClCompile> | |
84 | <Link> | |
85 | <GenerateDebugInformation>true</GenerateDebugInformation> | |
86 | <SubSystem>Windows</SubSystem> | |
87 | </Link> | |
88 | </ItemDefinitionGroup> | |
89 | <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> | |
90 | <ClCompile> | |
91 | <Optimization>Disabled</Optimization> | |
92 | <AdditionalIncludeDirectories>..\..\..\mupen64plus-core\src\api;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> | |
93 | <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;inline=__inline;%(PreprocessorDefinitions)</PreprocessorDefinitions> | |
94 | <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> | |
95 | <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> | |
96 | <WarningLevel>Level3</WarningLevel> | |
97 | </ClCompile> | |
98 | <Link> | |
99 | <GenerateDebugInformation>true</GenerateDebugInformation> | |
100 | <SubSystem>Windows</SubSystem> | |
101 | </Link> | |
102 | </ItemDefinitionGroup> | |
103 | <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> | |
104 | <ClCompile> | |
105 | <AdditionalIncludeDirectories>..\..\..\mupen64plus-core\src\api;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> | |
106 | <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;inline=__inline;%(PreprocessorDefinitions)</PreprocessorDefinitions> | |
107 | <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> | |
108 | <WarningLevel>Level3</WarningLevel> | |
109 | <Optimization>MaxSpeed</Optimization> | |
110 | <FunctionLevelLinking>true</FunctionLevelLinking> | |
111 | <IntrinsicFunctions>true</IntrinsicFunctions> | |
112 | </ClCompile> | |
113 | <Link> | |
114 | <GenerateDebugInformation>true</GenerateDebugInformation> | |
115 | <SubSystem>Windows</SubSystem> | |
116 | <OptimizeReferences>true</OptimizeReferences> | |
117 | <EnableCOMDATFolding>true</EnableCOMDATFolding> | |
118 | </Link> | |
119 | </ItemDefinitionGroup> | |
120 | <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> | |
121 | <ClCompile> | |
122 | <AdditionalIncludeDirectories>..\..\..\mupen64plus-core\src\api;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> | |
123 | <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;inline=__inline;%(PreprocessorDefinitions)</PreprocessorDefinitions> | |
124 | <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> | |
125 | <WarningLevel>Level3</WarningLevel> | |
126 | <Optimization>MaxSpeed</Optimization> | |
127 | <FunctionLevelLinking>true</FunctionLevelLinking> | |
128 | <IntrinsicFunctions>true</IntrinsicFunctions> | |
129 | </ClCompile> | |
130 | <Link> | |
131 | <GenerateDebugInformation>true</GenerateDebugInformation> | |
132 | <SubSystem>Windows</SubSystem> | |
133 | <OptimizeReferences>true</OptimizeReferences> | |
134 | <EnableCOMDATFolding>true</EnableCOMDATFolding> | |
135 | </Link> | |
136 | </ItemDefinitionGroup> | |
137 | <ItemGroup> | |
138 | <ClCompile Include="..\..\src\alist.c" /> | |
139 | <ClCompile Include="..\..\src\alist_audio.c" /> | |
140 | <ClCompile Include="..\..\src\alist_naudio.c" /> | |
141 | <ClCompile Include="..\..\src\alist_nead.c" /> | |
142 | <ClCompile Include="..\..\src\audio.c" /> | |
143 | <ClCompile Include="..\..\src\cicx105.c" /> | |
144 | <ClCompile Include="..\..\src\hle.c" /> | |
145 | <ClCompile Include="..\..\src\hvqm.c" /> | |
146 | <ClCompile Include="..\..\src\jpeg.c" /> | |
147 | <ClCompile Include="..\..\src\memory.c" /> | |
148 | <ClCompile Include="..\..\src\mp3.c" /> | |
149 | <ClCompile Include="..\..\src\musyx.c" /> | |
150 | <ClCompile Include="..\..\src\osal_dynamiclib_win32.c" /> | |
151 | <ClCompile Include="..\..\src\plugin.c" /> | |
152 | <ClCompile Include="..\..\src\re2.c" /> | |
153 | </ItemGroup> | |
154 | <ItemGroup> | |
155 | <ClInclude Include="..\..\src\alist.h" /> | |
156 | <ClInclude Include="..\..\src\arithmetics.h" /> | |
157 | <ClInclude Include="..\..\src\audio.h" /> | |
158 | <ClInclude Include="..\..\src\common.h" /> | |
159 | <ClInclude Include="..\..\src\hle.h" /> | |
160 | <ClInclude Include="..\..\src\hle_external.h" /> | |
161 | <ClInclude Include="..\..\src\hle_internal.h" /> | |
162 | <ClInclude Include="..\..\src\memory.h" /> | |
163 | <ClInclude Include="..\..\src\osal_dynamiclib.h" /> | |
164 | <ClInclude Include="..\..\src\ucodes.h" /> | |
165 | </ItemGroup> | |
166 | <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> | |
167 | <ImportGroup Label="ExtensionTargets"> | |
168 | </ImportGroup> | |
169 | </Project>⏎ |
0 | 0 | #/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
1 | 1 | # * mupen64plus-rsp-hle - Makefile * |
2 | # * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * | |
2 | # * Mupen64Plus homepage: https://mupen64plus.org/ * | |
3 | 3 | # * Copyright (C) 2008-2009 Richard Goedeken * |
4 | 4 | # * Copyright (C) 2007-2008 DarkJeztr Tillin9 * |
5 | 5 | # * * |
52 | 52 | OS = FREEBSD |
53 | 53 | SO_EXTENSION = so |
54 | 54 | SHARED = -shared |
55 | $(warning OS type "$(UNAME)" not officially supported.') | |
56 | 55 | endif |
57 | 56 | ifneq ("$(filter GNU/kFreeBSD kfreebsd,$(UNAME))","") |
58 | 57 | OS = LINUX |
66 | 65 | PIC = 0 |
67 | 66 | endif |
68 | 67 | ifeq ("$(OS)","NONE") |
69 | $(error OS type "$(UNAME)" not supported. Please file bug report at 'http://code.google.com/p/mupen64plus/issues') | |
68 | $(error OS type "$(UNAME)" not supported. Please file bug report at 'https://github.com/mupen64plus/mupen64plus-core/issues') | |
70 | 69 | endif |
71 | 70 | |
72 | 71 | # detect system architecture |
102 | 101 | PIC ?= 1 |
103 | 102 | $(warning Architecture "$(HOST_CPU)" not officially supported.') |
104 | 103 | endif |
104 | ifneq ("$(filter ppc64le powerpc64le,$(HOST_CPU))","") | |
105 | CPU := PPC | |
106 | ARCH_DETECTED := 64BITS | |
107 | BIG_ENDIAN := 0 | |
108 | PIC ?= 1 | |
109 | $(warning Architecture "$(HOST_CPU)" not officially supported.') | |
110 | endif | |
105 | 111 | ifneq ("$(filter arm%,$(HOST_CPU))","") |
106 | 112 | ifeq ("$(filter arm%b,$(HOST_CPU))","") |
107 | 113 | CPU := ARM |
116 | 122 | PIC ?= 1 |
117 | 123 | $(warning Architecture "$(HOST_CPU)" not officially supported.') |
118 | 124 | endif |
125 | ifneq ("$(filter aarch64,$(HOST_CPU))","") | |
126 | CPU := AARCH | |
127 | ARCH_DETECTED := 64BITS | |
128 | PIC ?= 1 | |
129 | NEW_DYNAREC := 1 | |
130 | NO_ASM := 1 | |
131 | endif | |
132 | ifneq ("$(filter riscv64,$(HOST_CPU))","") | |
133 | CPU := RISCV64 | |
134 | ARCH_DETECTED := 64BITS | |
135 | PIC ?= 1 | |
136 | NO_ASM := 1 | |
137 | $(warning Architecture "$(HOST_CPU)" not officially supported.) | |
138 | endif | |
119 | 139 | ifeq ("$(CPU)","NONE") |
120 | $(error CPU type "$(HOST_CPU)" not supported. Please file bug report at 'http://code.google.com/p/mupen64plus/issues') | |
121 | endif | |
140 | $(error CPU type "$(HOST_CPU)" not supported. Please file bug report at 'https://github.com/mupen64plus/mupen64plus-core/issues') | |
141 | endif | |
142 | ||
143 | SRCDIR = ../../src | |
144 | OBJDIR = _obj$(POSTFIX) | |
122 | 145 | |
123 | 146 | # base CFLAGS, LDLIBS, and LDFLAGS |
124 | 147 | OPTFLAGS ?= -O3 -flto |
125 | 148 | WARNFLAGS ?= -Wall |
126 | CFLAGS += $(OPTFLAGS) $(WARNFLAGS) -ffast-math -fno-strict-aliasing -fvisibility=hidden -I../../src | |
149 | CFLAGS += $(OPTFLAGS) $(WARNFLAGS) -ffast-math -fno-strict-aliasing -fvisibility=hidden -I$(SRCDIR) | |
127 | 150 | LDFLAGS += $(SHARED) |
128 | 151 | |
129 | 152 | # Since we are building a shared library, we must compile with -fPIC on some architectures |
143 | 166 | ifeq ($(OS), FREEBSD) |
144 | 167 | $(error Do not use the BITS=32 option with FreeBSD, use -m32 and -m elf_i386) |
145 | 168 | endif |
146 | CFLAGS += -m32 | |
147 | LDFLAGS += -Wl,-m,elf_i386 | |
169 | ifneq ($(OS), OSX) | |
170 | ifeq ($(OS), MINGW) | |
171 | CFLAGS += -march=i686 | |
172 | LDFLAGS += -Wl,-m,i386pe | |
173 | else | |
174 | CFLAGS += -m32 | |
175 | LDFLAGS += -Wl,-m,elf_i386 | |
176 | endif | |
177 | endif | |
178 | endif | |
179 | ||
180 | ifeq ($(ARCH_DETECTED), 64BITS) | |
181 | ifeq ($(OS), MINGW) | |
182 | CFLAGS += -march=x86-64 | |
183 | LDFLAGS += -Wl,-m,i386pep | |
184 | endif | |
148 | 185 | endif |
149 | 186 | |
150 | 187 | # set special flags per-system |
151 | 188 | ifeq ($(OS), LINUX) |
152 | 189 | # only export api symbols |
153 | 190 | LDFLAGS += -Wl,-version-script,$(SRCDIR)/rsp_api_export.ver |
191 | LDLIBS += -ldl | |
154 | 192 | endif |
155 | 193 | ifeq ($(OS), OSX) |
156 | #xcode-select has been around since XCode 3.0, i.e. OS X 10.5 | |
157 | OSX_SDK_ROOT = $(shell xcode-select -print-path)/Platforms/MacOSX.platform/Developer/SDKs | |
158 | OSX_SDK_PATH = $(OSX_SDK_ROOT)/$(shell ls $(OSX_SDK_ROOT) | tail -1) | |
194 | OSX_SDK_PATH = $(shell xcrun --sdk macosx --show-sdk-path) | |
159 | 195 | |
160 | 196 | ifeq ($(CPU), X86) |
161 | 197 | ifeq ($(ARCH_DETECTED), 64BITS) |
162 | CFLAGS += -pipe -arch x86_64 -mmacosx-version-min=10.5 -isysroot $(OSX_SDK_PATH) | |
198 | CFLAGS += -pipe -arch x86_64 -mmacosx-version-min=10.9 -isysroot $(OSX_SDK_PATH) | |
163 | 199 | else |
164 | 200 | CFLAGS += -pipe -mmmx -msse -fomit-frame-pointer -arch i686 -mmacosx-version-min=10.5 -isysroot $(OSX_SDK_PATH) |
165 | 201 | LDFLAGS += -read_only_relocs suppress |
210 | 246 | CFLAGS += -g |
211 | 247 | INSTALL_STRIP_FLAG ?= |
212 | 248 | else |
249 | CFLAGS += -DNDEBUG | |
213 | 250 | ifneq ($(OS),OSX) |
214 | 251 | INSTALL_STRIP_FLAG ?= -s |
215 | 252 | endif |
230 | 267 | ifeq ($(DUMP), 1) |
231 | 268 | CFLAGS += -DENABLE_TASK_DUMP |
232 | 269 | endif |
233 | ||
234 | ||
235 | SRCDIR = ../../src | |
236 | OBJDIR = _obj$(POSTFIX) | |
237 | 270 | |
238 | 271 | # list of source files to compile |
239 | 272 | SOURCE = \ |
244 | 277 | $(SRCDIR)/audio.c \ |
245 | 278 | $(SRCDIR)/cicx105.c \ |
246 | 279 | $(SRCDIR)/hle.c \ |
280 | $(SRCDIR)/hvqm.c \ | |
247 | 281 | $(SRCDIR)/jpeg.c \ |
248 | 282 | $(SRCDIR)/memory.c \ |
249 | 283 | $(SRCDIR)/mp3.c \ |
250 | 284 | $(SRCDIR)/musyx.c \ |
285 | $(SRCDIR)/re2.c \ | |
251 | 286 | $(SRCDIR)/plugin.c |
287 | ||
288 | ifeq ($(OS), MINGW) | |
289 | SOURCE += \ | |
290 | $(SRCDIR)/osal_dynamiclib_win32.c | |
291 | else | |
292 | SOURCE += \ | |
293 | $(SRCDIR)/osal_dynamiclib_unix.c | |
294 | endif | |
252 | 295 | |
253 | 296 | # generate a list of object files build, make a temporary directory for them |
254 | 297 | OBJECTS := $(patsubst $(SRCDIR)/%.c, $(OBJDIR)/%.o, $(filter %.c, $(SOURCE))) |
0 | 0 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
1 | 1 | * Mupen64plus-rsp-hle - alist.c * |
2 | * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * | |
2 | * Mupen64Plus homepage: https://mupen64plus.org/ * | |
3 | 3 | * Copyright (C) 2014 Bobby Smiles * |
4 | 4 | * Copyright (C) 2009 Richard Goedeken * |
5 | 5 | * Copyright (C) 2002 Hacktarux * |
49 | 49 | |
50 | 50 | static int16_t* sample(struct hle_t* hle, unsigned pos) |
51 | 51 | { |
52 | return (int16_t*)hle->alist_buffer + (pos ^ S); | |
52 | return (int16_t*)hle->alist_buffer + ((pos ^ S) & 0xfff); | |
53 | 53 | } |
54 | 54 | |
55 | 55 | static uint8_t* alist_u8(struct hle_t* hle, uint16_t dmem) |
56 | 56 | { |
57 | return u8(hle->alist_buffer, dmem); | |
57 | return (uint8_t*)(hle->alist_buffer + ((dmem ^ S8) & 0xfff)); | |
58 | 58 | } |
59 | 59 | |
60 | 60 | static int16_t* alist_s16(struct hle_t* hle, uint16_t dmem) |
61 | 61 | { |
62 | return (int16_t*)u16(hle->alist_buffer, dmem); | |
62 | return (int16_t*)(hle->alist_buffer + ((dmem ^ S16) & 0xfff)); | |
63 | 63 | } |
64 | 64 | |
65 | 65 | |
281 | 281 | int x, y; |
282 | 282 | short save_buffer[40]; |
283 | 283 | |
284 | memcpy((uint8_t *)save_buffer, (hle->dram + address), sizeof(save_buffer)); | |
284 | 285 | if (init) { |
285 | 286 | ramps[0].value = (vol[0] << 16); |
286 | 287 | ramps[1].value = (vol[1] << 16); |
291 | 292 | exp_seq[0] = (vol[0] * rate[0]); |
292 | 293 | exp_seq[1] = (vol[1] * rate[1]); |
293 | 294 | } else { |
294 | memcpy((uint8_t *)save_buffer, (hle->dram + address), 80); | |
295 | 295 | wet = *(int16_t *)(save_buffer + 0); /* 0-1 */ |
296 | 296 | dry = *(int16_t *)(save_buffer + 2); /* 2-3 */ |
297 | 297 | ramps[0].target = *(int32_t *)(save_buffer + 4); /* 4-5 */ |
353 | 353 | *(int32_t *)(save_buffer + 14) = exp_seq[1]; /* 14-15 */ |
354 | 354 | *(int32_t *)(save_buffer + 16) = (int32_t)ramps[0].value; /* 12-13 */ |
355 | 355 | *(int32_t *)(save_buffer + 18) = (int32_t)ramps[1].value; /* 14-15 */ |
356 | memcpy(hle->dram + address, (uint8_t *)save_buffer, 80); | |
356 | memcpy(hle->dram + address, (uint8_t *)save_buffer, sizeof(save_buffer)); | |
357 | 357 | } |
358 | 358 | |
359 | 359 | void alist_envmix_ge( |
381 | 381 | struct ramp_t ramps[2]; |
382 | 382 | short save_buffer[40]; |
383 | 383 | |
384 | memcpy((uint8_t *)save_buffer, (hle->dram + address), 80); | |
384 | 385 | if (init) { |
385 | 386 | ramps[0].value = (vol[0] << 16); |
386 | 387 | ramps[1].value = (vol[1] << 16); |
389 | 390 | ramps[0].step = rate[0] / 8; |
390 | 391 | ramps[1].step = rate[1] / 8; |
391 | 392 | } else { |
392 | memcpy((uint8_t *)save_buffer, (hle->dram + address), 80); | |
393 | 393 | wet = *(int16_t *)(save_buffer + 0); /* 0-1 */ |
394 | 394 | dry = *(int16_t *)(save_buffer + 2); /* 2-3 */ |
395 | 395 | ramps[0].target = *(int32_t *)(save_buffer + 4); /* 4-5 */ |
457 | 457 | int16_t* const wl = (int16_t*)(hle->alist_buffer + dmem_wl); |
458 | 458 | int16_t* const wr = (int16_t*)(hle->alist_buffer + dmem_wr); |
459 | 459 | |
460 | memcpy((uint8_t *)save_buffer, hle->dram + address, 80); | |
460 | 461 | if (init) { |
461 | 462 | ramps[0].step = rate[0] / 8; |
462 | 463 | ramps[0].value = (vol[0] << 16); |
466 | 467 | ramps[1].target = (target[1] << 16); |
467 | 468 | } |
468 | 469 | else { |
469 | memcpy((uint8_t *)save_buffer, hle->dram + address, 80); | |
470 | 470 | wet = *(int16_t *)(save_buffer + 0); /* 0-1 */ |
471 | 471 | dry = *(int16_t *)(save_buffer + 2); /* 2-3 */ |
472 | 472 | ramps[0].target = *(int16_t *)(save_buffer + 4) << 16; /* 4-5 */ |
665 | 665 | while (count != 0) { |
666 | 666 | const int16_t* lut = RESAMPLE_LUT + ((pitch_accu & 0xfc00) >> 8); |
667 | 667 | |
668 | *sample(hle, opos++) = clamp_s16( | |
669 | ((*sample(hle, ipos ) * lut[0]) >> 15) + | |
670 | ((*sample(hle, ipos + 1) * lut[1]) >> 15) + | |
671 | ((*sample(hle, ipos + 2) * lut[2]) >> 15) + | |
672 | ((*sample(hle, ipos + 3) * lut[3]) >> 15)); | |
668 | *sample(hle, opos++) = clamp_s16( ( | |
669 | (*sample(hle, ipos ) * lut[0]) + | |
670 | (*sample(hle, ipos + 1) * lut[1]) + | |
671 | (*sample(hle, ipos + 2) * lut[2]) + | |
672 | (*sample(hle, ipos + 3) * lut[3]) ) >> 15); | |
673 | 673 | |
674 | 674 | pitch_accu += pitch; |
675 | 675 | ipos += (pitch_accu >> 16); |
960 | 960 | count -= 16; |
961 | 961 | } while (count != 0); |
962 | 962 | |
963 | dram_store_u16(hle, (uint16_t*)(dst - 4), address, 4); | |
963 | dram_store_u32(hle, (uint32_t*)(dst - 4), address, 2); | |
964 | 964 | } |
965 | 965 | |
966 | 966 | void alist_iirf( |
1016 | 1016 | count -= 0x10; |
1017 | 1017 | } while (count > 0); |
1018 | 1018 | |
1019 | dram_store_u16(hle, (uint16_t*)&frame[6], address + 4, 4); | |
1020 | dram_store_u16(hle, (uint16_t*)&ibuf[(index-2)&3], address+8, 2); | |
1021 | dram_store_u16(hle, (uint16_t*)&ibuf[(index-1)&3], address+10, 2); | |
1022 | } | |
1023 | ||
1019 | dram_store_u16(hle, (uint16_t*)&frame[6], address + 4, 2); | |
1020 | dram_store_u16(hle, (uint16_t*)&ibuf[(index-2)&3], address+8, 1); | |
1021 | dram_store_u16(hle, (uint16_t*)&ibuf[(index-1)&3], address+10, 1); | |
1022 | } | |
1023 |
0 | 0 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
1 | 1 | * Mupen64plus-rsp-hle - alist.h * |
2 | * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * | |
2 | * Mupen64Plus homepage: https://mupen64plus.org/ * | |
3 | 3 | * Copyright (C) 2014 Bobby Smiles * |
4 | 4 | * * |
5 | 5 | * This program is free software; you can redistribute it and/or modify * |
0 | 0 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
1 | 1 | * Mupen64plus-rsp-hle - alist_audio.c * |
2 | * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * | |
2 | * Mupen64Plus homepage: https://mupen64plus.org/ * | |
3 | 3 | * Copyright (C) 2014 Bobby Smiles * |
4 | 4 | * Copyright (C) 2009 Richard Goedeken * |
5 | 5 | * Copyright (C) 2002 Hacktarux * |
56 | 56 | static void CLEARBUFF(struct hle_t* hle, uint32_t w1, uint32_t w2) |
57 | 57 | { |
58 | 58 | uint16_t dmem = w1 + DMEM_BASE; |
59 | uint16_t count = w2; | |
59 | uint16_t count = w2 & 0xfff; | |
60 | 60 | |
61 | 61 | if (count == 0) |
62 | 62 | return; |
110 | 110 | |
111 | 111 | alist_resample( |
112 | 112 | hle, |
113 | flags & 0x1, | |
113 | flags & A_INIT, | |
114 | 114 | flags & 0x2, |
115 | 115 | hle->alist_audio.out, |
116 | 116 | hle->alist_audio.in, |
151 | 151 | |
152 | 152 | alist_adpcm( |
153 | 153 | hle, |
154 | flags & 0x1, | |
155 | flags & 0x2, | |
154 | flags & A_INIT, | |
155 | flags & A_LOOP, | |
156 | 156 | false, /* unsupported in this ucode */ |
157 | 157 | hle->alist_audio.out, |
158 | 158 | hle->alist_audio.in, |
277 | 277 | |
278 | 278 | clear_segments(hle); |
279 | 279 | alist_process(hle, ABI, 0x10); |
280 | rsp_break(hle, SP_STATUS_TASKDONE); | |
280 | 281 | } |
281 | 282 | |
282 | 283 | void alist_process_audio_ge(struct hle_t* hle) |
290 | 291 | |
291 | 292 | clear_segments(hle); |
292 | 293 | alist_process(hle, ABI, 0x10); |
294 | rsp_break(hle, SP_STATUS_TASKDONE); | |
293 | 295 | } |
294 | 296 | |
295 | 297 | void alist_process_audio_bc(struct hle_t* hle) |
303 | 305 | |
304 | 306 | clear_segments(hle); |
305 | 307 | alist_process(hle, ABI, 0x10); |
306 | } | |
308 | rsp_break(hle, SP_STATUS_TASKDONE); | |
309 | } |
0 | 0 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
1 | 1 | * Mupen64plus-rsp-hle - alist_naudio.c * |
2 | * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * | |
2 | * Mupen64Plus homepage: https://mupen64plus.org/ * | |
3 | 3 | * Copyright (C) 2014 Bobby Smiles * |
4 | 4 | * Copyright (C) 2009 Richard Goedeken * |
5 | 5 | * Copyright (C) 2002 Hacktarux * |
107 | 107 | { |
108 | 108 | uint8_t flags = (w1 >> 16); |
109 | 109 | |
110 | if (flags & 0x4) { | |
111 | if (flags & 0x2) { | |
110 | if (flags & A_VOL) { | |
111 | if (flags & A_LEFT) { | |
112 | 112 | hle->alist_naudio.vol[0] = w1; |
113 | 113 | hle->alist_naudio.dry = (w2 >> 16); |
114 | 114 | hle->alist_naudio.wet = w2; |
115 | 115 | } |
116 | else { | |
116 | else { /* A_RIGHT */ | |
117 | 117 | hle->alist_naudio.target[1] = w1; |
118 | 118 | hle->alist_naudio.rate[1] = w2; |
119 | 119 | } |
120 | 120 | } |
121 | else { | |
121 | else { /* A_RATE */ | |
122 | 122 | hle->alist_naudio.target[0] = w1; |
123 | 123 | hle->alist_naudio.rate[0] = w2; |
124 | 124 | } |
133 | 133 | |
134 | 134 | alist_envmix_lin( |
135 | 135 | hle, |
136 | flags & 0x1, | |
136 | flags & A_INIT, | |
137 | 137 | NAUDIO_DRY_LEFT, |
138 | 138 | NAUDIO_DRY_RIGHT, |
139 | 139 | NAUDIO_WET_LEFT, |
151 | 151 | static void CLEARBUFF(struct hle_t* hle, uint32_t w1, uint32_t w2) |
152 | 152 | { |
153 | 153 | uint16_t dmem = w1 + NAUDIO_MAIN; |
154 | uint16_t count = w2; | |
154 | uint16_t count = w2 & 0xfff; | |
155 | 155 | |
156 | 156 | alist_clear(hle, dmem, count); |
157 | 157 | } |
215 | 215 | |
216 | 216 | alist_adpcm( |
217 | 217 | hle, |
218 | flags & 0x1, | |
219 | flags & 0x2, | |
218 | flags & A_INIT, | |
219 | flags & A_LOOP, | |
220 | 220 | false, /* unsuported by this ucode */ |
221 | 221 | dmemo, |
222 | 222 | dmemi, |
236 | 236 | |
237 | 237 | alist_resample( |
238 | 238 | hle, |
239 | flags & 0x1, | |
239 | flags & A_INIT, | |
240 | 240 | false, /* TODO: check which ABI supports it */ |
241 | 241 | dmemo, |
242 | 242 | dmemi, |
273 | 273 | }; |
274 | 274 | |
275 | 275 | alist_process(hle, ABI, 0x10); |
276 | rsp_break(hle, SP_STATUS_TASKDONE); | |
276 | 277 | } |
277 | 278 | |
278 | 279 | void alist_process_naudio_bk(struct hle_t* hle) |
286 | 287 | }; |
287 | 288 | |
288 | 289 | alist_process(hle, ABI, 0x10); |
290 | rsp_break(hle, SP_STATUS_TASKDONE); | |
289 | 291 | } |
290 | 292 | |
291 | 293 | void alist_process_naudio_dk(struct hle_t* hle) |
299 | 301 | }; |
300 | 302 | |
301 | 303 | alist_process(hle, ABI, 0x10); |
304 | rsp_break(hle, SP_STATUS_TASKDONE); | |
302 | 305 | } |
303 | 306 | |
304 | 307 | void alist_process_naudio_mp3(struct hle_t* hle) |
311 | 314 | }; |
312 | 315 | |
313 | 316 | alist_process(hle, ABI, 0x10); |
317 | rsp_break(hle, SP_STATUS_TASKDONE); | |
314 | 318 | } |
315 | 319 | |
316 | 320 | void alist_process_naudio_cbfd(struct hle_t* hle) |
324 | 328 | }; |
325 | 329 | |
326 | 330 | alist_process(hle, ABI, 0x10); |
327 | } | |
331 | rsp_break(hle, SP_STATUS_TASKDONE); | |
332 | } |
0 | 0 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
1 | 1 | * Mupen64plus-rsp-hle - alist_nead.c * |
2 | * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * | |
2 | * Mupen64Plus homepage: https://mupen64plus.org/ * | |
3 | 3 | * Copyright (C) 2014 Bobby Smiles * |
4 | 4 | * Copyright (C) 2009 Richard Goedeken * |
5 | 5 | * Copyright (C) 2002 Hacktarux * |
91 | 91 | static void CLEARBUFF(struct hle_t* hle, uint32_t w1, uint32_t w2) |
92 | 92 | { |
93 | 93 | uint16_t dmem = w1; |
94 | uint16_t count = w2; | |
94 | uint16_t count = w2 & 0xfff; | |
95 | 95 | |
96 | 96 | if (count == 0) |
97 | 97 | return; |
299 | 299 | static void HILOGAIN(struct hle_t* hle, uint32_t w1, uint32_t w2) |
300 | 300 | { |
301 | 301 | int8_t gain = (w1 >> 16); /* Q4.4 signed */ |
302 | uint16_t count = w1; | |
302 | uint16_t count = w1 & 0xfff; | |
303 | 303 | uint16_t dmem = (w2 >> 16); |
304 | 304 | |
305 | 305 | alist_multQ44(hle, dmem, count, gain); |
371 | 371 | }; |
372 | 372 | |
373 | 373 | alist_process(hle, ABI, 0x20); |
374 | rsp_break(hle, SP_STATUS_TASKDONE); | |
374 | 375 | } |
375 | 376 | |
376 | 377 | void alist_process_nead_sf(struct hle_t* hle) |
387 | 388 | }; |
388 | 389 | |
389 | 390 | alist_process(hle, ABI, 0x20); |
391 | rsp_break(hle, SP_STATUS_TASKDONE); | |
390 | 392 | } |
391 | 393 | |
392 | 394 | void alist_process_nead_sfj(struct hle_t* hle) |
403 | 405 | }; |
404 | 406 | |
405 | 407 | alist_process(hle, ABI, 0x20); |
408 | rsp_break(hle, SP_STATUS_TASKDONE); | |
406 | 409 | } |
407 | 410 | |
408 | 411 | void alist_process_nead_fz(struct hle_t* hle) |
419 | 422 | }; |
420 | 423 | |
421 | 424 | alist_process(hle, ABI, 0x20); |
425 | rsp_break(hle, SP_STATUS_TASKDONE); | |
422 | 426 | } |
423 | 427 | |
424 | 428 | void alist_process_nead_wrjb(struct hle_t* hle) |
435 | 439 | }; |
436 | 440 | |
437 | 441 | alist_process(hle, ABI, 0x20); |
442 | rsp_break(hle, SP_STATUS_TASKDONE); | |
438 | 443 | } |
439 | 444 | |
440 | 445 | void alist_process_nead_ys(struct hle_t* hle) |
449 | 454 | }; |
450 | 455 | |
451 | 456 | alist_process(hle, ABI, 0x18); |
457 | rsp_break(hle, SP_STATUS_TASKDONE); | |
452 | 458 | } |
453 | 459 | |
454 | 460 | void alist_process_nead_1080(struct hle_t* hle) |
463 | 469 | }; |
464 | 470 | |
465 | 471 | alist_process(hle, ABI, 0x18); |
472 | rsp_break(hle, SP_STATUS_TASKDONE); | |
466 | 473 | } |
467 | 474 | |
468 | 475 | void alist_process_nead_oot(struct hle_t* hle) |
477 | 484 | }; |
478 | 485 | |
479 | 486 | alist_process(hle, ABI, 0x18); |
487 | rsp_break(hle, SP_STATUS_TASKDONE); | |
480 | 488 | } |
481 | 489 | |
482 | 490 | void alist_process_nead_mm(struct hle_t* hle) |
491 | 499 | }; |
492 | 500 | |
493 | 501 | alist_process(hle, ABI, 0x18); |
502 | rsp_break(hle, SP_STATUS_TASKDONE); | |
494 | 503 | } |
495 | 504 | |
496 | 505 | void alist_process_nead_mmb(struct hle_t* hle) |
505 | 514 | }; |
506 | 515 | |
507 | 516 | alist_process(hle, ABI, 0x18); |
517 | rsp_break(hle, SP_STATUS_TASKDONE); | |
508 | 518 | } |
509 | 519 | |
510 | 520 | void alist_process_nead_ac(struct hle_t* hle) |
519 | 529 | }; |
520 | 530 | |
521 | 531 | alist_process(hle, ABI, 0x18); |
522 | } | |
532 | rsp_break(hle, SP_STATUS_TASKDONE); | |
533 | } | |
534 | ||
535 | void alist_process_nead_mats(struct hle_t* hle) | |
536 | { | |
537 | /* FIXME: implement proper ucode | |
538 | * Forward the task if possible, | |
539 | * otherwise better to have no sound than garbage sound | |
540 | */ | |
541 | if (HleForwardTask(hle->user_defined) != 0) { | |
542 | rsp_break(hle, SP_STATUS_TASKDONE); | |
543 | } | |
544 | } | |
545 | ||
546 | void alist_process_nead_efz(struct hle_t* hle) | |
547 | { | |
548 | /* FIXME: implement proper ucode | |
549 | * Forward the task if possible, | |
550 | * otherwise use FZero ucode which should be very similar | |
551 | */ | |
552 | if (HleForwardTask(hle->user_defined) != 0) { | |
553 | alist_process_nead_fz(hle); | |
554 | } | |
555 | } |
0 | 0 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
1 | 1 | * Mupen64plus-rsp-hle - arithmetics.h * |
2 | * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * | |
2 | * Mupen64Plus homepage: https://mupen64plus.org/ * | |
3 | 3 | * Copyright (C) 2014 Bobby Smiles * |
4 | 4 | * * |
5 | 5 | * This program is free software; you can redistribute it and/or modify * |
0 | 0 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
1 | 1 | * Mupen64plus-rsp-hle - audio.c * |
2 | * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * | |
2 | * Mupen64Plus homepage: https://mupen64plus.org/ * | |
3 | 3 | * Copyright (C) 2014 Bobby Smiles * |
4 | 4 | * * |
5 | 5 | * This program is free software; you can redistribute it and/or modify * |
0 | 0 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
1 | 1 | * Mupen64plus-rsp-hle - audio.h * |
2 | * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * | |
2 | * Mupen64Plus homepage: https://mupen64plus.org/ * | |
3 | 3 | * Copyright (C) 2014 Bobby Smiles * |
4 | 4 | * * |
5 | 5 | * This program is free software; you can redistribute it and/or modify * |
0 | 0 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
1 | 1 | * Mupen64plus-rsp-hle - cicx105.c * |
2 | * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * | |
2 | * Mupen64Plus homepage: https://mupen64plus.org/ * | |
3 | 3 | * Copyright (C) 2012 Bobby Smiles * |
4 | 4 | * Copyright (C) 2009 Richard Goedeken * |
5 | 5 | * Copyright (C) 2002 Hacktarux * |
49 | 49 | src += 0x8; |
50 | 50 | |
51 | 51 | } |
52 | ||
53 | rsp_break(hle, 0); | |
52 | 54 | } |
53 | 55 |
0 | 0 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
1 | 1 | * Mupen64plus-rsp-hle - common.h * |
2 | * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * | |
2 | * Mupen64Plus homepage: https://mupen64plus.org/ * | |
3 | 3 | * Copyright (C) 2014 Bobby Smiles * |
4 | 4 | * * |
5 | 5 | * This program is free software; you can redistribute it and/or modify * |
0 | 0 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
1 | 1 | * Mupen64plus-rsp-hle - hle.c * |
2 | * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * | |
2 | * Mupen64Plus homepage: https://mupen64plus.org/ * | |
3 | 3 | * Copyright (C) 2012 Bobby Smiles * |
4 | 4 | * Copyright (C) 2009 Richard Goedeken * |
5 | 5 | * Copyright (C) 2002 Hacktarux * |
34 | 34 | |
35 | 35 | #define min(a,b) (((a) < (b)) ? (a) : (b)) |
36 | 36 | |
37 | /* some rsp status flags */ | |
38 | #define SP_STATUS_HALT 0x1 | |
39 | #define SP_STATUS_BROKE 0x2 | |
40 | #define SP_STATUS_INTR_ON_BREAK 0x40 | |
41 | #define SP_STATUS_TASKDONE 0x200 | |
42 | ||
43 | 37 | /* some rdp status flags */ |
44 | 38 | #define DP_STATUS_FREEZE 0x2 |
45 | 39 | |
46 | /* some mips interface interrupt flags */ | |
47 | #define MI_INTR_SP 0x1 | |
48 | 40 | |
49 | 41 | |
50 | 42 | /* helper functions prototypes */ |
51 | 43 | static unsigned int sum_bytes(const unsigned char *bytes, unsigned int size); |
52 | 44 | static bool is_task(struct hle_t* hle); |
53 | static void rsp_break(struct hle_t* hle, unsigned int setbits); | |
54 | static void forward_gfx_task(struct hle_t* hle); | |
55 | static bool try_fast_audio_dispatching(struct hle_t* hle); | |
56 | static bool try_fast_task_dispatching(struct hle_t* hle); | |
57 | static void normal_task_dispatching(struct hle_t* hle); | |
58 | static void non_task_dispatching(struct hle_t* hle); | |
45 | static void send_dlist_to_gfx_plugin(struct hle_t* hle); | |
46 | static ucode_func_t try_audio_task_detection(struct hle_t* hle); | |
47 | static ucode_func_t try_normal_task_detection(struct hle_t* hle); | |
48 | static ucode_func_t non_task_detection(struct hle_t* hle); | |
49 | static ucode_func_t task_detection(struct hle_t* hle); | |
59 | 50 | |
60 | 51 | #ifdef ENABLE_TASK_DUMP |
61 | 52 | static void dump_binary(struct hle_t* hle, const char *const filename, |
62 | 53 | const unsigned char *const bytes, unsigned int size); |
63 | 54 | static void dump_task(struct hle_t* hle, const char *const filename); |
64 | static void dump_unknown_task(struct hle_t* hle, unsigned int sum); | |
65 | static void dump_unknown_non_task(struct hle_t* hle, unsigned int sum); | |
55 | static void dump_unknown_task(struct hle_t* hle, unsigned int uc_start); | |
56 | static void dump_unknown_non_task(struct hle_t* hle, unsigned int uc_start); | |
66 | 57 | #endif |
67 | ||
68 | /* local variables */ | |
69 | static const bool FORWARD_AUDIO = false, FORWARD_GFX = true; | |
70 | 58 | |
71 | 59 | /* Global functions */ |
72 | 60 | void hle_init(struct hle_t* hle, |
119 | 107 | |
120 | 108 | void hle_execute(struct hle_t* hle) |
121 | 109 | { |
122 | if (is_task(hle)) { | |
123 | if (!try_fast_task_dispatching(hle)) | |
124 | normal_task_dispatching(hle); | |
125 | rsp_break(hle, SP_STATUS_TASKDONE); | |
126 | } else { | |
127 | non_task_dispatching(hle); | |
128 | rsp_break(hle, 0); | |
129 | } | |
110 | uint32_t uc_start = *dmem_u32(hle, TASK_UCODE); | |
111 | uint32_t uc_dstart = *dmem_u32(hle, TASK_UCODE_DATA); | |
112 | uint32_t uc_dsize = *dmem_u32(hle, TASK_UCODE_DATA_SIZE); | |
113 | ||
114 | bool match = false; | |
115 | struct cached_ucodes_t * cached_ucodes = &hle->cached_ucodes; | |
116 | struct ucode_info_t *info = NULL; | |
117 | if (cached_ucodes->count > 0) | |
118 | info = &cached_ucodes->infos[cached_ucodes->count-1]; | |
119 | for (int i = 0; i < cached_ucodes->count; i++) | |
120 | { | |
121 | if (info->uc_start == uc_start && info->uc_dstart == uc_dstart && info->uc_dsize == uc_dsize) | |
122 | { | |
123 | match = true; | |
124 | break; | |
125 | } | |
126 | info--; | |
127 | } | |
128 | ||
129 | if (!match) | |
130 | { | |
131 | info = &cached_ucodes->infos[cached_ucodes->count]; | |
132 | info->uc_start = uc_start; | |
133 | info->uc_dstart = uc_dstart; | |
134 | info->uc_dsize = uc_dsize; | |
135 | info->uc_pfunc = task_detection(hle); | |
136 | cached_ucodes->count++; | |
137 | assert(cached_ucodes->count <= CACHED_UCODES_MAX_SIZE); | |
138 | assert(info->uc_pfunc != NULL); | |
139 | } | |
140 | ||
141 | info->uc_pfunc(hle); | |
130 | 142 | } |
131 | 143 | |
132 | 144 | /* local functions */ |
156 | 168 | return (*dmem_u32(hle, TASK_UCODE_BOOT_SIZE) <= 0x1000); |
157 | 169 | } |
158 | 170 | |
159 | static void rsp_break(struct hle_t* hle, unsigned int setbits) | |
171 | void rsp_break(struct hle_t* hle, unsigned int setbits) | |
160 | 172 | { |
161 | 173 | *hle->sp_status |= setbits | SP_STATUS_BROKE | SP_STATUS_HALT; |
162 | 174 | |
166 | 178 | } |
167 | 179 | } |
168 | 180 | |
169 | static void forward_gfx_task(struct hle_t* hle) | |
170 | { | |
181 | static void send_alist_to_audio_plugin(struct hle_t* hle) | |
182 | { | |
183 | HleProcessAlistList(hle->user_defined); | |
184 | rsp_break(hle, SP_STATUS_TASKDONE); | |
185 | } | |
186 | ||
187 | static void send_dlist_to_gfx_plugin(struct hle_t* hle) | |
188 | { | |
189 | /* Since GFX_INFO version 2, these bits are set before calling the ProcessDlistList function. | |
190 | * And the GFX plugin is responsible to unset them if needed. | |
191 | * For GFX_INFO version < 2, the GFX plugin didn't have access to sp_status so | |
192 | * it doesn't matter if we set these bits before calling ProcessDlistList function. | |
193 | */ | |
194 | *hle->sp_status |= SP_STATUS_TASKDONE | SP_STATUS_BROKE | SP_STATUS_HALT; | |
195 | ||
171 | 196 | HleProcessDlistList(hle->user_defined); |
172 | } | |
173 | ||
174 | static bool try_fast_audio_dispatching(struct hle_t* hle) | |
197 | ||
198 | if ((*hle->sp_status & SP_STATUS_INTR_ON_BREAK) && (*hle->sp_status & (SP_STATUS_TASKDONE | SP_STATUS_BROKE | SP_STATUS_HALT))) { | |
199 | *hle->mi_intr |= MI_INTR_SP; | |
200 | HleCheckInterrupts(hle->user_defined); | |
201 | } | |
202 | } | |
203 | ||
204 | static void task_done(struct hle_t* hle) | |
205 | { | |
206 | rsp_break(hle, SP_STATUS_TASKDONE); | |
207 | } | |
208 | ||
209 | static void unknown_ucode(struct hle_t* hle) | |
210 | { | |
211 | /* Forward task to RSP Fallback. | |
212 | * If task is not forwarded, use the regular "unknown ucode" path */ | |
213 | if (HleForwardTask(hle->user_defined) != 0) { | |
214 | ||
215 | uint32_t uc_start = *dmem_u32(hle, TASK_UCODE); | |
216 | HleWarnMessage(hle->user_defined, "unknown RSP code: uc_start: %x PC:%x", uc_start, *hle->sp_pc); | |
217 | #ifdef ENABLE_TASK_DUMP | |
218 | dump_unknown_non_task(hle, uc_start); | |
219 | #endif | |
220 | } | |
221 | } | |
222 | ||
223 | static void unknown_task(struct hle_t* hle) | |
224 | { | |
225 | /* Forward task to RSP Fallback. | |
226 | * If task is not forwarded, use the regular "unknown task" path */ | |
227 | if (HleForwardTask(hle->user_defined) != 0) { | |
228 | ||
229 | /* Send task_done signal for unknown ucodes to allow further processings */ | |
230 | rsp_break(hle, SP_STATUS_TASKDONE); | |
231 | ||
232 | uint32_t uc_start = *dmem_u32(hle, TASK_UCODE); | |
233 | HleWarnMessage(hle->user_defined, "unknown OSTask: uc_start: %x PC:%x", uc_start, *hle->sp_pc); | |
234 | #ifdef ENABLE_TASK_DUMP | |
235 | dump_unknown_task(hle, uc_start); | |
236 | #endif | |
237 | } | |
238 | } | |
239 | ||
240 | static ucode_func_t try_audio_task_detection(struct hle_t* hle) | |
175 | 241 | { |
176 | 242 | /* identify audio ucode by using the content of ucode_data */ |
177 | 243 | uint32_t ucode_data = *dmem_u32(hle, TASK_UCODE_DATA); |
183 | 249 | switch(v) |
184 | 250 | { |
185 | 251 | case 0x1e24138c: /* audio ABI (most common) */ |
186 | alist_process_audio(hle); return true; | |
252 | return &alist_process_audio; | |
187 | 253 | case 0x1dc8138c: /* GoldenEye */ |
188 | alist_process_audio_ge(hle); return true; | |
254 | return &alist_process_audio_ge; | |
189 | 255 | case 0x1e3c1390: /* BlastCorp, DiddyKongRacing */ |
190 | alist_process_audio_bc(hle); return true; | |
256 | return &alist_process_audio_bc; | |
191 | 257 | default: |
192 | 258 | HleWarnMessage(hle->user_defined, "ABI1 identification regression: v=%08x", v); |
193 | 259 | } |
196 | 262 | switch(v) |
197 | 263 | { |
198 | 264 | case 0x11181350: /* MarioKart, WaveRace (E) */ |
199 | alist_process_nead_mk(hle); return true; | |
265 | return &alist_process_nead_mk; | |
200 | 266 | case 0x111812e0: /* StarFox (J) */ |
201 | alist_process_nead_sfj(hle); return true; | |
267 | return &alist_process_nead_sfj; | |
202 | 268 | case 0x110412ac: /* WaveRace (J RevB) */ |
203 | alist_process_nead_wrjb(hle); return true; | |
269 | return &alist_process_nead_wrjb; | |
204 | 270 | case 0x110412cc: /* StarFox/LylatWars (except J) */ |
205 | alist_process_nead_sf(hle); return true; | |
271 | return &alist_process_nead_sf; | |
206 | 272 | case 0x1cd01250: /* FZeroX */ |
207 | alist_process_nead_fz(hle); return true; | |
273 | return &alist_process_nead_fz; | |
208 | 274 | case 0x1f08122c: /* YoshisStory */ |
209 | alist_process_nead_ys(hle); return true; | |
275 | return &alist_process_nead_ys; | |
210 | 276 | case 0x1f38122c: /* 1080° Snowboarding */ |
211 | alist_process_nead_1080(hle); return true; | |
277 | return &alist_process_nead_1080; | |
212 | 278 | case 0x1f681230: /* Zelda OoT / Zelda MM (J, J RevA) */ |
213 | alist_process_nead_oot(hle); return true; | |
279 | return &alist_process_nead_oot; | |
214 | 280 | case 0x1f801250: /* Zelda MM (except J, J RevA, E Beta), PokemonStadium 2 */ |
215 | alist_process_nead_mm(hle); return true; | |
281 | return &alist_process_nead_mm; | |
216 | 282 | case 0x109411f8: /* Zelda MM (E Beta) */ |
217 | alist_process_nead_mmb(hle); return true; | |
283 | return &alist_process_nead_mmb; | |
218 | 284 | case 0x1eac11b8: /* AnimalCrossing */ |
219 | alist_process_nead_ac(hle); return true; | |
285 | return &alist_process_nead_ac; | |
220 | 286 | case 0x00010010: /* MusyX v2 (IndianaJones, BattleForNaboo) */ |
221 | musyx_v2_task(hle); return true; | |
222 | ||
287 | return &musyx_v2_task; | |
288 | case 0x1f701238: /* Mario Artist Talent Studio */ | |
289 | return &alist_process_nead_mats; | |
290 | case 0x1f4c1230: /* FZeroX Expansion */ | |
291 | return &alist_process_nead_efz; | |
223 | 292 | default: |
224 | 293 | HleWarnMessage(hle->user_defined, "ABI2 identification regression: v=%08x", v); |
225 | 294 | } |
232 | 301 | RogueSquadron, ResidentEvil2, PolarisSnoCross, |
233 | 302 | TheWorldIsNotEnough, RugratsInParis, NBAShowTime, |
234 | 303 | HydroThunder, Tarzan, GauntletLegend, Rush2049 */ |
235 | musyx_v1_task(hle); return true; | |
304 | return &musyx_v1_task; | |
236 | 305 | case 0x0000127c: /* naudio (many games) */ |
237 | alist_process_naudio(hle); return true; | |
306 | return &alist_process_naudio; | |
238 | 307 | case 0x00001280: /* BanjoKazooie */ |
239 | alist_process_naudio_bk(hle); return true; | |
308 | return &alist_process_naudio_bk; | |
240 | 309 | case 0x1c58126c: /* DonkeyKong */ |
241 | alist_process_naudio_dk(hle); return true; | |
310 | return &alist_process_naudio_dk; | |
242 | 311 | case 0x1ae8143c: /* BanjoTooie, JetForceGemini, MickeySpeedWayUSA, PerfectDark */ |
243 | alist_process_naudio_mp3(hle); return true; | |
312 | return &alist_process_naudio_mp3; | |
244 | 313 | case 0x1ab0140c: /* ConkerBadFurDay */ |
245 | alist_process_naudio_cbfd(hle); return true; | |
314 | return &alist_process_naudio_cbfd; | |
246 | 315 | |
247 | 316 | default: |
248 | 317 | HleWarnMessage(hle->user_defined, "ABI3 identification regression: v=%08x", v); |
249 | 318 | } |
250 | 319 | } |
251 | 320 | |
252 | return false; | |
253 | } | |
254 | ||
255 | static bool try_fast_task_dispatching(struct hle_t* hle) | |
256 | { | |
257 | /* identify task ucode by its type */ | |
258 | switch (*dmem_u32(hle, TASK_TYPE)) { | |
259 | case 1: | |
260 | if (FORWARD_GFX) { | |
261 | forward_gfx_task(hle); | |
262 | return true; | |
263 | } | |
264 | break; | |
265 | ||
266 | case 2: | |
267 | if (FORWARD_AUDIO) { | |
268 | HleProcessAlistList(hle->user_defined); | |
269 | return true; | |
270 | } else if (try_fast_audio_dispatching(hle)) | |
271 | return true; | |
272 | break; | |
273 | ||
274 | case 7: | |
275 | HleShowCFB(hle->user_defined); | |
276 | return true; | |
277 | } | |
278 | ||
279 | return false; | |
280 | } | |
281 | ||
282 | static void normal_task_dispatching(struct hle_t* hle) | |
283 | { | |
284 | const unsigned int sum = | |
321 | return NULL; | |
322 | } | |
323 | ||
324 | static ucode_func_t try_normal_task_detection(struct hle_t* hle) | |
325 | { | |
326 | unsigned int sum = | |
285 | 327 | sum_bytes((void*)dram_u32(hle, *dmem_u32(hle, TASK_UCODE)), min(*dmem_u32(hle, TASK_UCODE_SIZE), 0xf80) >> 1); |
286 | 328 | |
287 | 329 | switch (sum) { |
288 | 330 | /* StoreVe12: found in Zelda Ocarina of Time [misleading task->type == 4] */ |
289 | 331 | case 0x278: |
290 | 332 | /* Nothing to emulate */ |
291 | return; | |
333 | return &task_done; | |
292 | 334 | |
293 | 335 | /* GFX: Twintris [misleading task->type == 0] */ |
294 | 336 | case 0x212ee: |
295 | if (FORWARD_GFX) { | |
296 | forward_gfx_task(hle); | |
297 | return; | |
337 | if (hle->hle_gfx) { | |
338 | return &send_dlist_to_gfx_plugin; | |
298 | 339 | } |
299 | break; | |
340 | return NULL; | |
300 | 341 | |
301 | 342 | /* JPEG: found in Pokemon Stadium J */ |
302 | 343 | case 0x2c85a: |
303 | jpeg_decode_PS0(hle); | |
304 | return; | |
344 | return &jpeg_decode_PS0; | |
305 | 345 | |
306 | 346 | /* JPEG: found in Zelda Ocarina of Time, Pokemon Stadium 1, Pokemon Stadium 2 */ |
307 | 347 | case 0x2caa6: |
308 | jpeg_decode_PS(hle); | |
309 | return; | |
348 | return &jpeg_decode_PS; | |
310 | 349 | |
311 | 350 | /* JPEG: found in Ogre Battle, Bottom of the 9th */ |
312 | 351 | case 0x130de: |
313 | 352 | case 0x278b0: |
314 | jpeg_decode_OB(hle); | |
315 | return; | |
316 | } | |
317 | ||
318 | HleWarnMessage(hle->user_defined, "unknown OSTask: sum: %x PC:%x", sum, *hle->sp_pc); | |
319 | #ifdef ENABLE_TASK_DUMP | |
320 | dump_unknown_task(hle, sum); | |
321 | #endif | |
322 | } | |
323 | ||
324 | static void non_task_dispatching(struct hle_t* hle) | |
353 | return &jpeg_decode_OB; | |
354 | } | |
355 | ||
356 | /* Resident Evil 2 */ | |
357 | sum = sum_bytes((void*)dram_u32(hle, *dmem_u32(hle, TASK_UCODE)), 256); | |
358 | switch (sum) { | |
359 | ||
360 | case 0x450f: | |
361 | return &resize_bilinear_task; | |
362 | ||
363 | case 0x3b44: | |
364 | return &decode_video_frame_task; | |
365 | ||
366 | case 0x3d84: | |
367 | return &fill_video_double_buffer_task; | |
368 | } | |
369 | ||
370 | /* HVQM */ | |
371 | sum = sum_bytes((void*)dram_u32(hle, *dmem_u32(hle, TASK_UCODE)), 1488); | |
372 | switch (sum) { | |
373 | case 0x19495: | |
374 | return &hvqm2_decode_sp1_task; | |
375 | ||
376 | case 0x19728: | |
377 | return &hvqm2_decode_sp2_task; | |
378 | } | |
379 | ||
380 | return NULL; | |
381 | } | |
382 | ||
383 | static ucode_func_t non_task_detection(struct hle_t* hle) | |
325 | 384 | { |
326 | 385 | const unsigned int sum = sum_bytes(hle->imem, 44); |
327 | 386 | |
328 | 387 | if (sum == 0x9e2) |
329 | 388 | { |
330 | 389 | /* CIC x105 ucode (used during boot of CIC x105 games) */ |
331 | cicx105_ucode(hle); | |
332 | return; | |
333 | } | |
334 | ||
335 | HleWarnMessage(hle->user_defined, "unknown RSP code: sum: %x PC:%x", sum, *hle->sp_pc); | |
390 | return &cicx105_ucode; | |
391 | } | |
392 | return &unknown_ucode; | |
393 | } | |
394 | ||
395 | static ucode_func_t task_detection(struct hle_t* hle) | |
396 | { | |
397 | if (is_task(hle)) { | |
398 | ucode_func_t uc_pfunc; | |
399 | uint32_t type = *dmem_u32(hle, TASK_TYPE); | |
400 | ||
401 | if (type == 2) { | |
402 | if (hle->hle_aud) { | |
403 | return &send_alist_to_audio_plugin; | |
404 | } | |
405 | uc_pfunc = try_audio_task_detection(hle); | |
406 | if (uc_pfunc) | |
407 | return uc_pfunc; | |
408 | } | |
409 | ||
410 | uc_pfunc = try_normal_task_detection(hle); | |
411 | if (uc_pfunc) | |
412 | return uc_pfunc; | |
413 | ||
414 | if (type == 1) { | |
415 | if (hle->hle_gfx) { | |
416 | return &send_dlist_to_gfx_plugin; | |
417 | } | |
418 | } | |
419 | ||
420 | return &unknown_task; | |
421 | } | |
422 | else { | |
423 | return non_task_detection(hle); | |
424 | } | |
425 | } | |
426 | ||
336 | 427 | #ifdef ENABLE_TASK_DUMP |
337 | dump_unknown_non_task(hle, sum); | |
338 | #endif | |
339 | } | |
340 | ||
341 | ||
342 | #ifdef ENABLE_TASK_DUMP | |
343 | static void dump_unknown_task(struct hle_t* hle, unsigned int sum) | |
428 | static void dump_unknown_task(struct hle_t* hle, unsigned int uc_start) | |
344 | 429 | { |
345 | 430 | char filename[256]; |
346 | 431 | uint32_t ucode = *dmem_u32(hle, TASK_UCODE); |
347 | 432 | uint32_t ucode_data = *dmem_u32(hle, TASK_UCODE_DATA); |
348 | 433 | uint32_t data_ptr = *dmem_u32(hle, TASK_DATA_PTR); |
349 | 434 | |
350 | sprintf(&filename[0], "task_%x.log", sum); | |
435 | sprintf(&filename[0], "task_%x.log", uc_start); | |
351 | 436 | dump_task(hle, filename); |
352 | 437 | |
353 | 438 | /* dump ucode_boot */ |
354 | sprintf(&filename[0], "ucode_boot_%x.bin", sum); | |
439 | sprintf(&filename[0], "ucode_boot_%x.bin", uc_start); | |
355 | 440 | dump_binary(hle, filename, (void*)dram_u32(hle, *dmem_u32(hle, TASK_UCODE_BOOT)), *dmem_u32(hle, TASK_UCODE_BOOT_SIZE)); |
356 | 441 | |
357 | 442 | /* dump ucode */ |
358 | 443 | if (ucode != 0) { |
359 | sprintf(&filename[0], "ucode_%x.bin", sum); | |
444 | sprintf(&filename[0], "ucode_%x.bin", uc_start); | |
360 | 445 | dump_binary(hle, filename, (void*)dram_u32(hle, ucode), 0xf80); |
361 | 446 | } |
362 | 447 | |
363 | 448 | /* dump ucode_data */ |
364 | 449 | if (ucode_data != 0) { |
365 | sprintf(&filename[0], "ucode_data_%x.bin", sum); | |
450 | sprintf(&filename[0], "ucode_data_%x.bin", uc_start); | |
366 | 451 | dump_binary(hle, filename, (void*)dram_u32(hle, ucode_data), *dmem_u32(hle, TASK_UCODE_DATA_SIZE)); |
367 | 452 | } |
368 | 453 | |
369 | 454 | /* dump data */ |
370 | 455 | if (data_ptr != 0) { |
371 | sprintf(&filename[0], "data_%x.bin", sum); | |
456 | sprintf(&filename[0], "data_%x.bin", uc_start); | |
372 | 457 | dump_binary(hle, filename, (void*)dram_u32(hle, data_ptr), *dmem_u32(hle, TASK_DATA_SIZE)); |
373 | 458 | } |
374 | 459 | } |
375 | 460 | |
376 | static void dump_unknown_non_task(struct hle_t* hle, unsigned int sum) | |
461 | static void dump_unknown_non_task(struct hle_t* hle, unsigned int uc_start) | |
377 | 462 | { |
378 | 463 | char filename[256]; |
379 | 464 | |
380 | 465 | /* dump IMEM & DMEM for further analysis */ |
381 | sprintf(&filename[0], "imem_%x.bin", sum); | |
466 | sprintf(&filename[0], "imem_%x.bin", uc_start); | |
382 | 467 | dump_binary(hle, filename, hle->imem, 0x1000); |
383 | 468 | |
384 | sprintf(&filename[0], "dmem_%x.bin", sum); | |
469 | sprintf(&filename[0], "dmem_%x.bin", uc_start); | |
385 | 470 | dump_binary(hle, filename, hle->dmem, 0x1000); |
386 | 471 | } |
387 | 472 |
0 | 0 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
1 | 1 | * Mupen64plus-rsp-hle - hle.h * |
2 | * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * | |
2 | * Mupen64Plus homepage: https://mupen64plus.org/ * | |
3 | 3 | * Copyright (C) 2014 Bobby Smiles * |
4 | 4 | * * |
5 | 5 | * This program is free software; you can redistribute it and/or modify * |
0 | 0 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
1 | 1 | * Mupen64plus-rsp-hle - hle_external.h * |
2 | * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * | |
2 | * Mupen64Plus homepage: https://mupen64plus.org/ * | |
3 | 3 | * Copyright (C) 2014 Bobby Smiles * |
4 | 4 | * * |
5 | 5 | * This program is free software; you can redistribute it and/or modify * |
21 | 21 | #ifndef HLE_EXTERNAL_H |
22 | 22 | #define HLE_EXTERNAL_H |
23 | 23 | |
24 | #if defined(__GNUC__) | |
25 | #define ATTR_FMT(fmtpos, attrpos) __attribute__ ((format (printf, fmtpos, attrpos))) | |
26 | #else | |
27 | #define ATTR_FMT(fmtpos, attrpos) | |
28 | #endif | |
29 | ||
24 | 30 | /* users of the hle core are expected to define these functions */ |
25 | 31 | |
26 | void HleVerboseMessage(void* user_defined, const char *message, ...); | |
27 | void HleErrorMessage(void* user_defined, const char *message, ...); | |
28 | void HleWarnMessage(void* user_defined, const char *message, ...); | |
32 | void HleVerboseMessage(void* user_defined, const char *message, ...) ATTR_FMT(2, 3); | |
33 | void HleInfoMessage(void* user_defined, const char *message, ...) ATTR_FMT(2, 3); | |
34 | void HleErrorMessage(void* user_defined, const char *message, ...) ATTR_FMT(2, 3); | |
35 | void HleWarnMessage(void* user_defined, const char *message, ...) ATTR_FMT(2, 3); | |
29 | 36 | |
30 | 37 | void HleCheckInterrupts(void* user_defined); |
31 | 38 | void HleProcessDlistList(void* user_defined); |
32 | 39 | void HleProcessAlistList(void* user_defined); |
33 | 40 | void HleProcessRdpList(void* user_defined); |
34 | 41 | void HleShowCFB(void* user_defined); |
42 | int HleForwardTask(void* user_defined); | |
35 | 43 | |
36 | 44 | #endif |
37 | 45 |
0 | 0 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
1 | 1 | * Mupen64plus-rsp-hle - hle_internal.h * |
2 | * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * | |
2 | * Mupen64Plus homepage: https://mupen64plus.org/ * | |
3 | 3 | * Copyright (C) 2014 Bobby Smiles * |
4 | 4 | * * |
5 | 5 | * This program is free software; you can redistribute it and/or modify * |
56 | 56 | /* for user convenience, this will be passed to "external" functions */ |
57 | 57 | void* user_defined; |
58 | 58 | |
59 | int hle_gfx; | |
60 | int hle_aud; | |
59 | 61 | |
60 | 62 | /* alist.c */ |
61 | 63 | uint8_t alist_buffer[0x1000]; |
71 | 73 | |
72 | 74 | /* mp3.c */ |
73 | 75 | uint8_t mp3_buffer[0x1000]; |
76 | ||
77 | struct cached_ucodes_t cached_ucodes; | |
74 | 78 | }; |
79 | ||
80 | /* some mips interface interrupt flags */ | |
81 | #define MI_INTR_SP 0x1 | |
82 | ||
83 | /* some rsp status flags */ | |
84 | #define SP_STATUS_HALT 0x1 | |
85 | #define SP_STATUS_BROKE 0x2 | |
86 | #define SP_STATUS_INTR_ON_BREAK 0x40 | |
87 | #define SP_STATUS_TASKDONE 0x200 | |
88 | ||
89 | void rsp_break(struct hle_t* hle, unsigned int setbits); | |
75 | 90 | |
76 | 91 | #endif |
77 | 92 |
0 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * | |
1 | * Mupen64plus-rsp-hle - hvqm.c * | |
2 | * Mupen64Plus homepage: https://mupen64plus.org/ * | |
3 | * Copyright (C) 2020 Gilles Siberlin * | |
4 | * * | |
5 | * This program is free software; you can redistribute it and/or modify * | |
6 | * it under the terms of the GNU General Public License as published by * | |
7 | * the Free Software Foundation; either version 2 of the License, or * | |
8 | * (at your option) any later version. * | |
9 | * * | |
10 | * This program is distributed in the hope that it will be useful, * | |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * | |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | |
13 | * GNU General Public License for more details. * | |
14 | * * | |
15 | * You should have received a copy of the GNU General Public License * | |
16 | * along with this program; if not, write to the * | |
17 | * Free Software Foundation, Inc., * | |
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * | |
19 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | |
20 | ||
21 | #include <assert.h> | |
22 | #include <stdio.h> | |
23 | #include <stdint.h> | |
24 | #include <string.h> | |
25 | #include <stdlib.h> | |
26 | ||
27 | #include "hle_external.h" | |
28 | #include "hle_internal.h" | |
29 | #include "memory.h" | |
30 | ||
31 | /* Nest size */ | |
32 | #define HVQM2_NESTSIZE_L 70 /* Number of elements on long side */ | |
33 | #define HVQM2_NESTSIZE_S 38 /* Number of elements on short side */ | |
34 | #define HVQM2_NESTSIZE (HVQM2_NESTSIZE_L * HVQM2_NESTSIZE_S) | |
35 | ||
36 | struct HVQM2Block { | |
37 | uint8_t nbase; | |
38 | uint8_t dc; | |
39 | uint8_t dc_l; | |
40 | uint8_t dc_r; | |
41 | uint8_t dc_u; | |
42 | uint8_t dc_d; | |
43 | }; | |
44 | ||
45 | struct HVQM2Basis { | |
46 | uint8_t sx; | |
47 | uint8_t sy; | |
48 | int16_t scale; | |
49 | uint16_t offset; | |
50 | uint16_t lineskip; | |
51 | }; | |
52 | ||
53 | struct HVQM2Arg { | |
54 | uint32_t info; | |
55 | uint32_t buf; | |
56 | uint16_t buf_width; | |
57 | uint8_t chroma_step_h; | |
58 | uint8_t chroma_step_v; | |
59 | uint16_t hmcus; | |
60 | uint16_t vmcus; | |
61 | uint8_t alpha; | |
62 | uint32_t nest; | |
63 | }; | |
64 | ||
65 | struct RGBA { | |
66 | uint8_t r; | |
67 | uint8_t g; | |
68 | uint8_t b; | |
69 | uint8_t a; | |
70 | }; | |
71 | ||
72 | static struct HVQM2Arg arg; | |
73 | ||
74 | static const int16_t constant[5][16] = { | |
75 | {0x0006,0x0008,0x0008,0x0006,0x0008,0x000A,0x000A,0x0008,0x0008,0x000A,0x000A,0x0008,0x0006,0x0008,0x0008,0x0006}, | |
76 | {0x0002,0x0000,0xFFFF,0xFFFF,0x0002,0x0000,0xFFFF,0xFFFF,0x0002,0x0000,0xFFFF,0xFFFF,0x0002,0x0000,0xFFFF,0xFFFF}, | |
77 | {0xFFFF,0xFFFF,0x0000,0x0002,0xFFFF,0xFFFF,0x0000,0x0002,0xFFFF,0xFFFF,0x0000,0x0002,0xFFFF,0xFFFF,0x0000,0x0002}, | |
78 | {0x0002,0x0002,0x0002,0x0002,0x0000,0x0000,0x0000,0x0000,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF}, | |
79 | {0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0x0000,0x0000,0x0000,0x0000,0x0002,0x0002,0x0002,0x0002} | |
80 | }; | |
81 | ||
82 | static int process_info(struct hle_t* hle, uint8_t* base, int16_t* out) | |
83 | { | |
84 | struct HVQM2Block block; | |
85 | uint8_t nbase = *base; | |
86 | ||
87 | dram_load_u8(hle, (uint8_t*)&block, arg.info, sizeof(struct HVQM2Block)); | |
88 | arg.info += 8; | |
89 | ||
90 | *base = block.nbase & 0x7; | |
91 | ||
92 | if ((block.nbase & nbase) != 0) | |
93 | return 0; | |
94 | ||
95 | if (block.nbase == 0) | |
96 | { | |
97 | //LABEL8 | |
98 | for (int i = 0; i < 16; i++) | |
99 | { | |
100 | out[i] = constant[0][i] * block.dc; | |
101 | out[i] += constant[1][i] * block.dc_l; | |
102 | out[i] += constant[2][i] * block.dc_r; | |
103 | out[i] += constant[3][i] * block.dc_u; | |
104 | out[i] += constant[4][i] * block.dc_d; | |
105 | out[i] += 4; | |
106 | out[i] >>= 3; | |
107 | } | |
108 | } | |
109 | else if ((block.nbase & 0xf) == 0) | |
110 | { | |
111 | //LABEL7 | |
112 | for (int i = 0; i < 16; i++) | |
113 | { | |
114 | out[i] = *dram_u8(hle, arg.info); | |
115 | arg.info++; | |
116 | } | |
117 | } | |
118 | else if (*base == 0) | |
119 | { | |
120 | //LABEL6 | |
121 | for (int i = 0; i < 16; i++) | |
122 | { | |
123 | out[i] = *(int8_t*)dram_u8(hle, arg.info) + block.dc; | |
124 | arg.info++; | |
125 | } | |
126 | } | |
127 | else | |
128 | { | |
129 | //LABEL5 | |
130 | struct HVQM2Basis basis; | |
131 | ||
132 | for (int i = 0; i < 16; i++) | |
133 | out[i] = block.dc; | |
134 | ||
135 | for (; *base != 0; (*base)--) | |
136 | { | |
137 | basis.sx = *dram_u8(hle, arg.info); | |
138 | arg.info++; | |
139 | basis.sy = *dram_u8(hle, arg.info); | |
140 | arg.info++; | |
141 | basis.scale = *dram_u16(hle, arg.info); | |
142 | arg.info += 2; | |
143 | basis.offset = *dram_u16(hle, arg.info); | |
144 | arg.info += 2; | |
145 | basis.lineskip = *dram_u16(hle, arg.info); | |
146 | arg.info += 2; | |
147 | ||
148 | int16_t vec[16]; | |
149 | uint32_t addr = arg.nest + basis.offset; | |
150 | int shift = (basis.sx != 0) ? 1 : 0; | |
151 | ||
152 | //LABEL9 | |
153 | //LABEL10 | |
154 | for (int i = 0; i < 16; i += 4) | |
155 | { | |
156 | vec[i] = *dram_u8(hle, addr); | |
157 | vec[i + 1] = *dram_u8(hle, addr + (1 << shift)); | |
158 | vec[i + 2] = *dram_u8(hle, addr + (2 << shift)); | |
159 | vec[i + 3] = *dram_u8(hle, addr + (3 << shift)); | |
160 | addr += basis.lineskip; | |
161 | } | |
162 | ||
163 | //LABEL11 | |
164 | int16_t sum = 0x8; | |
165 | for (int i = 0; i < 16; i++) | |
166 | sum += vec[i]; | |
167 | ||
168 | sum >>= 4; | |
169 | ||
170 | int16_t max = 0; | |
171 | for (int i = 0; i < 16; i++) | |
172 | { | |
173 | vec[i] -= sum; | |
174 | max = (abs(vec[i]) > max) ? abs(vec[i]) : max; | |
175 | } | |
176 | ||
177 | double dmax = 0.0; | |
178 | if (max > 0) | |
179 | dmax = (double)(basis.scale << 2) / (double)max; | |
180 | ||
181 | for (int i = 0; i < 16; i++) | |
182 | out[i] += (vec[i] < 0) ? (int16_t)((double)vec[i] * dmax - 0.5) : (int16_t)((double)vec[i] * dmax + 0.5); | |
183 | ||
184 | block.nbase &= 8; | |
185 | } | |
186 | ||
187 | assert(block.nbase == 0); | |
188 | //if(block.nbase != 0) | |
189 | // LABEL6 | |
190 | } | |
191 | ||
192 | return 1; | |
193 | } | |
194 | ||
195 | #define SATURATE8(x) ((unsigned int) x <= 255 ? x : (x < 0 ? 0: 255)) | |
196 | static struct RGBA YCbCr_to_RGBA(int16_t Y, int16_t Cb, int16_t Cr, uint8_t alpha) | |
197 | { | |
198 | struct RGBA color; | |
199 | ||
200 | //Format S10.6 | |
201 | int r = (int)(((double)Y + 0.5) + (1.765625 * (double)(Cr - 128))); | |
202 | int g = (int)(((double)Y + 0.5) - (0.34375 * (double)(Cr - 128)) - (0.71875 * (double)(Cb - 128))); | |
203 | int b = (int)(((double)Y + 0.5) + (1.40625 * (double)(Cb - 128))); | |
204 | ||
205 | color.r = SATURATE8(r); | |
206 | color.g = SATURATE8(g); | |
207 | color.b = SATURATE8(b); | |
208 | color.a = alpha; | |
209 | ||
210 | return color; | |
211 | } | |
212 | ||
213 | void store_rgba5551(struct hle_t* hle, struct RGBA color, uint32_t * addr) | |
214 | { | |
215 | uint16_t pixel = ((color.b >> 3) << 11) | ((color.g >> 3) << 6) | ((color.r >> 3) << 1) | (color.a & 1); | |
216 | dram_store_u16(hle, &pixel, *addr, 1); | |
217 | *addr += 2; | |
218 | } | |
219 | ||
220 | void store_rgba8888(struct hle_t* hle, struct RGBA color, uint32_t * addr) | |
221 | { | |
222 | uint32_t pixel = (color.b << 24) | (color.g << 16) | (color.r << 8) | color.a; | |
223 | dram_store_u32(hle, &pixel, *addr, 1); | |
224 | *addr += 4; | |
225 | } | |
226 | ||
227 | typedef void(*store_pixel_t)(struct hle_t* hle, struct RGBA color, uint32_t * addr); | |
228 | ||
229 | static void hvqm2_decode(struct hle_t* hle, int is32) | |
230 | { | |
231 | //uint32_t uc_data_ptr = *dmem_u32(hle, TASK_UCODE_DATA); | |
232 | uint32_t data_ptr = *dmem_u32(hle, TASK_DATA_PTR); | |
233 | ||
234 | assert((*dmem_u32(hle, TASK_FLAGS) & 0x1) == 0); | |
235 | ||
236 | /* Fill HVQM2Arg struct */ | |
237 | arg.info = *dram_u32(hle, data_ptr); | |
238 | data_ptr += 4; | |
239 | arg.buf = *dram_u32(hle, data_ptr); | |
240 | data_ptr += 4; | |
241 | arg.buf_width = *dram_u16(hle, data_ptr); | |
242 | data_ptr += 2; | |
243 | arg.chroma_step_h = *dram_u8(hle, data_ptr); | |
244 | data_ptr++; | |
245 | arg.chroma_step_v = *dram_u8(hle, data_ptr); | |
246 | data_ptr++; | |
247 | arg.hmcus = *dram_u16(hle, data_ptr); | |
248 | data_ptr += 2; | |
249 | arg.vmcus = *dram_u16(hle, data_ptr); | |
250 | data_ptr += 2; | |
251 | arg.alpha = *dram_u8(hle, data_ptr); | |
252 | arg.nest = data_ptr + 1; | |
253 | ||
254 | assert(arg.chroma_step_h == 2); | |
255 | assert((arg.chroma_step_v == 1) || (arg.chroma_step_v == 2)); | |
256 | assert((*hle->sp_status & 0x80) == 0); //SP_STATUS_YIELD | |
257 | ||
258 | int length, skip; | |
259 | store_pixel_t store_pixel; | |
260 | ||
261 | if (is32) | |
262 | { | |
263 | length = 0x20; | |
264 | skip = arg.buf_width << 2; | |
265 | arg.buf_width <<= 4; | |
266 | store_pixel = &store_rgba8888; | |
267 | } | |
268 | else | |
269 | { | |
270 | length = 0x10; | |
271 | skip = arg.buf_width << 1; | |
272 | arg.buf_width <<= 3; | |
273 | store_pixel = &store_rgba5551; | |
274 | } | |
275 | ||
276 | if (arg.chroma_step_v == 2) | |
277 | arg.buf_width += arg.buf_width; | |
278 | ||
279 | for (int i = arg.vmcus; i != 0; i--) | |
280 | { | |
281 | uint32_t out; | |
282 | int j; | |
283 | ||
284 | for (j = arg.hmcus, out = arg.buf; j != 0; j--, out += length) | |
285 | { | |
286 | uint8_t base = 0x80; | |
287 | int16_t Cb[16], Cr[16], Y1[32], Y2[32]; | |
288 | int16_t* pCb = Cb; | |
289 | int16_t* pCr = Cr; | |
290 | int16_t* pY1 = Y1; | |
291 | int16_t* pY2 = Y2; | |
292 | ||
293 | if (arg.chroma_step_v == 2) | |
294 | { | |
295 | if (process_info(hle, &base, pY1) == 0) | |
296 | continue; | |
297 | if (process_info(hle, &base, pY2) == 0) | |
298 | continue; | |
299 | ||
300 | pY1 = &Y1[16]; | |
301 | pY2 = &Y2[16]; | |
302 | } | |
303 | ||
304 | if (process_info(hle, &base, pY1) == 0) | |
305 | continue; | |
306 | if (process_info(hle, &base, pY2) == 0) | |
307 | continue; | |
308 | if (process_info(hle, &base, Cr) == 0) | |
309 | continue; | |
310 | if (process_info(hle, &base, Cb) == 0) | |
311 | continue; | |
312 | ||
313 | pY1 = Y1; | |
314 | pY2 = Y2; | |
315 | ||
316 | uint32_t out_buf = out; | |
317 | for (int k = 0; k < 4; k++) | |
318 | { | |
319 | for (int m = 0; m < arg.chroma_step_v; m++) | |
320 | { | |
321 | uint32_t addr = out_buf; | |
322 | for (int l = 0; l < 4; l++) | |
323 | { | |
324 | struct RGBA color = YCbCr_to_RGBA(pY1[l], pCb[l >> 1], pCr[l >> 1], arg.alpha); | |
325 | store_pixel(hle, color, &addr); | |
326 | } | |
327 | for (int l = 0; l < 4; l++) | |
328 | { | |
329 | struct RGBA color = YCbCr_to_RGBA(pY2[l], pCb[(l + 4) >> 1], pCr[(l + 4) >> 1], arg.alpha); | |
330 | store_pixel(hle, color, &addr); | |
331 | } | |
332 | out_buf += skip; | |
333 | pY1 += 4; | |
334 | pY2 += 4; | |
335 | } | |
336 | pCr += 4; | |
337 | pCb += 4; | |
338 | } | |
339 | } | |
340 | arg.buf += arg.buf_width; | |
341 | } | |
342 | rsp_break(hle, SP_STATUS_TASKDONE); | |
343 | } | |
344 | ||
345 | void hvqm2_decode_sp1_task(struct hle_t* hle) | |
346 | { | |
347 | hvqm2_decode(hle, 0); | |
348 | } | |
349 | ||
350 | void hvqm2_decode_sp2_task(struct hle_t* hle) | |
351 | { | |
352 | hvqm2_decode(hle, 1); | |
353 | }⏎ |
0 | 0 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
1 | 1 | * Mupen64plus-rsp-hle - jpeg.c * |
2 | * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * | |
2 | * Mupen64Plus homepage: https://mupen64plus.org/ * | |
3 | 3 | * Copyright (C) 2012 Bobby Smiles * |
4 | 4 | * Copyright (C) 2009 Richard Goedeken * |
5 | 5 | * Copyright (C) 2002 Hacktarux * |
140 | 140 | void jpeg_decode_PS0(struct hle_t* hle) |
141 | 141 | { |
142 | 142 | jpeg_decode_std(hle, "PS0", RescaleYSubBlock, RescaleUVSubBlock, EmitYUVTileLine); |
143 | rsp_break(hle, SP_STATUS_TASKDONE); | |
143 | 144 | } |
144 | 145 | |
145 | 146 | /*************************************************************************** |
149 | 150 | void jpeg_decode_PS(struct hle_t* hle) |
150 | 151 | { |
151 | 152 | jpeg_decode_std(hle, "PS", NULL, NULL, EmitRGBATileLine); |
153 | rsp_break(hle, SP_STATUS_TASKDONE); | |
152 | 154 | } |
153 | 155 | |
154 | 156 | /*************************************************************************** |
189 | 191 | |
190 | 192 | address += (2 * 6 * SUBBLOCK_SIZE); |
191 | 193 | } |
194 | rsp_break(hle, SP_STATUS_TASKDONE); | |
192 | 195 | } |
193 | 196 | |
194 | 197 | |
471 | 474 | unsigned int i; |
472 | 475 | |
473 | 476 | /* source and destination sublocks cannot overlap */ |
474 | assert(abs(dst - src) > SUBBLOCK_SIZE); | |
477 | assert(labs(dst - src) > SUBBLOCK_SIZE); | |
475 | 478 | |
476 | 479 | for (i = 0; i < SUBBLOCK_SIZE; ++i) |
477 | 480 | dst[i] = src[table[i]]; |
0 | 0 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
1 | 1 | * Mupen64plus-rsp-hle - memory.c * |
2 | * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * | |
2 | * Mupen64Plus homepage: https://mupen64plus.org/ * | |
3 | 3 | * Copyright (C) 2014 Bobby Smiles * |
4 | 4 | * * |
5 | 5 | * This program is free software; you can redistribute it and/or modify * |
0 | 0 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
1 | 1 | * Mupen64plus-rsp-hle - memory.h * |
2 | * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * | |
2 | * Mupen64Plus homepage: https://mupen64plus.org/ * | |
3 | 3 | * Copyright (C) 2014 Bobby Smiles * |
4 | 4 | * * |
5 | 5 | * This program is free software; you can redistribute it and/or modify * |
0 | 0 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
1 | 1 | * Mupen64plus-rsp-hle - mp3.c * |
2 | * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * | |
2 | * Mupen64Plus homepage: https://mupen64plus.org/ * | |
3 | 3 | * Copyright (C) 2014 Bobby Smiles * |
4 | 4 | * Copyright (C) 2009 Richard Goedeken * |
5 | 5 | * Copyright (C) 2002 Hacktarux * |
0 | 0 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
1 | 1 | * Mupen64plus-rsp-hle - musyx.c * |
2 | * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * | |
2 | * Mupen64Plus homepage: https://mupen64plus.org/ * | |
3 | 3 | * Copyright (C) 2013 Bobby Smiles * |
4 | 4 | * * |
5 | 5 | * This program is free software; you can redistribute it and/or modify * |
255 | 255 | dram_store_u16(hle, (uint16_t *)musyx.cc0, state_ptr + STATE_CC0, SUBFRAME_SIZE); |
256 | 256 | dram_store_u16(hle, (uint16_t *)musyx.subframe_740_last4, state_ptr + STATE_740_LAST4_V1, |
257 | 257 | 4); |
258 | ||
259 | rsp_break(hle, SP_STATUS_TASKDONE); | |
258 | 260 | } |
259 | 261 | |
260 | 262 | /************************************************************************** |
332 | 334 | |
333 | 335 | sfd_ptr += SFD2_VOICES + MAX_VOICES * VOICE_SIZE; |
334 | 336 | } |
337 | ||
338 | rsp_break(hle, SP_STATUS_TASKDONE); | |
335 | 339 | } |
336 | 340 | |
337 | 341 |
0 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * | |
1 | * Mupen64plus-ui-console - osal_dynamiclib.h * | |
2 | * Mupen64Plus homepage: https://mupen64plus.org/ * | |
3 | * Copyright (C) 2009 Richard Goedeken * | |
4 | * * | |
5 | * This program is free software; you can redistribute it and/or modify * | |
6 | * it under the terms of the GNU General Public License as published by * | |
7 | * the Free Software Foundation; either version 2 of the License, or * | |
8 | * (at your option) any later version. * | |
9 | * * | |
10 | * This program is distributed in the hope that it will be useful, * | |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * | |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | |
13 | * GNU General Public License for more details. * | |
14 | * * | |
15 | * You should have received a copy of the GNU General Public License * | |
16 | * along with this program; if not, write to the * | |
17 | * Free Software Foundation, Inc., * | |
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * | |
19 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | |
20 | ||
21 | #if !defined(OSAL_DYNAMICLIB_H) | |
22 | #define OSAL_DYNAMICLIB_H | |
23 | ||
24 | #include "m64p_types.h" | |
25 | ||
26 | m64p_error osal_dynlib_open(m64p_dynlib_handle *pLibHandle, const char *pccLibraryPath); | |
27 | ||
28 | void * osal_dynlib_getproc(m64p_dynlib_handle LibHandle, const char *pccProcedureName); | |
29 | ||
30 | m64p_error osal_dynlib_close(m64p_dynlib_handle LibHandle); | |
31 | ||
32 | #endif /* #define OSAL_DYNAMICLIB_H */ | |
33 |
0 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * | |
1 | * Mupen64plus-ui-console - osal_dynamiclib_unix.c * | |
2 | * Mupen64Plus homepage: https://mupen64plus.org/ * | |
3 | * Copyright (C) 2009 Richard Goedeken * | |
4 | * * | |
5 | * This program is free software; you can redistribute it and/or modify * | |
6 | * it under the terms of the GNU General Public License as published by * | |
7 | * the Free Software Foundation; either version 2 of the License, or * | |
8 | * (at your option) any later version. * | |
9 | * * | |
10 | * This program is distributed in the hope that it will be useful, * | |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * | |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | |
13 | * GNU General Public License for more details. * | |
14 | * * | |
15 | * You should have received a copy of the GNU General Public License * | |
16 | * along with this program; if not, write to the * | |
17 | * Free Software Foundation, Inc., * | |
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * | |
19 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | |
20 | ||
21 | #include <dlfcn.h> | |
22 | #include <stdio.h> | |
23 | #include <stdlib.h> | |
24 | #include <string.h> | |
25 | ||
26 | #include "m64p_types.h" | |
27 | #include "hle_external.h" | |
28 | #include "osal_dynamiclib.h" | |
29 | ||
30 | m64p_error osal_dynlib_open(m64p_dynlib_handle *pLibHandle, const char *pccLibraryPath) | |
31 | { | |
32 | if (pLibHandle == NULL || pccLibraryPath == NULL) | |
33 | return M64ERR_INPUT_ASSERT; | |
34 | ||
35 | *pLibHandle = dlopen(pccLibraryPath, RTLD_NOW); | |
36 | ||
37 | if (*pLibHandle == NULL) | |
38 | { | |
39 | /* only print an error message if there is a directory separator (/) in the pathname */ | |
40 | /* this prevents us from throwing an error for the use case where Mupen64Plus is not installed */ | |
41 | if (strchr(pccLibraryPath, '/') != NULL) | |
42 | HleErrorMessage(NULL, "dlopen('%s') failed: %s", pccLibraryPath, dlerror()); | |
43 | return M64ERR_INPUT_NOT_FOUND; | |
44 | } | |
45 | ||
46 | return M64ERR_SUCCESS; | |
47 | } | |
48 | ||
49 | void * osal_dynlib_getproc(m64p_dynlib_handle LibHandle, const char *pccProcedureName) | |
50 | { | |
51 | if (pccProcedureName == NULL) | |
52 | return NULL; | |
53 | ||
54 | return dlsym(LibHandle, pccProcedureName); | |
55 | } | |
56 | ||
57 | m64p_error osal_dynlib_close(m64p_dynlib_handle LibHandle) | |
58 | { | |
59 | int rval = dlclose(LibHandle); | |
60 | ||
61 | if (rval != 0) | |
62 | { | |
63 | HleErrorMessage(NULL, "dlclose() failed: %s", dlerror()); | |
64 | return M64ERR_INTERNAL; | |
65 | } | |
66 | ||
67 | return M64ERR_SUCCESS; | |
68 | } | |
69 | ||
70 |
0 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * | |
1 | * Mupen64plus-ui-console - osal_dynamiclib_win32.c * | |
2 | * Mupen64Plus homepage: https://mupen64plus.org/ * | |
3 | * Copyright (C) 2009 Richard Goedeken * | |
4 | * * | |
5 | * This program is free software; you can redistribute it and/or modify * | |
6 | * it under the terms of the GNU General Public License as published by * | |
7 | * the Free Software Foundation; either version 2 of the License, or * | |
8 | * (at your option) any later version. * | |
9 | * * | |
10 | * This program is distributed in the hope that it will be useful, * | |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * | |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | |
13 | * GNU General Public License for more details. * | |
14 | * * | |
15 | * You should have received a copy of the GNU General Public License * | |
16 | * along with this program; if not, write to the * | |
17 | * Free Software Foundation, Inc., * | |
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * | |
19 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | |
20 | ||
21 | #include <stdio.h> | |
22 | #include <stdlib.h> | |
23 | #include <windows.h> | |
24 | ||
25 | #include "m64p_types.h" | |
26 | #include "hle_external.h" | |
27 | #include "osal_dynamiclib.h" | |
28 | ||
29 | m64p_error osal_dynlib_open(m64p_dynlib_handle *pLibHandle, const char *pccLibraryPath) | |
30 | { | |
31 | if (pLibHandle == NULL || pccLibraryPath == NULL) | |
32 | return M64ERR_INPUT_ASSERT; | |
33 | ||
34 | *pLibHandle = LoadLibrary(pccLibraryPath); | |
35 | ||
36 | if (*pLibHandle == NULL) | |
37 | { | |
38 | char *pchErrMsg; | |
39 | DWORD dwErr = GetLastError(); | |
40 | FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwErr, | |
41 | MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &pchErrMsg, 0, NULL); | |
42 | HleErrorMessage(NULL, "LoadLibrary('%s') error: %s", pccLibraryPath, pchErrMsg); | |
43 | LocalFree(pchErrMsg); | |
44 | return M64ERR_INPUT_NOT_FOUND; | |
45 | } | |
46 | ||
47 | return M64ERR_SUCCESS; | |
48 | } | |
49 | ||
50 | void * osal_dynlib_getproc(m64p_dynlib_handle LibHandle, const char *pccProcedureName) | |
51 | { | |
52 | if (pccProcedureName == NULL) | |
53 | return NULL; | |
54 | ||
55 | return GetProcAddress(LibHandle, pccProcedureName); | |
56 | } | |
57 | ||
58 | m64p_error osal_dynlib_close(m64p_dynlib_handle LibHandle) | |
59 | { | |
60 | int rval = FreeLibrary(LibHandle); | |
61 | ||
62 | if (rval == 0) | |
63 | { | |
64 | char *pchErrMsg; | |
65 | DWORD dwErr = GetLastError(); | |
66 | FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwErr, | |
67 | MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &pchErrMsg, 0, NULL); | |
68 | HleErrorMessage(NULL, "FreeLibrary() error: %s", pchErrMsg); | |
69 | LocalFree(pchErrMsg); | |
70 | return M64ERR_INTERNAL; | |
71 | } | |
72 | ||
73 | return M64ERR_SUCCESS; | |
74 | } |
0 | 0 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
1 | 1 | * Mupen64plus-rsp-hle - plugin.c * |
2 | * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * | |
2 | * Mupen64Plus homepage: https://mupen64plus.org/ * | |
3 | 3 | * Copyright (C) 2014 Bobby Smiles * |
4 | 4 | * Copyright (C) 2009 Richard Goedeken * |
5 | 5 | * Copyright (C) 2002 Hacktarux * |
22 | 22 | |
23 | 23 | #include <stdarg.h> |
24 | 24 | #include <stdio.h> |
25 | #include <string.h> | |
25 | 26 | |
26 | 27 | #include "common.h" |
27 | 28 | #include "hle.h" |
28 | 29 | #include "hle_internal.h" |
30 | #include "hle_external.h" | |
29 | 31 | |
30 | 32 | #define M64P_PLUGIN_PROTOTYPES 1 |
31 | 33 | #include "m64p_common.h" |
34 | #include "m64p_config.h" | |
35 | #include "m64p_frontend.h" | |
32 | 36 | #include "m64p_plugin.h" |
33 | 37 | #include "m64p_types.h" |
34 | 38 | |
35 | #define RSP_HLE_VERSION 0x020500 | |
39 | #include "osal_dynamiclib.h" | |
40 | ||
41 | #define CONFIG_API_VERSION 0x020100 | |
42 | #define CONFIG_PARAM_VERSION 1.00 | |
43 | ||
44 | #define RSP_API_VERSION 0x20000 | |
45 | #define RSP_HLE_VERSION 0x020509 | |
36 | 46 | #define RSP_PLUGIN_API_VERSION 0x020000 |
47 | ||
48 | #define RSP_HLE_CONFIG_SECTION "Rsp-HLE" | |
49 | #define RSP_HLE_CONFIG_VERSION "Version" | |
50 | #define RSP_HLE_CONFIG_FALLBACK "RspFallback" | |
51 | #define RSP_HLE_CONFIG_HLE_GFX "DisplayListToGraphicsPlugin" | |
52 | #define RSP_HLE_CONFIG_HLE_AUD "AudioListToAudioPlugin" | |
53 | ||
54 | ||
55 | #define VERSION_PRINTF_SPLIT(x) (((x) >> 16) & 0xffff), (((x) >> 8) & 0xff), ((x) & 0xff) | |
56 | ||
57 | /* Handy macro to avoid code bloat when loading symbols */ | |
58 | #define GET_FUNC(type, field, name) \ | |
59 | ((field = (type)osal_dynlib_getproc(handle, name)) != NULL) | |
37 | 60 | |
38 | 61 | /* local variables */ |
39 | 62 | static struct hle_t g_hle; |
44 | 67 | static void (*l_ShowCFB)(void) = NULL; |
45 | 68 | static void (*l_DebugCallback)(void *, int, const char *) = NULL; |
46 | 69 | static void *l_DebugCallContext = NULL; |
70 | static m64p_dynlib_handle l_CoreHandle = NULL; | |
47 | 71 | static int l_PluginInit = 0; |
48 | 72 | |
73 | static m64p_handle l_ConfigRspHle; | |
74 | static m64p_dynlib_handle l_RspFallback; | |
75 | static ptr_InitiateRSP l_InitiateRSP = NULL; | |
76 | static ptr_DoRspCycles l_DoRspCycles = NULL; | |
77 | static ptr_RomClosed l_RomClosed = NULL; | |
78 | static ptr_PluginShutdown l_PluginShutdown = NULL; | |
79 | ||
80 | /* definitions of pointers to Core functions */ | |
81 | static ptr_ConfigOpenSection ConfigOpenSection = NULL; | |
82 | static ptr_ConfigDeleteSection ConfigDeleteSection = NULL; | |
83 | static ptr_ConfigSetParameter ConfigSetParameter = NULL; | |
84 | static ptr_ConfigGetParameter ConfigGetParameter = NULL; | |
85 | static ptr_ConfigSetDefaultInt ConfigSetDefaultInt = NULL; | |
86 | static ptr_ConfigSetDefaultFloat ConfigSetDefaultFloat = NULL; | |
87 | static ptr_ConfigSetDefaultBool ConfigSetDefaultBool = NULL; | |
88 | static ptr_ConfigSetDefaultString ConfigSetDefaultString = NULL; | |
89 | static ptr_ConfigGetParamInt ConfigGetParamInt = NULL; | |
90 | static ptr_ConfigGetParamFloat ConfigGetParamFloat = NULL; | |
91 | static ptr_ConfigGetParamBool ConfigGetParamBool = NULL; | |
92 | static ptr_ConfigGetParamString ConfigGetParamString = NULL; | |
93 | static ptr_CoreDoCommand CoreDoCommand = NULL; | |
94 | ||
49 | 95 | /* local function */ |
96 | static void teardown_rsp_fallback() | |
97 | { | |
98 | if (l_RspFallback != NULL) { | |
99 | (*l_PluginShutdown)(); | |
100 | osal_dynlib_close(l_RspFallback); | |
101 | } | |
102 | ||
103 | l_RspFallback = NULL; | |
104 | l_DoRspCycles = NULL; | |
105 | l_InitiateRSP = NULL; | |
106 | l_RomClosed = NULL; | |
107 | l_PluginShutdown = NULL; | |
108 | } | |
109 | ||
110 | static void setup_rsp_fallback(const char* rsp_fallback_path) | |
111 | { | |
112 | m64p_dynlib_handle handle = NULL; | |
113 | ||
114 | /* reset rsp fallback */ | |
115 | teardown_rsp_fallback(); | |
116 | ||
117 | if (rsp_fallback_path == NULL || strlen(rsp_fallback_path) == 0) { | |
118 | HleInfoMessage(NULL, "RSP Fallback disabled !"); | |
119 | return; | |
120 | } | |
121 | ||
122 | /* load plugin */ | |
123 | if (osal_dynlib_open(&handle, rsp_fallback_path) != M64ERR_SUCCESS) { | |
124 | HleErrorMessage(NULL, "Can't load library: %s", rsp_fallback_path); | |
125 | return; | |
126 | } | |
127 | ||
128 | /* call the GetVersion function for the plugin and check compatibility */ | |
129 | ptr_PluginGetVersion PluginGetVersion = (ptr_PluginGetVersion) osal_dynlib_getproc(handle, "PluginGetVersion"); | |
130 | if (PluginGetVersion == NULL) | |
131 | { | |
132 | HleErrorMessage(NULL, "library '%s' is not a Mupen64Plus library.", rsp_fallback_path); | |
133 | goto close_handle; | |
134 | } | |
135 | ||
136 | m64p_plugin_type plugin_type = (m64p_plugin_type)0; | |
137 | int plugin_version = 0; | |
138 | const char *plugin_name = NULL; | |
139 | int api_version = 0; | |
140 | ||
141 | (*PluginGetVersion)(&plugin_type, &plugin_version, &api_version, &plugin_name, NULL); | |
142 | ||
143 | if (plugin_type != M64PLUGIN_RSP) { | |
144 | HleErrorMessage(NULL, "plugin %s is not an RSP plugin (%u)", plugin_name, plugin_type); | |
145 | goto close_handle; | |
146 | } | |
147 | ||
148 | if ((api_version & 0xffff0000) != (RSP_API_VERSION & 0xffff0000)) { | |
149 | HleErrorMessage(NULL, "plugin %s. Version mismatch: %u.%u. Expected >= %u.0", | |
150 | plugin_name, | |
151 | (uint16_t)(api_version >> 16), | |
152 | (uint16_t)(api_version), | |
153 | (uint16_t)(RSP_API_VERSION >> 16)); | |
154 | goto close_handle; | |
155 | } | |
156 | ||
157 | /* load functions */ | |
158 | ptr_PluginStartup PluginStartup; | |
159 | ||
160 | if (!GET_FUNC(ptr_PluginStartup, PluginStartup, "PluginStartup") || | |
161 | !GET_FUNC(ptr_PluginShutdown, l_PluginShutdown, "PluginShutdown") || | |
162 | !GET_FUNC(ptr_DoRspCycles, l_DoRspCycles, "DoRspCycles") || | |
163 | !GET_FUNC(ptr_InitiateRSP, l_InitiateRSP, "InitiateRSP") || | |
164 | !GET_FUNC(ptr_RomClosed, l_RomClosed, "RomClosed")) | |
165 | { | |
166 | HleErrorMessage(NULL, "broken RSP plugin; function(s) not found."); | |
167 | l_PluginShutdown = NULL; | |
168 | l_DoRspCycles = NULL; | |
169 | l_InitiateRSP = NULL; | |
170 | l_RomClosed = NULL; | |
171 | goto close_handle; | |
172 | } | |
173 | ||
174 | /* call the plugin's initialization function and make sure it starts okay */ | |
175 | if ((*PluginStartup)(l_CoreHandle, l_DebugCallContext, l_DebugCallback) != M64ERR_SUCCESS) { | |
176 | HleErrorMessage(NULL, "Error: %s plugin library '%s' failed to start.", plugin_name, rsp_fallback_path); | |
177 | goto close_handle; | |
178 | } | |
179 | ||
180 | /* OK we're done ! */ | |
181 | l_RspFallback = handle; | |
182 | HleInfoMessage(NULL, "RSP Fallback '%s' loaded successfully !", rsp_fallback_path); | |
183 | return; | |
184 | ||
185 | close_handle: | |
186 | osal_dynlib_close(handle); | |
187 | } | |
188 | ||
50 | 189 | static void DebugMessage(int level, const char *message, va_list args) |
51 | 190 | { |
52 | 191 | char msgbuf[1024]; |
68 | 207 | va_end(args); |
69 | 208 | } |
70 | 209 | |
210 | void HleInfoMessage(void* UNUSED(user_defined), const char *message, ...) | |
211 | { | |
212 | va_list args; | |
213 | va_start(args, message); | |
214 | DebugMessage(M64MSG_INFO, message, args); | |
215 | va_end(args); | |
216 | } | |
217 | ||
71 | 218 | void HleErrorMessage(void* UNUSED(user_defined), const char *message, ...) |
72 | 219 | { |
73 | 220 | va_list args; |
125 | 272 | } |
126 | 273 | |
127 | 274 | |
275 | int HleForwardTask(void* user_defined) | |
276 | { | |
277 | if (l_DoRspCycles == NULL) | |
278 | return -1; | |
279 | ||
280 | (*l_DoRspCycles)(-1); | |
281 | return 0; | |
282 | } | |
283 | ||
284 | ||
128 | 285 | /* DLL-exported functions */ |
129 | EXPORT m64p_error CALL PluginStartup(m64p_dynlib_handle UNUSED(CoreLibHandle), void *Context, | |
286 | EXPORT m64p_error CALL PluginStartup(m64p_dynlib_handle CoreLibHandle, void *Context, | |
130 | 287 | void (*DebugCallback)(void *, int, const char *)) |
131 | 288 | { |
289 | ptr_CoreGetAPIVersions CoreAPIVersionFunc; | |
290 | int ConfigAPIVersion, DebugAPIVersion, VidextAPIVersion; | |
291 | float fConfigParamsVersion = 0.0f; | |
292 | ||
132 | 293 | if (l_PluginInit) |
133 | 294 | return M64ERR_ALREADY_INIT; |
134 | 295 | |
136 | 297 | l_DebugCallback = DebugCallback; |
137 | 298 | l_DebugCallContext = Context; |
138 | 299 | |
139 | /* this plugin doesn't use any Core library functions (ex for Configuration), so no need to keep the CoreLibHandle */ | |
300 | /* attach and call the CoreGetAPIVersions function, check Config API version for compatibility */ | |
301 | CoreAPIVersionFunc = (ptr_CoreGetAPIVersions) osal_dynlib_getproc(CoreLibHandle, "CoreGetAPIVersions"); | |
302 | if (CoreAPIVersionFunc == NULL) | |
303 | { | |
304 | HleErrorMessage(NULL, "Core emulator broken; no CoreAPIVersionFunc() function found."); | |
305 | return M64ERR_INCOMPATIBLE; | |
306 | } | |
307 | ||
308 | (*CoreAPIVersionFunc)(&ConfigAPIVersion, &DebugAPIVersion, &VidextAPIVersion, NULL); | |
309 | if ((ConfigAPIVersion & 0xffff0000) != (CONFIG_API_VERSION & 0xffff0000)) | |
310 | { | |
311 | HleErrorMessage(NULL, "Emulator core Config API (v%i.%i.%i) incompatible with plugin (v%i.%i.%i)", | |
312 | VERSION_PRINTF_SPLIT(ConfigAPIVersion), VERSION_PRINTF_SPLIT(CONFIG_API_VERSION)); | |
313 | return M64ERR_INCOMPATIBLE; | |
314 | } | |
315 | ||
316 | /* Get the core config function pointers from the library handle */ | |
317 | ConfigOpenSection = (ptr_ConfigOpenSection) osal_dynlib_getproc(CoreLibHandle, "ConfigOpenSection"); | |
318 | ConfigDeleteSection = (ptr_ConfigDeleteSection) osal_dynlib_getproc(CoreLibHandle, "ConfigDeleteSection"); | |
319 | ConfigSetParameter = (ptr_ConfigSetParameter) osal_dynlib_getproc(CoreLibHandle, "ConfigSetParameter"); | |
320 | ConfigGetParameter = (ptr_ConfigGetParameter) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParameter"); | |
321 | ConfigSetDefaultInt = (ptr_ConfigSetDefaultInt) osal_dynlib_getproc(CoreLibHandle, "ConfigSetDefaultInt"); | |
322 | ConfigSetDefaultFloat = (ptr_ConfigSetDefaultFloat) osal_dynlib_getproc(CoreLibHandle, "ConfigSetDefaultFloat"); | |
323 | ConfigSetDefaultBool = (ptr_ConfigSetDefaultBool) osal_dynlib_getproc(CoreLibHandle, "ConfigSetDefaultBool"); | |
324 | ConfigSetDefaultString = (ptr_ConfigSetDefaultString) osal_dynlib_getproc(CoreLibHandle, "ConfigSetDefaultString"); | |
325 | ConfigGetParamInt = (ptr_ConfigGetParamInt) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParamInt"); | |
326 | ConfigGetParamFloat = (ptr_ConfigGetParamFloat) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParamFloat"); | |
327 | ConfigGetParamBool = (ptr_ConfigGetParamBool) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParamBool"); | |
328 | ConfigGetParamString = (ptr_ConfigGetParamString) osal_dynlib_getproc(CoreLibHandle, "ConfigGetParamString"); | |
329 | ||
330 | if (!ConfigOpenSection || !ConfigDeleteSection || !ConfigSetParameter || !ConfigGetParameter || | |
331 | !ConfigSetDefaultInt || !ConfigSetDefaultFloat || !ConfigSetDefaultBool || !ConfigSetDefaultString || | |
332 | !ConfigGetParamInt || !ConfigGetParamFloat || !ConfigGetParamBool || !ConfigGetParamString) | |
333 | return M64ERR_INCOMPATIBLE; | |
334 | ||
335 | /* Get core DoCommand function */ | |
336 | CoreDoCommand = (ptr_CoreDoCommand) osal_dynlib_getproc(CoreLibHandle, "CoreDoCommand"); | |
337 | if (!CoreDoCommand) { | |
338 | return M64ERR_INCOMPATIBLE; | |
339 | } | |
340 | ||
341 | /* get a configuration section handle */ | |
342 | if (ConfigOpenSection(RSP_HLE_CONFIG_SECTION, &l_ConfigRspHle) != M64ERR_SUCCESS) | |
343 | { | |
344 | HleErrorMessage(NULL, "Couldn't open config section '" RSP_HLE_CONFIG_SECTION "'"); | |
345 | return M64ERR_INPUT_NOT_FOUND; | |
346 | } | |
347 | ||
348 | /* check the section version number */ | |
349 | if (ConfigGetParameter(l_ConfigRspHle, RSP_HLE_CONFIG_VERSION, M64TYPE_FLOAT, &fConfigParamsVersion, sizeof(float)) != M64ERR_SUCCESS) | |
350 | { | |
351 | HleWarnMessage(NULL, "No version number in '" RSP_HLE_CONFIG_SECTION "' config section. Setting defaults."); | |
352 | ConfigDeleteSection(RSP_HLE_CONFIG_SECTION); | |
353 | ConfigOpenSection(RSP_HLE_CONFIG_SECTION, &l_ConfigRspHle); | |
354 | } | |
355 | else if (((int) fConfigParamsVersion) != ((int) CONFIG_PARAM_VERSION)) | |
356 | { | |
357 | HleWarnMessage(NULL, "Incompatible version %.2f in '" RSP_HLE_CONFIG_SECTION "' config section: current is %.2f. Setting defaults.", fConfigParamsVersion, (float) CONFIG_PARAM_VERSION); | |
358 | ConfigDeleteSection(RSP_HLE_CONFIG_SECTION); | |
359 | ConfigOpenSection(RSP_HLE_CONFIG_SECTION, &l_ConfigRspHle); | |
360 | } | |
361 | else if ((CONFIG_PARAM_VERSION - fConfigParamsVersion) >= 0.0001f) | |
362 | { | |
363 | /* handle upgrades */ | |
364 | float fVersion = CONFIG_PARAM_VERSION; | |
365 | ConfigSetParameter(l_ConfigRspHle, "Version", M64TYPE_FLOAT, &fVersion); | |
366 | HleInfoMessage(NULL, "Updating parameter set version in '" RSP_HLE_CONFIG_SECTION "' config section to %.2f", fVersion); | |
367 | } | |
368 | ||
369 | /* set the default values for this plugin */ | |
370 | ConfigSetDefaultFloat(l_ConfigRspHle, RSP_HLE_CONFIG_VERSION, CONFIG_PARAM_VERSION, | |
371 | "Mupen64Plus RSP HLE Plugin config parameter version number"); | |
372 | ConfigSetDefaultString(l_ConfigRspHle, RSP_HLE_CONFIG_FALLBACK, "", | |
373 | "Path to a RSP plugin which will be used when encountering an unknown ucode." | |
374 | "You can disable this by letting an empty string."); | |
375 | ConfigSetDefaultBool(l_ConfigRspHle, RSP_HLE_CONFIG_HLE_GFX, 1, | |
376 | "Send display lists to the graphics plugin"); | |
377 | ConfigSetDefaultBool(l_ConfigRspHle, RSP_HLE_CONFIG_HLE_AUD, 0, | |
378 | "Send audio lists to the audio plugin"); | |
379 | ||
380 | l_CoreHandle = CoreLibHandle; | |
140 | 381 | |
141 | 382 | l_PluginInit = 1; |
142 | 383 | return M64ERR_SUCCESS; |
150 | 391 | /* reset some local variable */ |
151 | 392 | l_DebugCallback = NULL; |
152 | 393 | l_DebugCallContext = NULL; |
394 | l_CoreHandle = NULL; | |
395 | ||
396 | teardown_rsp_fallback(); | |
153 | 397 | |
154 | 398 | l_PluginInit = 0; |
155 | 399 | return M64ERR_SUCCESS; |
182 | 426 | return Cycles; |
183 | 427 | } |
184 | 428 | |
185 | EXPORT void CALL InitiateRSP(RSP_INFO Rsp_Info, unsigned int* UNUSED(CycleCount)) | |
429 | EXPORT void CALL InitiateRSP(RSP_INFO Rsp_Info, unsigned int* CycleCount) | |
186 | 430 | { |
187 | 431 | hle_init(&g_hle, |
188 | 432 | Rsp_Info.RDRAM, |
213 | 457 | l_ProcessAlistList = Rsp_Info.ProcessAlistList; |
214 | 458 | l_ProcessRdpList = Rsp_Info.ProcessRdpList; |
215 | 459 | l_ShowCFB = Rsp_Info.ShowCFB; |
460 | ||
461 | setup_rsp_fallback(ConfigGetParamString(l_ConfigRspHle, RSP_HLE_CONFIG_FALLBACK)); | |
462 | ||
463 | g_hle.hle_gfx = ConfigGetParamBool(l_ConfigRspHle, RSP_HLE_CONFIG_HLE_GFX); | |
464 | g_hle.hle_aud = ConfigGetParamBool(l_ConfigRspHle, RSP_HLE_CONFIG_HLE_AUD); | |
465 | ||
466 | /* notify fallback plugin */ | |
467 | if (l_InitiateRSP) { | |
468 | l_InitiateRSP(Rsp_Info, CycleCount); | |
469 | } | |
216 | 470 | } |
217 | 471 | |
218 | 472 | EXPORT void CALL RomClosed(void) |
219 | 473 | { |
220 | /* do nothing */ | |
221 | } | |
474 | g_hle.cached_ucodes.count = 0; | |
475 | ||
476 | /* notify fallback plugin */ | |
477 | if (l_RomClosed) { | |
478 | l_RomClosed(); | |
479 | } | |
480 | } |
0 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * | |
1 | * Mupen64plus-rsp-hle - re2.c * | |
2 | * Mupen64Plus homepage: https://mupen64plus.org/ * | |
3 | * Copyright (C) 2016 Gilles Siberlin * | |
4 | * * | |
5 | * This program is free software; you can redistribute it and/or modify * | |
6 | * it under the terms of the GNU General Public License as published by * | |
7 | * the Free Software Foundation; either version 2 of the License, or * | |
8 | * (at your option) any later version. * | |
9 | * * | |
10 | * This program is distributed in the hope that it will be useful, * | |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * | |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | |
13 | * GNU General Public License for more details. * | |
14 | * * | |
15 | * You should have received a copy of the GNU General Public License * | |
16 | * along with this program; if not, write to the * | |
17 | * Free Software Foundation, Inc., * | |
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * | |
19 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | |
20 | ||
21 | #include <assert.h> | |
22 | #include <stdint.h> | |
23 | #include <stdlib.h> | |
24 | ||
25 | #include "hle_external.h" | |
26 | #include "hle_internal.h" | |
27 | #include "memory.h" | |
28 | ||
29 | #define SATURATE8(x) ((unsigned int) x <= 255 ? x : (x < 0 ? 0: 255)) | |
30 | ||
31 | /************************************************************************** | |
32 | * Resident evil 2 ucodes | |
33 | **************************************************************************/ | |
34 | void resize_bilinear_task(struct hle_t* hle) | |
35 | { | |
36 | int data_ptr = *dmem_u32(hle, TASK_UCODE_DATA); | |
37 | ||
38 | int src_addr = *dram_u32(hle, data_ptr); | |
39 | int dst_addr = *dram_u32(hle, data_ptr + 4); | |
40 | int dst_width = *dram_u32(hle, data_ptr + 8); | |
41 | int dst_height = *dram_u32(hle, data_ptr + 12); | |
42 | int x_ratio = *dram_u32(hle, data_ptr + 16); | |
43 | int y_ratio = *dram_u32(hle, data_ptr + 20); | |
44 | #if 0 /* unused, but keep it for documentation purpose */ | |
45 | int dst_stride = *dram_u32(hle, data_ptr + 24); | |
46 | #endif | |
47 | int src_offset = *dram_u32(hle, data_ptr + 36); | |
48 | ||
49 | int a, b, c ,d, index, y_index, xr, yr, blue, green, red, addr, i, j; | |
50 | long long x, y, x_diff, y_diff, one_min_x_diff, one_min_y_diff; | |
51 | unsigned short pixel; | |
52 | ||
53 | src_addr += (src_offset >> 16) * (320 * 3); | |
54 | x = y = 0; | |
55 | ||
56 | for(i = 0; i < dst_height; i++) | |
57 | { | |
58 | yr = (int)(y >> 16); | |
59 | y_diff = y - (yr << 16); | |
60 | one_min_y_diff = 65536 - y_diff; | |
61 | y_index = yr * 320; | |
62 | x = 0; | |
63 | ||
64 | for(j = 0; j < dst_width; j++) | |
65 | { | |
66 | xr = (int)(x >> 16); | |
67 | x_diff = x - (xr << 16); | |
68 | one_min_x_diff = 65536 - x_diff; | |
69 | index = y_index + xr; | |
70 | addr = src_addr + (index * 3); | |
71 | ||
72 | dram_load_u8(hle, (uint8_t*)&a, addr, 3); | |
73 | dram_load_u8(hle, (uint8_t*)&b, (addr + 3), 3); | |
74 | dram_load_u8(hle, (uint8_t*)&c, (addr + (320 * 3)), 3); | |
75 | dram_load_u8(hle, (uint8_t*)&d, (addr + (320 * 3) + 3), 3); | |
76 | ||
77 | blue = (int)(((a&0xff)*one_min_x_diff*one_min_y_diff + (b&0xff)*x_diff*one_min_y_diff + | |
78 | (c&0xff)*y_diff*one_min_x_diff + (d&0xff)*x_diff*y_diff) >> 32); | |
79 | ||
80 | green = (int)((((a>>8)&0xff)*one_min_x_diff*one_min_y_diff + ((b>>8)&0xff)*x_diff*one_min_y_diff + | |
81 | ((c>>8)&0xff)*y_diff*one_min_x_diff + ((d>>8)&0xff)*x_diff*y_diff) >> 32); | |
82 | ||
83 | red = (int)((((a>>16)&0xff)*one_min_x_diff*one_min_y_diff + ((b>>16)&0xff)*x_diff*one_min_y_diff + | |
84 | ((c>>16)&0xff)*y_diff*one_min_x_diff + ((d>>16)&0xff)*x_diff*y_diff) >> 32); | |
85 | ||
86 | blue = (blue >> 3) & 0x001f; | |
87 | green = (green >> 3) & 0x001f; | |
88 | red = (red >> 3) & 0x001f; | |
89 | pixel = (red << 11) | (green << 6) | (blue << 1) | 1; | |
90 | ||
91 | dram_store_u16(hle, &pixel, dst_addr, 1); | |
92 | dst_addr += 2; | |
93 | ||
94 | x += x_ratio; | |
95 | } | |
96 | y += y_ratio; | |
97 | } | |
98 | ||
99 | rsp_break(hle, SP_STATUS_TASKDONE); | |
100 | } | |
101 | ||
102 | static uint32_t YCbCr_to_RGBA(uint8_t Y, uint8_t Cb, uint8_t Cr) | |
103 | { | |
104 | int r, g, b; | |
105 | ||
106 | r = (int)(((double)Y * 0.582199097) + (0.701004028 * (double)(Cr - 128))); | |
107 | g = (int)(((double)Y * 0.582199097) - (0.357070923 * (double)(Cr - 128)) - (0.172073364 * (double)(Cb - 128))); | |
108 | b = (int)(((double)Y * 0.582199097) + (0.886001587 * (double)(Cb - 128))); | |
109 | ||
110 | r = SATURATE8(r); | |
111 | g = SATURATE8(g); | |
112 | b = SATURATE8(b); | |
113 | ||
114 | return (r << 24) | (g << 16) | (b << 8) | 0; | |
115 | } | |
116 | ||
117 | void decode_video_frame_task(struct hle_t* hle) | |
118 | { | |
119 | int data_ptr = *dmem_u32(hle, TASK_UCODE_DATA); | |
120 | ||
121 | int pLuminance = *dram_u32(hle, data_ptr); | |
122 | int pCb = *dram_u32(hle, data_ptr + 4); | |
123 | int pCr = *dram_u32(hle, data_ptr + 8); | |
124 | int pDestination = *dram_u32(hle, data_ptr + 12); | |
125 | int nMovieWidth = *dram_u32(hle, data_ptr + 16); | |
126 | int nMovieHeight = *dram_u32(hle, data_ptr + 20); | |
127 | #if 0 /* unused, but keep it for documentation purpose */ | |
128 | int nRowsPerDMEM = *dram_u32(hle, data_ptr + 24); | |
129 | int nDMEMPerFrame = *dram_u32(hle, data_ptr + 28); | |
130 | int nLengthSkipCount = *dram_u32(hle, data_ptr + 32); | |
131 | #endif | |
132 | int nScreenDMAIncrement = *dram_u32(hle, data_ptr + 36); | |
133 | ||
134 | int i, j; | |
135 | uint8_t Y, Cb, Cr; | |
136 | uint32_t pixel; | |
137 | int pY_1st_row, pY_2nd_row, pDest_1st_row, pDest_2nd_row; | |
138 | ||
139 | for (i = 0; i < nMovieHeight; i += 2) | |
140 | { | |
141 | pY_1st_row = pLuminance; | |
142 | pY_2nd_row = pLuminance + nMovieWidth; | |
143 | pDest_1st_row = pDestination; | |
144 | pDest_2nd_row = pDestination + (nScreenDMAIncrement >> 1); | |
145 | ||
146 | for (j = 0; j < nMovieWidth; j += 2) | |
147 | { | |
148 | dram_load_u8(hle, (uint8_t*)&Cb, pCb++, 1); | |
149 | dram_load_u8(hle, (uint8_t*)&Cr, pCr++, 1); | |
150 | ||
151 | /*1st row*/ | |
152 | dram_load_u8(hle, (uint8_t*)&Y, pY_1st_row++, 1); | |
153 | pixel = YCbCr_to_RGBA(Y, Cb, Cr); | |
154 | dram_store_u32(hle, &pixel, pDest_1st_row, 1); | |
155 | pDest_1st_row += 4; | |
156 | ||
157 | dram_load_u8(hle, (uint8_t*)&Y, pY_1st_row++, 1); | |
158 | pixel = YCbCr_to_RGBA(Y, Cb, Cr); | |
159 | dram_store_u32(hle, &pixel, pDest_1st_row, 1); | |
160 | pDest_1st_row += 4; | |
161 | ||
162 | /*2nd row*/ | |
163 | dram_load_u8(hle, (uint8_t*)&Y, pY_2nd_row++, 1); | |
164 | pixel = YCbCr_to_RGBA(Y, Cb, Cr); | |
165 | dram_store_u32(hle, &pixel, pDest_2nd_row, 1); | |
166 | pDest_2nd_row += 4; | |
167 | ||
168 | dram_load_u8(hle, (uint8_t*)&Y, pY_2nd_row++, 1); | |
169 | pixel = YCbCr_to_RGBA(Y, Cb, Cr); | |
170 | dram_store_u32(hle, &pixel, pDest_2nd_row, 1); | |
171 | pDest_2nd_row += 4; | |
172 | } | |
173 | ||
174 | pLuminance += (nMovieWidth << 1); | |
175 | pDestination += nScreenDMAIncrement; | |
176 | } | |
177 | ||
178 | rsp_break(hle, SP_STATUS_TASKDONE); | |
179 | } | |
180 | ||
181 | void fill_video_double_buffer_task(struct hle_t* hle) | |
182 | { | |
183 | int data_ptr = *dmem_u32(hle, TASK_UCODE_DATA); | |
184 | ||
185 | int pSrc = *dram_u32(hle, data_ptr); | |
186 | int pDest = *dram_u32(hle, data_ptr + 0x4); | |
187 | int width = *dram_u32(hle, data_ptr + 0x8) >> 1; | |
188 | int height = *dram_u32(hle, data_ptr + 0x10) << 1; | |
189 | int stride = *dram_u32(hle, data_ptr + 0x1c) >> 1; | |
190 | ||
191 | assert((*dram_u32(hle, data_ptr + 0x28) >> 16) == 0x8000); | |
192 | ||
193 | #if 0 /* unused, but keep it for documentation purpose */ | |
194 | int arg3 = *dram_u32(hle, data_ptr + 0xc); | |
195 | int arg5 = *dram_u32(hle, data_ptr + 0x14); | |
196 | int arg6 = *dram_u32(hle, data_ptr + 0x18); | |
197 | #endif | |
198 | ||
199 | int i, j; | |
200 | int r, g, b; | |
201 | uint32_t pixel, pixel1, pixel2; | |
202 | ||
203 | for(i = 0; i < height; i++) | |
204 | { | |
205 | for(j = 0; j < width; j=j+4) | |
206 | { | |
207 | pixel1 = *dram_u32(hle, pSrc+j); | |
208 | pixel2 = *dram_u32(hle, pDest+j); | |
209 | ||
210 | r = (((pixel1 >> 24) & 0xff) + ((pixel2 >> 24) & 0xff)) >> 1; | |
211 | g = (((pixel1 >> 16) & 0xff) + ((pixel2 >> 16) & 0xff)) >> 1; | |
212 | b = (((pixel1 >> 8) & 0xff) + ((pixel2 >> 8) & 0xff)) >> 1; | |
213 | ||
214 | pixel = (r << 24) | (g << 16) | (b << 8) | 0; | |
215 | ||
216 | dram_store_u32(hle, &pixel, pDest+j, 1); | |
217 | } | |
218 | pSrc += stride; | |
219 | pDest += stride; | |
220 | } | |
221 | ||
222 | rsp_break(hle, SP_STATUS_TASKDONE); | |
223 | } |
0 | 0 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
1 | 1 | * Mupen64plus-rsp-hle - ucodes.h * |
2 | * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * | |
2 | * Mupen64Plus homepage: https://mupen64plus.org/ * | |
3 | 3 | * Copyright (C) 2014 Bobby Smiles * |
4 | 4 | * * |
5 | 5 | * This program is free software; you can redistribute it and/or modify * |
23 | 23 | |
24 | 24 | #include <stdint.h> |
25 | 25 | |
26 | #define CACHED_UCODES_MAX_SIZE 16 | |
27 | ||
26 | 28 | struct hle_t; |
27 | 29 | |
30 | typedef void(*ucode_func_t)(struct hle_t* hle); | |
31 | ||
32 | struct ucode_info_t { | |
33 | uint32_t uc_start; | |
34 | uint32_t uc_dstart; | |
35 | uint16_t uc_dsize; | |
36 | ucode_func_t uc_pfunc; | |
37 | }; | |
38 | ||
39 | struct cached_ucodes_t { | |
40 | struct ucode_info_t infos[CACHED_UCODES_MAX_SIZE]; | |
41 | int count; | |
42 | }; | |
28 | 43 | |
29 | 44 | /* cic_x105 ucode */ |
30 | 45 | void cicx105_ucode(struct hle_t* hle); |
125 | 140 | void alist_process_nead_mm (struct hle_t* hle); |
126 | 141 | void alist_process_nead_mmb (struct hle_t* hle); |
127 | 142 | void alist_process_nead_ac (struct hle_t* hle); |
128 | ||
143 | void alist_process_nead_mats(struct hle_t* hle); | |
144 | void alist_process_nead_efz (struct hle_t* hle); | |
129 | 145 | |
130 | 146 | /* mp3 ucode */ |
131 | 147 | void mp3_task(struct hle_t* hle, unsigned int index, uint32_t address); |
141 | 157 | void jpeg_decode_PS(struct hle_t* hle); |
142 | 158 | void jpeg_decode_OB(struct hle_t* hle); |
143 | 159 | |
160 | /* Resident evil 2 ucode */ | |
161 | void resize_bilinear_task(struct hle_t* hle); | |
162 | void decode_video_frame_task(struct hle_t* hle); | |
163 | void fill_video_double_buffer_task(struct hle_t* hle); | |
164 | ||
165 | /* hvqm2 ucode */ | |
166 | void hvqm2_decode_sp1_task(struct hle_t* hle); | |
167 | void hvqm2_decode_sp2_task(struct hle_t* hle); | |
168 | ||
144 | 169 | #endif |
145 | 170 |