mirror of
https://github.com/simple64/simple64.git
synced 2026-11-13 20:58:42 +01:00
update core
This commit is contained in:
1 parent
9e45d7f0c4
commit
a616e3cdca
7 files changed
+678
-60
No files matched your search
+288
@@ -0,0 +1,288 @@
|
||||
name: Core
|
||||
|
||||
on:
|
||||
push:
|
||||
paths-ignore:
|
||||
- '**/*.md'
|
||||
- '.{gitattributes,gitignore,travis.yml}'
|
||||
- 'appveyor.yml,README'
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- '**/*.md'
|
||||
- '.{gitattributes,gitignore,travis.yml}'
|
||||
- 'appveyor.yml,README'
|
||||
workflow_dispatch:
|
||||
jobs:
|
||||
|
||||
Linux:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- cc: GCC
|
||||
- cc: Clang
|
||||
name: Linux / ${{ matrix.cc }} / x64 | x86
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Get build dependencies and arrange the environment
|
||||
run: |
|
||||
sudo dpkg --add-architecture i386
|
||||
sudo apt-get update
|
||||
sudo apt-get -y install libfreetype6-dev libgl1-mesa-dev libglu1-mesa-dev libpng-dev libsdl1.2-dev libsdl2-dev nasm zlib1g-dev
|
||||
sudo apt-get --reinstall -y install gcc-multilib g++-multilib libc6 libc6-dev-i386 libfreetype6:i386 libgl1-mesa-glx:i386 libglu1-mesa:i386 libpng16-16:i386 libsdl1.2debian:i386 libsdl2-2.0-0:i386 zlib1g:i386
|
||||
LINK="sudo ln -s -T"
|
||||
cd /usr/lib/i386-linux-gnu
|
||||
if ! [[ -f libfreetype.so ]]; then ${LINK} libfreetype.so.6.17.1 libfreetype.so; fi
|
||||
if ! [[ -f libGL.so ]]; then ${LINK} libGL.so.1.7.0 libGL.so; fi
|
||||
if ! [[ -f libGLU.so ]]; then ${LINK} libGLU.so.1.3.1 libGLU.so; fi
|
||||
if ! [[ -f libpng16.so ]]; then ${LINK} libpng16.so.16.37.0 libpng16.so; fi
|
||||
if ! [[ -f libSDL.so ]]; then ${LINK} libSDL-1.2.so.0.11.4 libSDL.so; fi
|
||||
if ! [[ -f libSDL2.so ]]; then ${LINK} libSDL2-2.0.so.0.10.0 libSDL2.so; fi
|
||||
if ! [[ -f libz.so ]]; then ${LINK} libz.so.1.2.11 libz.so; fi
|
||||
cd /usr/include/SDL2
|
||||
if ! [[ -f _real_SDL_config.h ]]; then ${LINK} ../x86_64-linux-gnu/SDL2/_real_SDL_config.h _real_SDL_config.h; fi
|
||||
sudo ldconfig
|
||||
- name: Build and related stuff
|
||||
run: |
|
||||
if [[ "${{ matrix.cc }}" == "GCC" ]]; then
|
||||
CC="gcc"
|
||||
CXX="g++"
|
||||
else
|
||||
CC="clang"
|
||||
CXX="clang++"
|
||||
fi
|
||||
${CC} --version
|
||||
for TSK in 1 2 3 4 5 6 7 8
|
||||
do
|
||||
unset PIC
|
||||
if [[ ${TSK} -le 4 ]]; then
|
||||
SDL="sdl"
|
||||
MSG="SDL1.2"
|
||||
else
|
||||
SDL="sdl2"
|
||||
MSG="SDL2"
|
||||
fi
|
||||
if [[ "${DYN}" == "0" ]]; then
|
||||
DYN="1"
|
||||
MSG="${MSG} / NEW_DYNAREC"
|
||||
else
|
||||
DYN="0"
|
||||
if [[ "${BITS}" == "64" ]]; then BITS="32"; else BITS="64"; fi
|
||||
fi
|
||||
if [[ ${BITS} -eq 32 ]]; then
|
||||
if [[ "${CC}" == "clang" ]]; then export PIC="1"; fi
|
||||
MSG="x86 / ${MSG}"
|
||||
else
|
||||
MSG="x64 / ${MSG}"
|
||||
fi
|
||||
echo ""
|
||||
echo ":: ${{ matrix.cc }} ${MSG} ::"
|
||||
echo ""
|
||||
make -C projects/unix clean
|
||||
echo ""
|
||||
make CC="${CC}" CXX="${CXX}" BITS="${BITS}" SDL_CONFIG="${SDL}-config" NEW_DYNAREC="${DYN}" -C projects/unix all
|
||||
echo ""
|
||||
ls -gG projects/unix/*.so*
|
||||
ldd projects/unix/libmupen64plus.so.2.0.0
|
||||
done
|
||||
|
||||
MSYS2:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- cc: GCC
|
||||
platform: x64
|
||||
cross: x86_64
|
||||
bits: 64
|
||||
- cc: GCC
|
||||
platform: x86
|
||||
cross: i686
|
||||
bits: 32
|
||||
name: Windows / MSYS2 ${{ matrix.cc }} / ${{ matrix.platform }}
|
||||
runs-on: windows-2019
|
||||
defaults:
|
||||
run:
|
||||
shell: msys2 {0}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: msys2/setup-msys2@v2
|
||||
with:
|
||||
msystem: MINGW${{ matrix.bits }}
|
||||
update: true
|
||||
install: >-
|
||||
git
|
||||
make
|
||||
mingw-w64-${{ matrix.cross }}-gcc
|
||||
mingw-w64-${{ matrix.cross }}-toolchain
|
||||
mingw-w64-${{ matrix.cross }}-freetype
|
||||
mingw-w64-${{ matrix.cross }}-libpng
|
||||
mingw-w64-${{ matrix.cross }}-nasm
|
||||
mingw-w64-${{ matrix.cross }}-SDL2
|
||||
mingw-w64-${{ matrix.cross }}-zlib
|
||||
- name: Build and related stuff
|
||||
run: |
|
||||
export OPTFLAGS="-O2 -flto"
|
||||
echo "G_REV=$(git rev-parse --short HEAD)" >> "${GITHUB_ENV}"
|
||||
CC="gcc"
|
||||
CXX="g++"
|
||||
${CC} --version
|
||||
mkdir backup
|
||||
LIB="-old"
|
||||
for DYN in 0 1
|
||||
do
|
||||
echo ""
|
||||
echo ":: ${{ matrix.cc }} ${{ matrix.platform }} / SDL2${MSG} ::"
|
||||
echo ""
|
||||
make -C projects/unix clean
|
||||
echo ""
|
||||
make CC="${CC}" CXX="${CXX}" BITS="${{ matrix.bits }}" NEW_DYNAREC="${DYN}" -C projects/unix all
|
||||
echo ""
|
||||
cp projects/unix/*.dll backup/mupen64plus${LIB}.dll
|
||||
ls -gG backup/mupen64plus${LIB}.dll
|
||||
ldd backup/mupen64plus${LIB}.dll
|
||||
unset LIB
|
||||
MSG=" / NEW_DYNAREC"
|
||||
done
|
||||
- name: Copy binaries, dependencies, etc...
|
||||
run: |
|
||||
mkdir pkg
|
||||
if [[ ${{ matrix.bits }} -eq 32 ]]; then LIBGCC="libgcc_s_dw2-1"; else LIBGCC="libgcc_s_seh-1"; fi
|
||||
for LIB in libbrotlicommon libbrotlidec libbz2-1 libfreetype-6 ${LIBGCC} libglib-2.0-0 libgraphite2 libharfbuzz-0 libiconv-2 libintl-8 libpcre-1 libpng16-16 libstdc++-6 libwinpthread-1 SDL2 zlib1
|
||||
do
|
||||
echo ":: Copying ${LIB}.dll"
|
||||
cp "/mingw${{ matrix.bits }}/bin/${LIB}.dll" pkg/
|
||||
done
|
||||
if [ -d data ]; then
|
||||
cd data
|
||||
for DAT in *
|
||||
do
|
||||
echo ":: Copying ${DAT}"
|
||||
cp -r "${DAT}" ../pkg/
|
||||
done
|
||||
fi
|
||||
cd ../backup
|
||||
for BIN in *.dll
|
||||
do
|
||||
echo ":: Copying ${BIN}"
|
||||
cp "${BIN}" ../pkg/
|
||||
done
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: mupen64plus-core-msys2-${{ matrix.platform }}-g${{ env.G_REV }}
|
||||
path: pkg/*
|
||||
|
||||
MSVC:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- toolset: v142
|
||||
platform: x64
|
||||
- toolset: v141_xp
|
||||
platform: x86
|
||||
name: Windows / MSVC ${{ matrix.toolset }} / ${{ matrix.platform }}
|
||||
runs-on: windows-2019
|
||||
defaults:
|
||||
run:
|
||||
shell: cmd
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: microsoft/setup-msbuild@v1.0.3
|
||||
# with:
|
||||
# vs-version: 16.11
|
||||
- name: Build and related stuff
|
||||
run: |
|
||||
for /f "tokens=1" %%R in ('git rev-parse --short HEAD') do set "G_REV=%%R"
|
||||
echo G_REV=%G_REV%>> "%GITHUB_ENV%"
|
||||
set "ARCH=${{ matrix.platform }}"
|
||||
if [%ARCH%] == [x86] set "ARCH=Win32"
|
||||
echo.
|
||||
msbuild --version
|
||||
echo.
|
||||
git clone --depth 1 https://github.com/mupen64plus/mupen64plus-win32-deps.git ..\mupen64plus-win32-deps
|
||||
md backup
|
||||
for %%B in (Release New_Dynarec_Release) do (
|
||||
echo.
|
||||
msbuild "projects\msvc\mupen64plus-core.vcxproj" /p:Configuration=%%B;Platform=%ARCH%;PlatformToolset=${{ matrix.toolset }} /t:Rebuild
|
||||
echo.
|
||||
copy "projects\msvc\%ARCH%\%%B\mupen64plus.dll" backup\
|
||||
if not exist "backup\mupen64plus-old.dll" (
|
||||
ren "backup\mupen64plus.dll" "mupen64plus-old.dll"
|
||||
dir "backup\mupen64plus-old.dll"
|
||||
) else dir "backup\mupen64plus.dll"
|
||||
)
|
||||
- name: Copy binaries, dependencies, etc...
|
||||
run: |
|
||||
md pkg
|
||||
cd pkg
|
||||
xcopy "..\backup" .
|
||||
xcopy "..\data" .
|
||||
copy "..\..\mupen64plus-win32-deps\freetype-2.10.1\lib\${{ matrix.platform }}\*.dll" .
|
||||
copy "..\..\mupen64plus-win32-deps\libpng-1.6.37\lib\${{ matrix.platform }}\*.dll" .
|
||||
copy "..\..\mupen64plus-win32-deps\SDL2-2.0.10\lib\${{ matrix.platform }}\*.dll" .
|
||||
copy "..\..\mupen64plus-win32-deps\SDL2_net-2.0.1\lib\${{ matrix.platform }}\*.dll" .
|
||||
copy "..\..\mupen64plus-win32-deps\zlib-1.2.11\lib\${{ matrix.platform }}\*.dll" .
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: mupen64plus-core-msvc-${{ matrix.platform }}-g${{ env.G_REV }}
|
||||
path: pkg/*
|
||||
|
||||
Nightly-build:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [MSYS2, MSVC]
|
||||
if: github.ref == 'refs/heads/master'
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Download artifacts
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
path: binaries
|
||||
- name: Get some tools
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get -y install hashdeep
|
||||
- name: Creating new artifacts and update nightly-build
|
||||
run: |
|
||||
mkdir pkg
|
||||
cd binaries
|
||||
for BIN in *
|
||||
do
|
||||
echo ":: Creating ${BIN}.zip"
|
||||
cd "${BIN}"
|
||||
zip -r "../../pkg/${BIN}.zip" *
|
||||
cd ..
|
||||
done
|
||||
cd ../pkg
|
||||
echo ""
|
||||
for BIN in *.zip
|
||||
do
|
||||
ls -gG ${BIN}
|
||||
tigerdeep -l ${BIN} >> ${BIN:0:16}.tiger.txt
|
||||
sha256sum ${BIN} >> ${BIN:0:16}.sha256.txt
|
||||
sha512sum ${BIN} >> ${BIN:0:16}.sha512.txt
|
||||
done
|
||||
echo ""
|
||||
echo "TIGER:"
|
||||
cat *.tiger.txt
|
||||
echo ""
|
||||
echo "SHA256:"
|
||||
cat *.sha256.txt
|
||||
echo ""
|
||||
echo "SHA512:"
|
||||
cat *.sha512.txt
|
||||
echo ""
|
||||
git tag -f nightly-build
|
||||
git push -f origin nightly-build
|
||||
- name: Nightly-build
|
||||
uses: ncipollo/release-action@v1
|
||||
with:
|
||||
prerelease: true
|
||||
allowUpdates: true
|
||||
removeArtifacts: true
|
||||
replacesArtifacts: false
|
||||
tag: nightly-build
|
||||
artifacts: pkg/*
|
||||
@@ -99,25 +99,30 @@ endif
|
||||
ifneq ("$(filter arm%,$(HOST_CPU))","")
|
||||
ifeq ("$(filter arm%b,$(HOST_CPU))","")
|
||||
CPU := ARM
|
||||
ARCH_DETECTED := 32BITS
|
||||
PIC ?= 1
|
||||
NEW_DYNAREC := 1
|
||||
CFLAGS += -marm
|
||||
ifneq ("$(filter armv5%,$(HOST_CPU))","")
|
||||
CFLAGS += -DARMv5_ONLY
|
||||
$(warning Using ARMv5_ONLY)
|
||||
endif
|
||||
ifneq ("$(filter armv6%,$(HOST_CPU))","")
|
||||
CFLAGS += -DARMv5_ONLY
|
||||
$(warning Using ARMv5_ONLY)
|
||||
endif
|
||||
ifeq ($(NEON), 1)
|
||||
CFLAGS += -mfpu=neon -mfloat-abi=hard
|
||||
ifneq ("$(filter arm64,$(HOST_CPU))","")
|
||||
ARCH_DETECTED := 64BITS
|
||||
$(warning Architecture "$(HOST_CPU)" not officially supported.)
|
||||
else
|
||||
ifeq ($(VFP_HARD), 1)
|
||||
CFLAGS += -mfpu=vfp -mfloat-abi=hard
|
||||
ARCH_DETECTED := 32BITS
|
||||
CFLAGS += -marm
|
||||
ifneq ("$(filter armv5%,$(HOST_CPU))","")
|
||||
CFLAGS += -DARMv5_ONLY
|
||||
$(warning Using ARMv5_ONLY)
|
||||
endif
|
||||
ifneq ("$(filter armv6%,$(HOST_CPU))","")
|
||||
CFLAGS += -DARMv5_ONLY
|
||||
$(warning Using ARMv5_ONLY)
|
||||
endif
|
||||
ifeq ($(NEON), 1)
|
||||
CFLAGS += -mfpu=neon -mfloat-abi=hard
|
||||
else
|
||||
CFLAGS += -mfpu=vfp -mfloat-abi=softfp
|
||||
ifeq ($(VFP_HARD), 1)
|
||||
CFLAGS += -mfpu=vfp -mfloat-abi=hard
|
||||
else
|
||||
CFLAGS += -mfpu=vfp -mfloat-abi=softfp
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
@@ -175,9 +180,21 @@ ifeq ($(ARCH_DETECTED), 64BITS_32)
|
||||
ifeq ($(OS), FREEBSD)
|
||||
$(error Do not use the BITS=32 option with FreeBSD, use -m32 and -m elf_i386)
|
||||
endif
|
||||
ifneq ($(OS),OSX)
|
||||
CFLAGS += -m32
|
||||
LDFLAGS += -Wl,-m,elf_i386
|
||||
ifneq ($(OS), OSX)
|
||||
ifeq ($(OS), MINGW)
|
||||
CFLAGS += -march=i686
|
||||
LDFLAGS += -Wl,-m,i386pe
|
||||
else
|
||||
CFLAGS += -m32
|
||||
LDFLAGS += -Wl,-m,elf_i386
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(ARCH_DETECTED), 64BITS)
|
||||
ifeq ($(OS), MINGW)
|
||||
CFLAGS += -march=x86-64
|
||||
LDFLAGS += -Wl,-m,i386pep
|
||||
endif
|
||||
endif
|
||||
|
||||
@@ -230,6 +247,11 @@ ifeq ($(OS), OSX)
|
||||
LDFLAGS += -read_only_relocs suppress
|
||||
endif
|
||||
endif
|
||||
ifeq ($(CPU), ARM)
|
||||
# assembly compilation not yet supported on macOS with Apple Silicon
|
||||
NO_ASM = 1
|
||||
CFLAGS += -pipe -arch arm64 -mmacosx-version-min=10.16 -isysroot $(OSX_SDK_PATH)
|
||||
endif
|
||||
endif
|
||||
ifeq ($(OS), MINGW)
|
||||
TARGET = mupen64plus$(POSTFIX).dll
|
||||
|
||||
@@ -23,61 +23,131 @@
|
||||
|
||||
#include "backends/api/storage_backend.h"
|
||||
#include "device/controllers/game_controller.h"
|
||||
#include "main/util.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
/* Serialized representation of ID Block
|
||||
* Only used to ease offsets/pointers computation
|
||||
* DO NOT DEREFERENCE
|
||||
*/
|
||||
#pragma pack(push, 1)
|
||||
struct id_block_serialized {
|
||||
uint32_t serial[6];
|
||||
uint16_t device_id;
|
||||
uint8_t banks;
|
||||
uint8_t version;
|
||||
uint16_t sum;
|
||||
uint16_t isum;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
#if defined(static_assert)
|
||||
static_assert(sizeof(struct id_block_serialized) == 32, "id_block_serialized must have a size of 32 bytes");
|
||||
#endif
|
||||
|
||||
void format_mempak(uint8_t* mem)
|
||||
static void checksum_id_block(unsigned char* ptr,
|
||||
uint16_t* sum, uint16_t* isum)
|
||||
{
|
||||
size_t i;
|
||||
uint16_t accu = 0;
|
||||
for (i = 0; i < offsetof(struct id_block_serialized, sum); i += 2) {
|
||||
accu += load_beu16((void*)&ptr[i]);
|
||||
}
|
||||
*sum = accu;
|
||||
*isum = UINT16_C(0xfff2) - accu;
|
||||
}
|
||||
|
||||
static uint8_t checksum_index_table(size_t count, unsigned char* ptr)
|
||||
{
|
||||
unsigned sum = 0;
|
||||
while (count != 0) {
|
||||
sum += load_beu8((void*)ptr);
|
||||
++ptr;
|
||||
--count;
|
||||
}
|
||||
|
||||
return (uint8_t)sum;
|
||||
}
|
||||
|
||||
static void serialize_id_block(unsigned char *ptr, const uint32_t serial[6], uint16_t device_id, uint8_t banks, uint8_t version) {
|
||||
|
||||
size_t i;
|
||||
/* _ should never be dereferenced - it is only used to ease pointer/offsets computation */
|
||||
struct id_block_serialized* const _ = (struct id_block_serialized*)ptr;
|
||||
|
||||
|
||||
for (i = 0; i < 6; ++i) {
|
||||
store_beu32(serial[i], (void*)&_->serial[i]);
|
||||
}
|
||||
store_beu16(device_id, (void*)&_->device_id);
|
||||
store_beu8(banks, (void*)&_->banks);
|
||||
store_beu8(version, (void*)&_->version);
|
||||
|
||||
uint16_t sum, isum;
|
||||
checksum_id_block(ptr, &sum, &isum);
|
||||
|
||||
store_beu16(sum, (void*)&_->sum);
|
||||
store_beu16(isum, (void*)&_->isum);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void format_mempak(uint8_t* mem,
|
||||
const uint32_t serial[6],
|
||||
uint16_t device_id,
|
||||
uint8_t banks,
|
||||
uint8_t version)
|
||||
{
|
||||
enum { MPK_PAGE_SIZE = 256 };
|
||||
size_t i;
|
||||
|
||||
static const uint8_t page_0[MPK_PAGE_SIZE] =
|
||||
{
|
||||
/* Label area */
|
||||
0x81,0x01,0x02,0x03, 0x04,0x05,0x06,0x07, 0x08,0x09,0x0a,0x0b, 0x0c,0x0d,0x0e,0x0f,
|
||||
0x10,0x11,0x12,0x13, 0x14,0x15,0x16,0x17, 0x18,0x19,0x1a,0x1b, 0x1c,0x1d,0x1e,0x1f,
|
||||
/* Main ID area */
|
||||
0xff,0xff,0xff,0xff, 0x05,0x1a,0x5f,0x13, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
|
||||
0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0x01,0xff, 0x66,0x25,0x99,0xcd,
|
||||
/* Unused */
|
||||
0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
|
||||
/* ID area backup #1 */
|
||||
0xff,0xff,0xff,0xff, 0x05,0x1a,0x5f,0x13, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
|
||||
0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0x01,0xff, 0x66,0x25,0x99,0xcd,
|
||||
/* ID area backup #2 */
|
||||
0xff,0xff,0xff,0xff, 0x05,0x1a,0x5f,0x13, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
|
||||
0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0x01,0xff, 0x66,0x25,0x99,0xcd,
|
||||
/* Unused */
|
||||
0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
|
||||
/* ID area backup #3 */
|
||||
0xff,0xff,0xff,0xff, 0x05,0x1a,0x5f,0x13, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
|
||||
0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0x01,0xff, 0x66,0x25,0x99,0xcd,
|
||||
/* Unused */
|
||||
0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00
|
||||
};
|
||||
uint8_t* const page_0 = mem + 0*MPK_PAGE_SIZE;
|
||||
uint8_t* const page_1 = mem + 1*MPK_PAGE_SIZE;
|
||||
uint8_t* const page_2 = mem + 2*MPK_PAGE_SIZE;
|
||||
uint8_t* const page_3 = mem + 3*MPK_PAGE_SIZE;
|
||||
|
||||
/* Fill Page 0 with pre-initialized content */
|
||||
memcpy(mem, page_0, MPK_PAGE_SIZE);
|
||||
/* Page 0 is divided in 8 x 32-byte blocks:
|
||||
* 0. reserved
|
||||
* 1. ID
|
||||
* 2. reserved
|
||||
* 3. ID backup #1
|
||||
* 4. ID backup #2
|
||||
* 5. reserved
|
||||
* 6. ID backup #3
|
||||
* 7. reserved
|
||||
*/
|
||||
serialize_id_block(page_0 + 1*32, serial, device_id, banks, version);
|
||||
|
||||
/* Fill INODE page 1 and update it's checkum */
|
||||
memset(page_0 + 0*32, 0, 32);
|
||||
memset(page_0 + 2*32, 0, 32);
|
||||
memset(page_0 + 5*32, 0, 32);
|
||||
memset(page_0 + 7*32, 0, 32);
|
||||
|
||||
memcpy(page_0 + 3*32, page_0 + 1*32, 32);
|
||||
memcpy(page_0 + 4*32, page_0 + 1*32, 32);
|
||||
memcpy(page_0 + 6*32, page_0 + 1*32, 32);
|
||||
|
||||
/* Page 1 holds the index table.
|
||||
* The first 5 inodes are reserved because the first 5 pages are reserved.
|
||||
* The first inode page index holds the checksum of the 123 normal nodes.
|
||||
* The remaining 123 pages are marked empty.
|
||||
*/
|
||||
size_t start_page = 5;
|
||||
memset(mem + 1*MPK_PAGE_SIZE, 0, 2*start_page);
|
||||
for (i = 1*MPK_PAGE_SIZE+2*start_page; i < 2*MPK_PAGE_SIZE; i += 2) {
|
||||
mem[i+0] = 0x00;
|
||||
mem[i+1] = 0x03;
|
||||
size_t last_page = 128;
|
||||
size_t i;
|
||||
memset(page_1, 0, 2*start_page);
|
||||
for(i = start_page; i < last_page; ++i) {
|
||||
store_beu16(UINT16_C(0x0003), page_1 + 2*i);
|
||||
}
|
||||
mem[1*MPK_PAGE_SIZE + 1] = 0x71;
|
||||
page_1[1] = checksum_index_table(2*(last_page-start_page), page_1 + 2*start_page);
|
||||
|
||||
/* Page 2 is identical to page 1 */
|
||||
memcpy(mem + 2*MPK_PAGE_SIZE, mem + 1*MPK_PAGE_SIZE, MPK_PAGE_SIZE);
|
||||
/* Page 2 is a backup of Page 1 */
|
||||
memcpy(page_2, page_1, MPK_PAGE_SIZE);
|
||||
|
||||
/* Remaining pages DIR+DATA (3...) are initialized with 0x00 */
|
||||
memset(mem + 3*MPK_PAGE_SIZE, 0, MEMPAK_SIZE - 3*MPK_PAGE_SIZE);
|
||||
memset(page_3, 0, MEMPAK_SIZE - 3*MPK_PAGE_SIZE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -27,6 +27,10 @@
|
||||
|
||||
struct storage_backend_interface;
|
||||
|
||||
#define DEFAULT_MEMPAK_DEVICEID UINT16_C(0x0001)
|
||||
#define DEFAULT_MEMPAK_BANKS UINT8_C(0x01)
|
||||
#define DEFAULT_MEMPAK_VERSION UINT8_C(0x00)
|
||||
|
||||
struct mempak
|
||||
{
|
||||
void* storage;
|
||||
@@ -35,7 +39,11 @@ struct mempak
|
||||
|
||||
enum { MEMPAK_SIZE = 0x8000 };
|
||||
|
||||
void format_mempak(uint8_t* mem);
|
||||
void format_mempak(uint8_t* mem,
|
||||
const uint32_t serial[6],
|
||||
uint16_t device_id,
|
||||
uint8_t banks,
|
||||
uint8_t version);
|
||||
|
||||
void init_mempak(struct mempak* mpk,
|
||||
void* storage,
|
||||
|
||||
@@ -135,6 +135,9 @@ static void* l_paks[GAME_CONTROLLERS_COUNT][PAK_MAX_SIZE];
|
||||
static const struct pak_interface* l_ipaks[PAK_MAX_SIZE];
|
||||
static size_t l_pak_type_idx[6];
|
||||
|
||||
/* PRNG state - used for Mempaks ID generation */
|
||||
static struct xoshiro256pp_state l_mpk_idgen;
|
||||
|
||||
/*********************************************************************************************************
|
||||
* static functions
|
||||
*/
|
||||
@@ -1014,7 +1017,19 @@ static void open_mpk_file(struct file_storage* fstorage)
|
||||
if (ret == (int)file_open_error) {
|
||||
/* if file doesn't exists provide default content */
|
||||
for(i = 0; i < GAME_CONTROLLERS_COUNT; ++i) {
|
||||
format_mempak(fstorage->data + i * MEMPAK_SIZE);
|
||||
|
||||
/* Generate a random serial ID */
|
||||
uint32_t serial[6];
|
||||
size_t k;
|
||||
for (k = 0; k < 6; ++k) {
|
||||
serial[k] = xoshiro256pp_next(&l_mpk_idgen);
|
||||
}
|
||||
|
||||
format_mempak(fstorage->data + i * MEMPAK_SIZE,
|
||||
serial,
|
||||
DEFAULT_MEMPAK_DEVICEID,
|
||||
DEFAULT_MEMPAK_BANKS,
|
||||
DEFAULT_MEMPAK_VERSION);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1471,6 +1486,10 @@ m64p_error main_run(void)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Seed MPK ID gen using current time */
|
||||
uint64_t mpk_seed = !netplay_is_init() ? (uint64_t)time(NULL) : 0;
|
||||
l_mpk_idgen = xoshiro256pp_seed(mpk_seed);
|
||||
|
||||
/* take the r4300 emulator mode from the config file at this point and cache it in a global variable */
|
||||
emumode = ConfigGetParamInt(g_CoreConfig, "R4300Emulator");
|
||||
|
||||
|
||||
@@ -257,6 +257,182 @@ void to_big_endian_buffer(void *buffer, size_t length, size_t count)
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Simple serialization primitives,
|
||||
* Use byte access to avoid alignment issues.
|
||||
*/
|
||||
uint8_t load_beu8(const unsigned char *ptr)
|
||||
{
|
||||
return (uint8_t)ptr[0];
|
||||
}
|
||||
|
||||
uint16_t load_beu16(const unsigned char *ptr)
|
||||
{
|
||||
return ((uint16_t)ptr[0] << 8)
|
||||
| ((uint16_t)ptr[1] << 0);
|
||||
}
|
||||
|
||||
uint32_t load_beu32(const unsigned char *ptr)
|
||||
{
|
||||
return ((uint32_t)ptr[0] << 24)
|
||||
| ((uint32_t)ptr[1] << 16)
|
||||
| ((uint32_t)ptr[2] << 8)
|
||||
| ((uint32_t)ptr[3] << 0);
|
||||
}
|
||||
|
||||
uint64_t load_beu64(const unsigned char *ptr)
|
||||
{
|
||||
return ((uint64_t)ptr[0] << 56)
|
||||
| ((uint64_t)ptr[1] << 48)
|
||||
| ((uint64_t)ptr[2] << 40)
|
||||
| ((uint64_t)ptr[3] << 32)
|
||||
| ((uint64_t)ptr[4] << 24)
|
||||
| ((uint64_t)ptr[5] << 16)
|
||||
| ((uint64_t)ptr[6] << 8)
|
||||
| ((uint64_t)ptr[7] << 0);
|
||||
}
|
||||
|
||||
|
||||
uint8_t load_leu8(const unsigned char *ptr)
|
||||
{
|
||||
return (uint8_t)ptr[0];
|
||||
}
|
||||
|
||||
uint16_t load_leu16(const unsigned char *ptr)
|
||||
{
|
||||
return ((uint16_t)ptr[0] << 0)
|
||||
| ((uint16_t)ptr[1] << 8);
|
||||
}
|
||||
|
||||
uint32_t load_leu32(const unsigned char *ptr)
|
||||
{
|
||||
return ((uint32_t)ptr[0] << 0)
|
||||
| ((uint32_t)ptr[1] << 8)
|
||||
| ((uint32_t)ptr[2] << 16)
|
||||
| ((uint32_t)ptr[3] << 24);
|
||||
}
|
||||
|
||||
uint64_t load_leu64(const unsigned char *ptr)
|
||||
{
|
||||
return ((uint64_t)ptr[0] << 0)
|
||||
| ((uint64_t)ptr[1] << 8)
|
||||
| ((uint64_t)ptr[2] << 16)
|
||||
| ((uint64_t)ptr[3] << 24)
|
||||
| ((uint64_t)ptr[4] << 32)
|
||||
| ((uint64_t)ptr[5] << 40)
|
||||
| ((uint64_t)ptr[6] << 48)
|
||||
| ((uint64_t)ptr[7] << 56);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void store_beu8(uint8_t value, unsigned char *ptr)
|
||||
{
|
||||
ptr[0] = (uint8_t)value;
|
||||
}
|
||||
|
||||
void store_beu16(uint16_t value, unsigned char *ptr)
|
||||
{
|
||||
ptr[0] = (uint8_t)(value >> 8);
|
||||
ptr[1] = (uint8_t)(value >> 0);
|
||||
}
|
||||
|
||||
void store_beu32(uint32_t value, unsigned char *ptr)
|
||||
{
|
||||
ptr[0] = (uint8_t)(value >> 24);
|
||||
ptr[1] = (uint8_t)(value >> 16);
|
||||
ptr[2] = (uint8_t)(value >> 8);
|
||||
ptr[3] = (uint8_t)(value >> 0);
|
||||
}
|
||||
|
||||
void store_beu64(uint64_t value, unsigned char *ptr)
|
||||
{
|
||||
ptr[0] = (uint8_t)(value >> 56);
|
||||
ptr[1] = (uint8_t)(value >> 48);
|
||||
ptr[2] = (uint8_t)(value >> 40);
|
||||
ptr[3] = (uint8_t)(value >> 32);
|
||||
ptr[4] = (uint8_t)(value >> 24);
|
||||
ptr[5] = (uint8_t)(value >> 16);
|
||||
ptr[6] = (uint8_t)(value >> 8);
|
||||
ptr[7] = (uint8_t)(value >> 0);
|
||||
}
|
||||
|
||||
|
||||
void store_leu8(uint8_t value, unsigned char *ptr)
|
||||
{
|
||||
ptr[0] = (uint8_t)value;
|
||||
}
|
||||
|
||||
void store_leu16(uint16_t value, unsigned char *ptr)
|
||||
{
|
||||
ptr[0] = (uint8_t)(value >> 0);
|
||||
ptr[1] = (uint8_t)(value >> 8);
|
||||
}
|
||||
|
||||
void store_leu32(uint32_t value, unsigned char *ptr)
|
||||
{
|
||||
ptr[0] = (uint8_t)(value >> 0);
|
||||
ptr[1] = (uint8_t)(value >> 8);
|
||||
ptr[2] = (uint8_t)(value >> 16);
|
||||
ptr[3] = (uint8_t)(value >> 24);
|
||||
}
|
||||
|
||||
void store_leu64(uint64_t value, unsigned char *ptr)
|
||||
{
|
||||
ptr[0] = (uint8_t)(value >> 0);
|
||||
ptr[1] = (uint8_t)(value >> 8);
|
||||
ptr[2] = (uint8_t)(value >> 16);
|
||||
ptr[3] = (uint8_t)(value >> 24);
|
||||
ptr[4] = (uint8_t)(value >> 32);
|
||||
ptr[5] = (uint8_t)(value >> 40);
|
||||
ptr[6] = (uint8_t)(value >> 48);
|
||||
ptr[7] = (uint8_t)(value >> 56);
|
||||
}
|
||||
|
||||
|
||||
/**********************
|
||||
Random utilities
|
||||
**********************/
|
||||
|
||||
static inline uint64_t rotl(uint64_t x, int k) {
|
||||
return (x << k) | (x >> (64 - k));
|
||||
}
|
||||
|
||||
struct splitmix64_state { uint64_t x; };
|
||||
|
||||
static uint64_t splitmix64_next(struct splitmix64_state* s) {
|
||||
uint64_t z = (s->x += 0x9e3779b97f4a7c15);
|
||||
z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
|
||||
z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
|
||||
return z ^ (z >> 31);
|
||||
}
|
||||
|
||||
struct xoshiro256pp_state xoshiro256pp_seed(uint64_t seed)
|
||||
{
|
||||
struct xoshiro256pp_state xs;
|
||||
struct splitmix64_state ss = { seed };
|
||||
|
||||
size_t i;
|
||||
for (i = 0; i < 4; ++i) {
|
||||
xs.s[i] = splitmix64_next(&ss);
|
||||
}
|
||||
|
||||
return xs;
|
||||
}
|
||||
|
||||
uint64_t xoshiro256pp_next(struct xoshiro256pp_state* s) {
|
||||
uint64_t result = rotl(s->s[0] + s->s[3], 23) + s->s[0];
|
||||
|
||||
uint64_t t = s->s[1] << 17;
|
||||
s->s[2] ^= s->s[0];
|
||||
s->s[3] ^= s->s[1];
|
||||
s->s[1] ^= s->s[2];
|
||||
s->s[0] ^= s->s[3];
|
||||
s->s[2] ^= t;
|
||||
s->s[3] = rotl(s->s[3], 45);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**********************
|
||||
GUI utilities
|
||||
**********************/
|
||||
|
||||
@@ -150,6 +150,41 @@ void swap_buffer(void *buffer, size_t length, size_t count);
|
||||
void to_little_endian_buffer(void *buffer, size_t length, size_t count);
|
||||
void to_big_endian_buffer(void *buffer, size_t length, size_t count);
|
||||
|
||||
|
||||
/* Simple serialization primitives,
|
||||
* Loosely modeled after N2827 <stdbit.h> proposal.
|
||||
*/
|
||||
uint8_t load_beu8(const unsigned char *ptr);
|
||||
uint16_t load_beu16(const unsigned char *ptr);
|
||||
uint32_t load_beu32(const unsigned char *ptr);
|
||||
uint64_t load_beu64(const unsigned char *ptr);
|
||||
|
||||
uint8_t load_leu8(const unsigned char *ptr);
|
||||
uint16_t load_leu16(const unsigned char *ptr);
|
||||
uint32_t load_leu32(const unsigned char *ptr);
|
||||
uint64_t load_leu64(const unsigned char *ptr);
|
||||
|
||||
void store_beu8(uint8_t value, unsigned char *ptr);
|
||||
void store_beu16(uint16_t value, unsigned char *ptr);
|
||||
void store_beu32(uint32_t value, unsigned char *ptr);
|
||||
void store_beu64(uint64_t value, unsigned char *ptr);
|
||||
|
||||
void store_leu8(uint8_t value, unsigned char *ptr);
|
||||
void store_leu16(uint16_t value, unsigned char *ptr);
|
||||
void store_leu32(uint32_t value, unsigned char *ptr);
|
||||
void store_leu64(uint64_t value, unsigned char *ptr);
|
||||
|
||||
|
||||
/**********************
|
||||
Random utilities
|
||||
**********************/
|
||||
|
||||
struct xoshiro256pp_state { uint64_t s[4]; };
|
||||
|
||||
struct xoshiro256pp_state xoshiro256pp_seed(uint64_t seed);
|
||||
|
||||
uint64_t xoshiro256pp_next(struct xoshiro256pp_state* s);
|
||||
|
||||
/**********************
|
||||
GUI utilities
|
||||
**********************/
|
||||
|
||||
Reference in new issue
Block a user