mirror of https://github.com/ClassiCube/ClassiCube
Merge branch 'master' of https://github.com/UnknownShadow200/ClassiCube into AndroidUI2
This commit is contained in:
commit
14be9f0856
|
|
@ -1,5 +1,10 @@
|
|||
name: Build latest (3DS)
|
||||
on: [push]
|
||||
# trigger via either push to selected branches or on manual run
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.ref }}-3ds
|
||||
|
|
@ -7,7 +12,6 @@ concurrency:
|
|||
|
||||
jobs:
|
||||
build-3DS:
|
||||
if: github.ref_name == github.event.repository.default_branch
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: devkitpro/devkitarm:latest
|
||||
|
|
|
|||
|
|
@ -1,5 +1,10 @@
|
|||
name: Build latest (Dreamcast)
|
||||
on: [push]
|
||||
# trigger via either push to selected branches or on manual run
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.ref }}-dreamcast
|
||||
|
|
@ -7,7 +12,6 @@ concurrency:
|
|||
|
||||
jobs:
|
||||
build:
|
||||
if: github.ref_name == github.event.repository.default_branch
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: kazade/dreamcast-sdk
|
||||
|
|
|
|||
|
|
@ -1,5 +1,10 @@
|
|||
name: Build latest (FreeBSD)
|
||||
on: [push]
|
||||
# trigger via either push to selected branches or on manual run
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.ref }}-freebsd
|
||||
|
|
@ -7,7 +12,6 @@ concurrency:
|
|||
|
||||
jobs:
|
||||
build:
|
||||
if: github.ref_name == github.event.repository.default_branch
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: empterdose/freebsd-cross-build:11.4
|
||||
|
|
|
|||
|
|
@ -1,5 +1,10 @@
|
|||
name: Build latest (Haiku)
|
||||
on: [push]
|
||||
# trigger via either push to selected branches or on manual run
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.ref }}-haiku
|
||||
|
|
@ -7,7 +12,6 @@ concurrency:
|
|||
|
||||
jobs:
|
||||
build-haiku:
|
||||
if: github.ref_name == github.event.repository.default_branch
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: haiku/cross-compiler:x86_64-r1beta4
|
||||
|
|
|
|||
|
|
@ -1,5 +1,10 @@
|
|||
name: Build latest (iOS)
|
||||
on: [push]
|
||||
# trigger via either push to selected branches or on manual run
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.ref }}-ios
|
||||
|
|
@ -7,7 +12,6 @@ concurrency:
|
|||
|
||||
jobs:
|
||||
build:
|
||||
if: github.ref_name == github.event.repository.default_branch
|
||||
runs-on: macOS-11
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
|
|
|||
|
|
@ -1,5 +1,11 @@
|
|||
name: Build latest (Linux)
|
||||
on: [push]
|
||||
# trigger via either push to selected branches or on manual run
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- ModernLighting
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.ref }}-linux
|
||||
|
|
@ -10,7 +16,6 @@ jobs:
|
|||
# =============== 32 BIT LINUX ==============
|
||||
# ===========================================
|
||||
build-32:
|
||||
if: github.ref_name == github.event.repository.default_branch
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
|
@ -64,7 +69,6 @@ jobs:
|
|||
# =============== 64 BIT LINUX ==============
|
||||
# ===========================================
|
||||
build-64:
|
||||
if: github.ref_name == github.event.repository.default_branch
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
|
|
|||
|
|
@ -1,5 +1,10 @@
|
|||
name: Build latest (macOS 64 bit)
|
||||
on: [push]
|
||||
# trigger via either push to selected branches or on manual run
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.ref }}-mac64
|
||||
|
|
@ -7,7 +12,6 @@ concurrency:
|
|||
|
||||
jobs:
|
||||
build:
|
||||
if: github.ref_name == github.event.repository.default_branch
|
||||
runs-on: macOS-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
|
|
|||
|
|
@ -1,5 +1,10 @@
|
|||
name: Build latest (N64)
|
||||
on: [push]
|
||||
# trigger via either push to selected branches or on manual run
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.ref }}-n64
|
||||
|
|
@ -7,7 +12,6 @@ concurrency:
|
|||
|
||||
jobs:
|
||||
build:
|
||||
if: github.ref_name == github.event.repository.default_branch
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: ghcr.io/dragonminded/libdragon:latest
|
||||
|
|
|
|||
|
|
@ -1,5 +1,10 @@
|
|||
name: Build latest (NDS)
|
||||
on: [push]
|
||||
# trigger via either push to selected branches or on manual run
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.ref }}-nds
|
||||
|
|
@ -7,7 +12,6 @@ concurrency:
|
|||
|
||||
jobs:
|
||||
build-DS:
|
||||
if: github.ref_name == github.event.repository.default_branch
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: skylyrac/blocksds:dev-latest
|
||||
|
|
|
|||
|
|
@ -1,5 +1,10 @@
|
|||
name: Build latest (NetBSD)
|
||||
on: [push]
|
||||
# trigger via either push to selected branches or on manual run
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.ref }}-netbsd
|
||||
|
|
@ -7,7 +12,6 @@ concurrency:
|
|||
|
||||
jobs:
|
||||
build:
|
||||
if: github.ref_name == github.event.repository.default_branch
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: ghcr.io/cross-rs/x86_64-unknown-netbsd
|
||||
|
|
|
|||
|
|
@ -1,5 +1,10 @@
|
|||
name: Build latest (PS2)
|
||||
on: [push]
|
||||
# trigger via either push to selected branches or on manual run
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.ref }}-ps2
|
||||
|
|
@ -7,7 +12,6 @@ concurrency:
|
|||
|
||||
jobs:
|
||||
build:
|
||||
if: github.ref_name == github.event.repository.default_branch
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: ghcr.io/ps2dev/ps2sdk:latest
|
||||
|
|
|
|||
|
|
@ -1,5 +1,10 @@
|
|||
name: Build latest (PS3)
|
||||
on: [push]
|
||||
# trigger via either push to selected branches or on manual run
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.ref }}-ps3
|
||||
|
|
@ -7,7 +12,6 @@ concurrency:
|
|||
|
||||
jobs:
|
||||
build-PS3:
|
||||
if: github.ref_name == github.event.repository.default_branch
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: ghcr.io/classicube/minimal-psl1ght:latest
|
||||
|
|
|
|||
|
|
@ -1,5 +1,10 @@
|
|||
name: Build latest (PSP)
|
||||
on: [push]
|
||||
# trigger via either push to selected branches or on manual run
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.ref }}-psp
|
||||
|
|
@ -7,7 +12,6 @@ concurrency:
|
|||
|
||||
jobs:
|
||||
build-PSP:
|
||||
if: github.ref_name == github.event.repository.default_branch
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: pspdev/pspdev:latest
|
||||
|
|
|
|||
|
|
@ -1,5 +1,10 @@
|
|||
name: Build latest (RPI)
|
||||
on: [push]
|
||||
# trigger via either push to selected branches or on manual run
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.ref }}-rpi
|
||||
|
|
@ -10,7 +15,6 @@ jobs:
|
|||
# ================ 32 BIT RPI ===============
|
||||
# ===========================================
|
||||
build-RPI32:
|
||||
if: github.ref_name == github.event.repository.default_branch
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: dockcross/linux-armv6-lts
|
||||
|
|
@ -59,7 +63,6 @@ jobs:
|
|||
# ================ 64 BIT RPI ===============
|
||||
# ===========================================
|
||||
build-RPI64:
|
||||
if: github.ref_name == github.event.repository.default_branch
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: dockcross/linux-arm64-lts
|
||||
|
|
|
|||
|
|
@ -1,5 +1,10 @@
|
|||
name: Build latest (Saturn)
|
||||
on: [push]
|
||||
# trigger via either push to selected branches or on manual run
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.ref }}-saturn
|
||||
|
|
@ -7,7 +12,6 @@ concurrency:
|
|||
|
||||
jobs:
|
||||
build:
|
||||
if: github.ref_name == github.event.repository.default_branch
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: ijacquez/yaul
|
||||
|
|
@ -36,3 +40,9 @@ jobs:
|
|||
with:
|
||||
SOURCE_FILE: 'ClassiCube-saturn.iso'
|
||||
DEST_NAME: 'ClassiCube-saturn.iso'
|
||||
|
||||
- uses: ./.github/actions/upload_build
|
||||
if: ${{ always() && steps.compile.outcome == 'success' }}
|
||||
with:
|
||||
SOURCE_FILE: 'ClassiCube-saturn.cue'
|
||||
DEST_NAME: 'ClassiCube-saturn.cue'
|
||||
|
|
@ -1,5 +1,10 @@
|
|||
name: Build latest (Switch)
|
||||
on: [push]
|
||||
# trigger via either push to selected branches or on manual run
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.ref }}-switch
|
||||
|
|
@ -7,7 +12,6 @@ concurrency:
|
|||
|
||||
jobs:
|
||||
build-switch:
|
||||
if: github.ref_name == github.event.repository.default_branch
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: devkitpro/devkita64:latest
|
||||
|
|
|
|||
|
|
@ -1,5 +1,10 @@
|
|||
name: Build latest (Vita)
|
||||
on: [push]
|
||||
# trigger via either push to selected branches or on manual run
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.ref }}-vita
|
||||
|
|
@ -7,7 +12,6 @@ concurrency:
|
|||
|
||||
jobs:
|
||||
build-Vita:
|
||||
if: github.ref_name == github.event.repository.default_branch
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: vitasdk/vitasdk:latest
|
||||
|
|
|
|||
|
|
@ -0,0 +1,44 @@
|
|||
name: Build latest (Webclient)
|
||||
# trigger via either push to selected branches or on manual run
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.ref }}-webclient
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: trzeci/emscripten-fastcomp:1.39.0
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Compiles webclient
|
||||
id: compile
|
||||
run: |
|
||||
cd src
|
||||
emcc *.c -o ClassiCube.js -s WASM=0 -s NO_EXIT_RUNTIME=1 -s LEGACY_VM_SUPPORT=1 -s ALLOW_MEMORY_GROWTH=1 -s ABORTING_MALLOC=0 -s ENVIRONMENT=web -s TOTAL_STACK=256Kb --js-library interop_web.js -Os -g2 -s SINGLE_FILE
|
||||
sed -i 's#eventHandler.useCapture);#{ useCapture: eventHandler.useCapture, passive: false });#g' ClassiCube.js
|
||||
|
||||
- uses: ./.github/actions/notify_failure
|
||||
if: ${{ always() && steps.compile.outcome == 'failure' }}
|
||||
with:
|
||||
NOTIFY_MESSAGE: 'Failed to compile Webclient'
|
||||
WEBHOOK_URL: '${{ secrets.WEBHOOK_URL }}'
|
||||
|
||||
- uses: ./.github/actions/upload_build
|
||||
if: ${{ always() && steps.compile.outcome == 'success' }}
|
||||
with:
|
||||
SOURCE_FILE: 'src/ClassiCube.js'
|
||||
DEST_NAME: 'ClassiCube.js'
|
||||
|
||||
|
||||
- uses: ./.github/actions/notify_success
|
||||
if: ${{ always() && steps.compile.outcome == 'success' }}
|
||||
with:
|
||||
DESTINATION_URL: '${{ secrets.NOTIFY_URL }}'
|
||||
WORKFLOW_NAME: 'webclient'
|
||||
|
|
@ -1,5 +1,10 @@
|
|||
name: Build latest (Wii/GameCube)
|
||||
on: [push]
|
||||
# trigger via either push to selected branches or on manual run
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.ref }}-wiigc
|
||||
|
|
@ -7,7 +12,6 @@ concurrency:
|
|||
|
||||
jobs:
|
||||
build:
|
||||
if: github.ref_name == github.event.repository.default_branch
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: devkitpro/devkitppc:latest
|
||||
|
|
|
|||
|
|
@ -1,5 +1,10 @@
|
|||
name: Build latest (WiiU)
|
||||
on: [push]
|
||||
# trigger via either push to selected branches or on manual run
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.ref }}-wiiu
|
||||
|
|
@ -7,7 +12,6 @@ concurrency:
|
|||
|
||||
jobs:
|
||||
build:
|
||||
if: github.ref_name == github.event.repository.default_branch
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: devkitpro/devkitppc:latest
|
||||
|
|
|
|||
|
|
@ -0,0 +1,79 @@
|
|||
name: Build latest (Windows ARM32/64)
|
||||
# trigger via either push to selected branches or on manual run
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.ref }}-windows-arm
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
#============================================
|
||||
# ============== ARM32 WINDOWS ==============
|
||||
# ===========================================
|
||||
build-32:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: dockcross/windows-armv7
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Compile ARM32 Windows builds
|
||||
shell: bash
|
||||
id: compile
|
||||
env:
|
||||
COMMON_FLAGS: "-O1 -s -fno-stack-protector -fno-math-errno -Qn"
|
||||
WIN32_FLAGS: "-mwindows -nostartfiles -Wl,-emain_real -DCC_NOMAIN"
|
||||
run: |
|
||||
LATEST_FLAG=-DCC_COMMIT_SHA=\"${GITHUB_SHA::9}\"
|
||||
|
||||
cd src
|
||||
armv7-w64-mingw32-gcc *.c ${{ env.COMMON_FLAGS }} ${{ env.WIN32_FLAGS }} -o cc-arm32-d3d11.exe $LATEST_FLAG -DCC_BUILD_MANUAL -DCC_BUILD_WIN -DCC_BUILD_D3D11 -DCC_BUILD_WINGUI -DCC_BUILD_WGL -DCC_BUILD_WINMM -DCC_BUILD_HTTPCLIENT -DCC_BUILD_SCHANNEL -lwinmm -limagehlp
|
||||
|
||||
|
||||
- uses: ./.github/actions/notify_failure
|
||||
if: ${{ always() && steps.compile.outcome == 'failure' }}
|
||||
with:
|
||||
NOTIFY_MESSAGE: 'Failed to compile 32 bit Windows build'
|
||||
WEBHOOK_URL: '${{ secrets.WEBHOOK_URL }}'
|
||||
|
||||
- uses: ./.github/actions/upload_build
|
||||
if: ${{ always() && steps.compile.outcome == 'success' }}
|
||||
with:
|
||||
SOURCE_FILE: 'src/cc-arm32-d3d11.exe'
|
||||
DEST_NAME: 'ClassiCube-arm32-Direct3D11.exe'
|
||||
#============================================
|
||||
# ============== ARM64 WINDOWS ==============
|
||||
# ===========================================
|
||||
build-64:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: dockcross/windows-arm64
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Compile ARM64 Windows builds
|
||||
shell: bash
|
||||
id: compile
|
||||
env:
|
||||
COMMON_FLAGS: "-O1 -s -fno-stack-protector -fno-math-errno -Qn"
|
||||
WIN64_FLAGS: "-mwindows -nostartfiles -Wl,-emain_real -DCC_NOMAIN"
|
||||
run: |
|
||||
LATEST_FLAG=-DCC_COMMIT_SHA=\"${GITHUB_SHA::9}\"
|
||||
|
||||
cd src
|
||||
aarch64-w64-mingw32-gcc *.c ${{ env.COMMON_FLAGS }} ${{ env.WIN64_FLAGS }} -o cc-arm64-d3d11.exe $LATEST_FLAG -DCC_BUILD_MANUAL -DCC_BUILD_WIN -DCC_BUILD_D3D11 -DCC_BUILD_WINGUI -DCC_BUILD_WGL -DCC_BUILD_WINMM -DCC_BUILD_HTTPCLIENT -DCC_BUILD_SCHANNEL -lwinmm -limagehlp
|
||||
|
||||
|
||||
- uses: ./.github/actions/notify_failure
|
||||
if: ${{ always() && steps.compile.outcome == 'failure' }}
|
||||
with:
|
||||
NOTIFY_MESSAGE: 'Failed to compile 64 bit Windows build'
|
||||
WEBHOOK_URL: '${{ secrets.WEBHOOK_URL }}'
|
||||
|
||||
- uses: ./.github/actions/upload_build
|
||||
if: ${{ always() && steps.compile.outcome == 'success' }}
|
||||
with:
|
||||
SOURCE_FILE: 'src/cc-arm64-d3d11.exe'
|
||||
DEST_NAME: 'ClassiCube-arm64-Direct3D11.exe'
|
||||
|
|
@ -1,5 +1,11 @@
|
|||
name: Build latest (Windows)
|
||||
on: [push]
|
||||
# trigger via either push to selected branches or on manual run
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- ModernLighting
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.ref }}-windows
|
||||
|
|
@ -10,7 +16,6 @@ jobs:
|
|||
# ============== 32 BIT WINDOWS =============
|
||||
# ===========================================
|
||||
build-32:
|
||||
if: github.ref_name == github.event.repository.default_branch
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
|
@ -77,7 +82,6 @@ jobs:
|
|||
# ============== 64 BIT WINDOWS =============
|
||||
# ===========================================
|
||||
build-64:
|
||||
if: github.ref_name == github.event.repository.default_branch
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
|
|
|||
|
|
@ -1,5 +1,10 @@
|
|||
name: Build latest (Xbox)
|
||||
on: [push]
|
||||
# trigger via either push to selected branches or on manual run
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.ref }}-xbox
|
||||
|
|
@ -7,7 +12,6 @@ concurrency:
|
|||
|
||||
jobs:
|
||||
build-Xbox:
|
||||
if: github.ref_name == github.event.repository.default_branch
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: ghcr.io/xboxdev/nxdk:git-e955705a
|
||||
|
|
|
|||
|
|
@ -1,13 +1,17 @@
|
|||
name: Build latest (Xbox 360)
|
||||
on: [push]
|
||||
# trigger via either push to selected branches or on manual run
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.ref }}-xbox360
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
build-Xbox:
|
||||
if: github.ref_name == github.event.repository.default_branch
|
||||
build-360:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: free60/libxenon
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ concurrency:
|
|||
|
||||
jobs:
|
||||
build:
|
||||
if: github.ref_name == github.event.repository.default_branch
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
|
|
|||
|
|
@ -38,6 +38,12 @@ build-saturn/
|
|||
cd/
|
||||
# Microsoft console build results
|
||||
build-360/
|
||||
main.exe
|
||||
main.lib
|
||||
misc/xbox/ps_coloured.inl
|
||||
misc/xbox/ps_textured.inl
|
||||
misc/xbox/vs_coloured.inl
|
||||
misc/xbox/vs_textured.inl
|
||||
# Sony console build results
|
||||
build-ps2/
|
||||
build-ps3/
|
||||
|
|
@ -91,6 +97,8 @@ CMakeCache.txt
|
|||
|
||||
#GCC object files
|
||||
*.o
|
||||
# Build dependency files
|
||||
*.d
|
||||
|
||||
# Roslyn cache directories
|
||||
*.ide/
|
||||
|
|
|
|||
|
|
@ -506,7 +506,7 @@
|
|||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
|
|
@ -559,7 +559,7 @@
|
|||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
MTL_FAST_MATH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
|
|
@ -573,7 +573,7 @@
|
|||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
INFOPLIST_FILE = Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
|
|
@ -590,7 +590,7 @@
|
|||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
INFOPLIST_FILE = Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
Copyright (c) 2014 - 2022, UnknownShadow200
|
||||
Copyright (c) 2014 - 2024, UnknownShadow200
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,93 @@
|
|||
!r0 = clip flags
|
||||
!r1 = GPU command
|
||||
!r2 = temp
|
||||
!r3 = prefetch address
|
||||
!r4 = src pointer ARG
|
||||
!r5 = dst pointer ARG
|
||||
!r6 = quads count ARG
|
||||
!r7 = ?
|
||||
|
||||
!fr0 = temp
|
||||
!fr1 = u (0.0)
|
||||
!fr2 = v (0.0)
|
||||
!fr3 = c
|
||||
!fr4 = x
|
||||
!fr5 = y
|
||||
!fr6 = z
|
||||
!fr7 = w
|
||||
!fr8 = VIEWPORT_HWIDTH
|
||||
!fr9 = VIEWPORT_HHEIGHT
|
||||
!fr10 = VIEWPORT_X_PLUS_HWIDTH
|
||||
!fr11 = VIEWPORT_Y_PLUS_HHEIGHT
|
||||
|
||||
!fv4 = XYZW
|
||||
|
||||
#include "ViewportTransform.S"
|
||||
.global _DrawColouredQuads
|
||||
.align 4
|
||||
.type _DrawColouredQuads,%function
|
||||
|
||||
_DrawColouredQuads:
|
||||
! Setup
|
||||
fldi0 fr1 ! U = 0
|
||||
fldi0 fr2 ! V = 0
|
||||
mov r4,r3 ! r3 = src
|
||||
add #-32, r5 ! r5 -= sizeof(VERTEX)
|
||||
ViewportTransformSetup _VP_COL_HWIDTH
|
||||
|
||||
.TRANSFORM_QUAD:
|
||||
mov.l CMD_COL_VERT, r1 ! r1 = GPU VERT command
|
||||
|
||||
LoadColouredVertex
|
||||
ProcessVertex1
|
||||
|
||||
LoadColouredVertex
|
||||
ProcessVertex2
|
||||
|
||||
LoadColouredVertex
|
||||
ProcessVertex3
|
||||
|
||||
LoadColouredVertex
|
||||
ProcessVertex4 CMD_COL_EOS
|
||||
|
||||
! CLIPFLAGS TESTING
|
||||
cmp/eq #0,r0 ! T = r0 == 0 (all points invisible)
|
||||
bt/s .NO_POINTS_VISIBLE ! if T goto NO_POINTS_VISIBLE
|
||||
nop
|
||||
bra .SOME_POINTS_VISIBLE
|
||||
nop
|
||||
|
||||
.NO_POINTS_VISIBLE:
|
||||
bra .LOOP_END ! jump to loop end after executing instruction in delay slot
|
||||
add #-128, r5 ! r5 -= 4 * sizeof(VERTEX), move back to 1 vertex before start of quad
|
||||
|
||||
.SOME_POINTS_VISIBLE:
|
||||
|
||||
.LOOP_END:
|
||||
dt r6 ! r6--; T = r6 == 0
|
||||
bf .TRANSFORM_QUAD ! if !T then goto TRANSFORM_QUAD
|
||||
nop
|
||||
|
||||
add #32, r5 ! r5 += sizeof(VERTEX)
|
||||
rts ! return after executing instruction in delay slot
|
||||
mov r5,r0 ! r0 = r5
|
||||
|
||||
.align 2
|
||||
CMD_COL_VERT: .long 0xe0000000
|
||||
CMD_COL_EOS: .long 0xf0000000
|
||||
|
||||
.global _VP_COL_HWIDTH
|
||||
.type _VP_COL_HWIDTH,%object
|
||||
_VP_COL_HWIDTH: .long 0
|
||||
|
||||
.global _VP_COL_HHEIGHT
|
||||
.type _VP_COL_HHEIGHT,%object
|
||||
_VP_COL_HHEIGHT: .long 0
|
||||
|
||||
.global _VP_COL_X_PLUS_HWIDTH
|
||||
.type _VP_COL_X_PLUS_HWIDTH,%object
|
||||
_VP_COL_X_PLUS_HWIDTH: .long 0
|
||||
|
||||
.global _VP_COL_Y_PLUS_HHEIGHT
|
||||
.type _VP_COL_Y_PLUS_HHEIGHT,%object
|
||||
_VP_COL_Y_PLUS_HHEIGHT: .long 0
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
!r0 = clip flags
|
||||
!r1 = GPU command
|
||||
!r2 = temp
|
||||
!r3 = prefetch address
|
||||
!r4 = src pointer ARG
|
||||
!r5 = dst pointer ARG
|
||||
!r6 = quads count ARG
|
||||
!r7 = ?
|
||||
|
||||
!fr0 = temp
|
||||
!fr1 = u
|
||||
!fr2 = v
|
||||
!fr3 = c
|
||||
!fr4 = x
|
||||
!fr5 = y
|
||||
!fr6 = z
|
||||
!fr7 = w
|
||||
!fr8 = VIEWPORT_HWIDTH
|
||||
!fr9 = VIEWPORT_HHEIGHT
|
||||
!fr10 = VIEWPORT_X_PLUS_HWIDTH
|
||||
!fr11 = VIEWPORT_Y_PLUS_HHEIGHT
|
||||
|
||||
!fv4 = XYZW
|
||||
|
||||
#include "ViewportTransform.S"
|
||||
.global _DrawTexturedQuads
|
||||
.align 4
|
||||
.type _DrawTexturedQuads,%function
|
||||
|
||||
_DrawTexturedQuads:
|
||||
! Setup
|
||||
mov r4,r3 ! r3 = src
|
||||
add #-32, r5 ! r5 -= sizeof(VERTEX)
|
||||
ViewportTransformSetup _VP_TEX_HWIDTH
|
||||
|
||||
.TRANSFORM_QUAD:
|
||||
mov.l CMD_TEX_VERT, r1 ! r1 = GPU VERT command
|
||||
|
||||
LoadTexturedVertex
|
||||
ProcessVertex1
|
||||
|
||||
LoadTexturedVertex
|
||||
ProcessVertex2
|
||||
|
||||
LoadTexturedVertex
|
||||
ProcessVertex3
|
||||
|
||||
LoadTexturedVertex
|
||||
ProcessVertex4 CMD_TEX_EOS
|
||||
|
||||
! CLIPFLAGS TESTING
|
||||
cmp/eq #0,r0 ! T = r0 == 0 (all points invisible)
|
||||
bt/s .NO_POINTS_VISIBLE ! if T goto NO_POINTS_VISIBLE
|
||||
nop
|
||||
bra .SOME_POINTS_VISIBLE
|
||||
nop
|
||||
|
||||
.NO_POINTS_VISIBLE:
|
||||
bra .LOOP_END ! jump to loop end after executing instruction in delay slot
|
||||
add #-128, r5 ! r5 -= 4 * sizeof(VERTEX), move back to prior quad, so that this invisible quad gets overwritten in next iteration
|
||||
|
||||
.SOME_POINTS_VISIBLE:
|
||||
|
||||
.LOOP_END:
|
||||
dt r6 ! r6--; T = r6 == 0
|
||||
bf .TRANSFORM_QUAD ! if !T then goto TRANSFORM_QUAD
|
||||
nop
|
||||
|
||||
add #32, r5 ! r5 += sizeof(VERTEX)
|
||||
rts ! return after executing instruction in delay slot
|
||||
mov r5,r0 ! r0 = r5
|
||||
|
||||
.align 2
|
||||
CMD_TEX_VERT: .long 0xe0000000
|
||||
CMD_TEX_EOS: .long 0xf0000000
|
||||
|
||||
.global _VP_TEX_HWIDTH
|
||||
.type _VP_TEX_HWIDTH,%object
|
||||
_VP_TEX_HWIDTH: .long 0
|
||||
|
||||
.global _VP_TEX_HHEIGHT
|
||||
.type _VP_TEX_HHEIGHT,%object
|
||||
_VP_TEX_HHEIGHT: .long 0
|
||||
|
||||
.global _VP_TEX_X_PLUS_HWIDTH
|
||||
.type _VP_TEX_X_PLUS_HWIDTH,%object
|
||||
_VP_TEX_X_PLUS_HWIDTH: .long 0
|
||||
|
||||
.global _VP_TEX_Y_PLUS_HHEIGHT
|
||||
.type _VP_TEX_Y_PLUS_HHEIGHT,%object
|
||||
_VP_TEX_Y_PLUS_HHEIGHT: .long 0
|
||||
|
|
@ -1,8 +1,9 @@
|
|||
BUILD_DIR := build-dc
|
||||
SOURCE_DIRS := src third_party/bearssl/src
|
||||
SOURCE_DIRS := src third_party/bearssl/src misc/dreamcast
|
||||
|
||||
S_FILES := $(foreach dir,$(SOURCE_DIRS),$(wildcard $(dir)/*.S))
|
||||
C_FILES := $(foreach dir,$(SOURCE_DIRS),$(wildcard $(dir)/*.c))
|
||||
OBJS := $(addprefix $(BUILD_DIR)/, $(notdir $(C_FILES:%.c=%.o)))
|
||||
OBJS := $(addprefix $(BUILD_DIR)/, $(notdir $(C_FILES:%.c=%.o) $(S_FILES:%.S=%.o)))
|
||||
CFLAGS :=-g -O1 -pipe -fno-math-errno -Ithird_party/bearssl/inc
|
||||
|
||||
GLDC_LIB=third_party/gldc/libGLdc.a
|
||||
|
|
@ -21,8 +22,9 @@ default: $(CC_TEXTURES) $(GLDC_LIB) $(BUILD_DIR) $(TARGET).cdi
|
|||
$(BUILD_DIR):
|
||||
mkdir -p $(BUILD_DIR)
|
||||
|
||||
$(GLDC_LIB):
|
||||
$(GLDC_LIB): FORCE
|
||||
$(MAKE) -C third_party/gldc
|
||||
FORCE: ;
|
||||
|
||||
# TODO add textures to misc folder ?
|
||||
$(CC_TEXTURES):
|
||||
|
|
@ -31,6 +33,9 @@ $(CC_TEXTURES):
|
|||
$(BUILD_DIR)/%.o: src/%.c
|
||||
kos-cc $(CFLAGS) -c $< -o $@
|
||||
|
||||
$(BUILD_DIR)/%.o: misc/dreamcast/%.S
|
||||
kos-cc -c $< -o $@
|
||||
|
||||
$(BUILD_DIR)/%.o: third_party/bearssl/src/%.c
|
||||
kos-cc $(CFLAGS) -c $< -o $@
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,161 @@
|
|||
! =========================================================
|
||||
! ========================= VERTEX LOADING ================
|
||||
! =========================================================
|
||||
.macro LoadColouredVertex
|
||||
! PREPARE NEXT VERTEX
|
||||
add #16, r3 ! r3 += VERTEX_STRIDE
|
||||
pref @r3 ! PREFETCH r3 (next vertex)
|
||||
add #64, r5 ! r5 += 2 * sizeof(VERTEX)
|
||||
! LOAD XYZ
|
||||
fmov @r4+, fr4 ! X = src->x
|
||||
fmov @r4+, fr5 ! Y = src->y
|
||||
fmov @r4+, fr6 ! Z = src->z
|
||||
fldi1 fr7 ! W = 1.0
|
||||
! TRANSFORM VERTEX
|
||||
ftrv xmtrx, fv4 ! TRANSFORM(XYZW)
|
||||
! LOAD ATTRIBUTES
|
||||
fmov @r4+,fr3 ! C = src->color
|
||||
.endm
|
||||
|
||||
.macro LoadTexturedVertex
|
||||
! PREPARE NEXT VERTEX
|
||||
add #24, r3 ! r3 += VERTEX_STRIDE
|
||||
pref @r3 ! PREFETCH r3 (next vertex)
|
||||
add #64, r5 ! r5 += 2 * sizeof(VERTEX)
|
||||
! LOAD XYZ
|
||||
fmov @r4+, fr4 ! X = src->x
|
||||
fmov @r4+, fr5 ! Y = src->y
|
||||
fmov @r4+, fr6 ! Z = src->z
|
||||
fldi1 fr7 ! W = 1.0
|
||||
! TRANSFORM VERTEX
|
||||
ftrv xmtrx, fv4 ! TRANSFORM(XYZW)
|
||||
! LOAD ATTRIBUTES
|
||||
fmov @r4+,fr3 ! C = src->color
|
||||
fmov @r4+,fr1 ! U = src->u
|
||||
fmov @r4+,fr2 ! V = src->v
|
||||
.endm
|
||||
|
||||
! =========================================================
|
||||
! ========================= VERTEX OUTPUT =================
|
||||
! =========================================================
|
||||
! To take advantage of SH4 dual instruction processing, interleave
|
||||
! the clipflag calculation and vertex output instructions
|
||||
.macro ProcessVertex1
|
||||
fmov.s fr7,@-r5 ! dst->w = W
|
||||
fmov.s fr3,@-r5 ! dst->c = C
|
||||
fneg fr7 ! W = -W
|
||||
fmov.s fr2,@-r5 ! dst->v = V
|
||||
fcmp/gt fr7,fr6 ! T = Z > W (i.e. Z > -W)
|
||||
fmov.s fr1,@-r5 ! dst->u = U
|
||||
movt r0 ! CLIPFLAGS = T
|
||||
fmov.s fr6,@-r5 ! dst->z = Z
|
||||
fmov.s fr5,@-r5 ! dst->y = Y
|
||||
fmov.s fr4,@-r5 ! dst->x = X
|
||||
mov.l r1,@-r5 ! dst->flags = CMD_VERT
|
||||
.endm
|
||||
|
||||
.macro ProcessVertex2
|
||||
fmov.s fr7,@-r5 ! dst->w = W
|
||||
fmov.s fr3,@-r5 ! dst->c = C
|
||||
fneg fr7 ! W = -W
|
||||
fmov.s fr2,@-r5 ! dst->v = V
|
||||
fcmp/gt fr7,fr6 ! T = Z > W (i.e. Z > -W)
|
||||
fmov.s fr1,@-r5 ! dst->u = U
|
||||
movt r2 ! tmp = T
|
||||
fmov.s fr6,@-r5 ! dst->z = Z
|
||||
add r2,r2 ! tmp = tmp + tmp
|
||||
fmov.s fr5,@-r5 ! dst->y = Y
|
||||
or r2,r0 ! CLIPFLAGS |= tmp (T << 1)
|
||||
fmov.s fr4,@-r5 ! dst->x = X
|
||||
mov.l r1,@-r5 ! dst->flags = CMD_VERT
|
||||
.endm
|
||||
|
||||
.macro ProcessVertex3
|
||||
fmov.s fr7,@-r5 ! dst->w = W
|
||||
fmov.s fr3,@-r5 ! dst->c = C
|
||||
fneg fr7 ! W = -W
|
||||
fmov.s fr2,@-r5 ! dst->v = V
|
||||
fcmp/gt fr7,fr6 ! T = Z > W (i.e. Z > -W)
|
||||
fmov.s fr1,@-r5 ! dst->u = U
|
||||
movt r2 ! tmp = T
|
||||
fmov.s fr6,@-r5 ! dst->z = Z
|
||||
fmov.s fr5,@-r5 ! dst->y = Y
|
||||
shll2 r2 ! tmp = tmp << 2
|
||||
fmov.s fr4,@-r5 ! dst->x = X
|
||||
or r2,r0 ! CLIPFLAGS |= tmp (T << 2)
|
||||
mov.l r1,@-r5 ! dst->flags = CMD_VERT
|
||||
.endm
|
||||
|
||||
.macro ProcessVertex4 eos_addr
|
||||
fmov.s fr7,@-r5 ! dst->w = W
|
||||
fmov.s fr3,@-r5 ! dst->c = C
|
||||
fneg fr7 ! W = -W
|
||||
fmov.s fr2,@-r5 ! dst->v = V
|
||||
fcmp/gt fr7,fr6 ! T = Z > W (i.e. Z > -W)
|
||||
fmov.s fr1,@-r5 ! dst->u = U
|
||||
movt r2 ! tmp = T
|
||||
fmov.s fr6,@-r5 ! dst->z = Z
|
||||
shll2 r2 ! tmp = tmp << 2
|
||||
fmov.s fr5,@-r5 ! dst->y = Y
|
||||
add r2,r2 ! tmp = (tmp << 2) + (tmp << 2)
|
||||
fmov.s fr4,@-r5 ! dst->x = X
|
||||
mov.l \eos_addr, r1 ! r1 = GPU EOS command
|
||||
or r2,r0 ! CLIPFLAGS |= tmp (T << 3)
|
||||
or r0,r1 ! r1 |= CLIPFLAGS
|
||||
mov.l r1,@-r5 ! dst->flags = GPU EOS | CLIPFLAGS
|
||||
.endm
|
||||
|
||||
|
||||
! =========================================================
|
||||
! ====================== VIEWPORT TRANSFORM ===============
|
||||
! =========================================================
|
||||
!r2 = return addr
|
||||
!r0 = temp
|
||||
!r5 = dst pointer
|
||||
|
||||
!fr0 = temp
|
||||
!fr4 = temp
|
||||
!fr5 = temp
|
||||
!fr5 = temp
|
||||
!fr8 = VIEWPORT_HWIDTH
|
||||
!fr9 = VIEWPORT_HHEIGHT
|
||||
!fr10 = VIEWPORT_X_PLUS_HWIDTH
|
||||
!fr11 = VIEWPORT_Y_PLUS_HHEIGHT
|
||||
|
||||
.macro ViewportTransformSetup viewport_addr
|
||||
mova \viewport_addr, r0
|
||||
fmov.s @r0+,fr8 ! fr8 = VIEWPORT_HWIDTH
|
||||
fmov.s @r0+,fr9 ! fr9 = VIEWPORT_HHEIGHT
|
||||
fmov.s @r0+,fr10 ! fr10 = VIEWPORT_X_PLUS_HWIDTH
|
||||
fmov.s @r0+,fr11 ! fr11 = VIEWPORT_Y_PLUS_HHEIGHT
|
||||
nop ! align to even instructions
|
||||
.endm
|
||||
|
||||
.macro ViewportTransformVertex
|
||||
! INVERSE W CALCULATION
|
||||
add #28, r5 ! r5 = &vertex->w
|
||||
fmov.s @r5,fr0 ! fr0 = vertex->w
|
||||
fmul fr0,fr0 ! fr0 = fr0 * fr0
|
||||
add #-24, r5 ! r5 = &vertex->x
|
||||
fsrra fr0 ! fr0 = 1 / sqrt(fr0) -> 1 / vertex->w
|
||||
|
||||
! TRANSFORM X
|
||||
fmov.s @r5,fr4 ! fr4 = vertex->x
|
||||
fmov fr10,fr5 ! fr5 = VIEWPORT_X_PLUS_HWIDTH
|
||||
fmul fr8,fr4 ! fr4 = VIEWPORT_HWIDTH * vertex->x
|
||||
fmac fr0,fr4,fr5 ! fr5 = fr0 * fr4 + fr5 -- (X * F * hwidth) + x_plus_hwidth
|
||||
fmov.s fr5,@r5 ! vertex->x = fr5
|
||||
add #4, r5 ! r5 = &vertex->y
|
||||
|
||||
! TRANSFORM Y
|
||||
fmov.s @r5,fr4 ! fr4 = vertex->y
|
||||
fmov fr11,fr5 ! fr5 = VIEWPORT_Y_PLUS_HHEIGHT
|
||||
fmul fr9,fr4 ! fr4 = VIEWPORT_HHEIGHT * vertex->y
|
||||
fmac fr0,fr4,fr5 ! fr5 = fr0 * fr4 + fr5 -- (Y * F * hheight) + y_plus_hheight
|
||||
fmov.s fr5,@r5 ! vertex->y = fr5
|
||||
add #4, r5 ! r5 = &vertex->z
|
||||
|
||||
! ASSIGN Z
|
||||
fmov.s fr0,@r5 ! vertex->z = fr0
|
||||
add #20, r5 ! r5 += 20 (points to start of next vertex)
|
||||
.endm
|
||||
|
|
@ -16,10 +16,10 @@ SH_CFLAGS+= -Os -I. -DPLAT_SATURN
|
|||
SH_LDFLAGS+=
|
||||
|
||||
IP_VERSION:= V1.000
|
||||
IP_RELEASE_DATE:= 20160101
|
||||
IP_RELEASE_DATE:= 20230101
|
||||
IP_AREAS:= JTUBKAEL
|
||||
IP_PERIPHERALS:= JAMKST
|
||||
IP_TITLE:= VDP1 drawing
|
||||
IP_TITLE:= ClassiCube
|
||||
IP_MASTER_STACK_ADDR:= 0x06004000
|
||||
IP_SLAVE_STACK_ADDR:= 0x06001E00
|
||||
IP_1ST_READ_ADDR:= 0x06004000
|
||||
|
|
|
|||
|
|
@ -78,14 +78,15 @@ export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
|
|||
export DEPSDIR := $(CURDIR)/$(BUILD)
|
||||
|
||||
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
|
||||
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
|
||||
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
|
||||
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) \
|
||||
$(foreach dir,$(SHADERS),$(notdir $(wildcard $(dir)/*.gsh)))
|
||||
|
||||
export LD := $(CC)
|
||||
export LD := $(CXX)
|
||||
|
||||
export OFILES_BIN := $(addsuffix .o,$(BINFILES))
|
||||
export OFILES_SRC := $(CFILES:.c=.o) $(SFILES:.s=.o)
|
||||
export OFILES_SRC := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
|
||||
export OFILES := $(OFILES_BIN) $(OFILES_SRC)
|
||||
export HFILES_BIN := $(addsuffix .h,$(subst .,_,$(BINFILES)))
|
||||
|
||||
|
|
|
|||
12
src/Bitmap.c
12
src/Bitmap.c
|
|
@ -163,8 +163,8 @@ static void Png_Reconstruct(cc_uint8 type, cc_uint8 bytesPerPixel, cc_uint8* lin
|
|||
|
||||
/* 7.2 Scanlines */
|
||||
#define PNG_Do_Grayscale(dstI, src, scale) rgb = (src) * scale; Bitmap_Set(dst[dstI], rgb, rgb, rgb, 255);
|
||||
#define PNG_Do_Grayscale_8() rgb = src[0]; Bitmap_Set(*dst, rgb, rgb, rgb, 255); dst--; src -= 2;
|
||||
#define PNG_Do_Grayscale_A__8() rgb = src[0]; Bitmap_Set(*dst, rgb, rgb, rgb, src[1]); dst--; src -= 1;
|
||||
#define PNG_Do_Grayscale_8() rgb = src[0]; Bitmap_Set(*dst, rgb, rgb, rgb, 255); dst--; src -= 1;
|
||||
#define PNG_Do_Grayscale_A__8() rgb = src[0]; Bitmap_Set(*dst, rgb, rgb, rgb, src[1]); dst--; src -= 2;
|
||||
#define PNG_Do_RGB__8() Bitmap_Set(*dst, src[0], src[1], src[2], 255); dst--; src -= 3;
|
||||
#define PNG_Do_RGB_A__8() Bitmap_Set(*dst, src[0], src[1], src[2], src[3]); dst++; src += 4;
|
||||
#define PNG_Do_Palette__8() *dst-- = palette[*src--];
|
||||
|
|
@ -489,11 +489,13 @@ cc_result Png_Decode(struct Bitmap* bmp, struct Stream* stream) {
|
|||
if (colorspace == PNG_COLOR_RGB_A) {
|
||||
/* Prior line is no longer needed and can be overwritten now */
|
||||
rowExpander(bmp->width, palette, &prior[1], Bitmap_GetRow(bmp, rowY - 1));
|
||||
/* Current line is also no longer needed and can be overwritten now */
|
||||
if (rowY == bmp->height - 1)
|
||||
rowExpander(bmp->width, palette, &scanline[1], Bitmap_GetRow(bmp, rowY));
|
||||
}
|
||||
}
|
||||
|
||||
/* Current line is also no longer needed and can be overwritten now */
|
||||
if (colorspace == PNG_COLOR_RGB_A && rowY == bmp->height - 1) {
|
||||
rowExpander(bmp->width, palette, &scanline[1], Bitmap_GetRow(bmp, rowY));
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if image fully decoded or not */
|
||||
|
|
|
|||
|
|
@ -360,9 +360,16 @@ static void OutputChunkPartsMeta(int x, int y, int z, struct ChunkInfo* info) {
|
|||
}
|
||||
|
||||
void Builder_MakeChunk(struct ChunkInfo* info) {
|
||||
#ifdef CC_BUILD_SATURN
|
||||
/* The Saturn build only has 16 kb stack, not large enough */
|
||||
static BlockID chunk[EXTCHUNK_SIZE_3];
|
||||
static cc_uint8 counts[CHUNK_SIZE_3 * FACE_COUNT];
|
||||
static int bitFlags[1];
|
||||
#else
|
||||
BlockID chunk[EXTCHUNK_SIZE_3];
|
||||
cc_uint8 counts[CHUNK_SIZE_3 * FACE_COUNT];
|
||||
int bitFlags[EXTCHUNK_SIZE_3];
|
||||
#endif
|
||||
|
||||
cc_bool allAir, allSolid, onBorder;
|
||||
int xMax, yMax, zMax, totalVerts;
|
||||
|
|
@ -761,6 +768,7 @@ static void NormalBuilder_SetActive(void) {
|
|||
/*########################################################################################################################*
|
||||
*-------------------------------------------------Advanced mesh builder---------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
#ifdef CC_BUILD_ADVLIGHTING
|
||||
static Vec3 adv_minBB, adv_maxBB;
|
||||
static int adv_initBitFlags, adv_baseOffset;
|
||||
static int* adv_bitFlags;
|
||||
|
|
@ -1259,6 +1267,9 @@ static void AdvBuilder_SetActive(void) {
|
|||
Builder_RenderBlock = Adv_RenderBlock;
|
||||
Builder_PrePrepareChunk = Adv_PrePrepareChunk;
|
||||
}
|
||||
#else
|
||||
static void AdvBuilder_SetActive(void) { NormalBuilder_SetActive(); }
|
||||
#endif
|
||||
|
||||
|
||||
/*########################################################################################################################*
|
||||
|
|
|
|||
|
|
@ -154,8 +154,10 @@ static Vec2 FirstPersonCamera_GetOrientation(struct LocalPlayer* p) {
|
|||
return v;
|
||||
}
|
||||
|
||||
static Vec3 FirstPersonCamera_GetPosition(struct LocalPlayer* p, float t) {
|
||||
static Vec3 FirstPersonCamera_GetPosition(float t) {
|
||||
struct LocalPlayer* p = Entities.CurPlayer;
|
||||
struct Entity* e = &p->Base;
|
||||
|
||||
Vec3 camPos = Entity_GetEyePosition(e);
|
||||
float yaw = e->Yaw * MATH_DEG2RAD;
|
||||
PerspectiveCamera_CalcViewBobbing(p, t, 1);
|
||||
|
|
@ -202,8 +204,10 @@ static float ThirdPersonCamera_GetZoom(struct LocalPlayer* p) {
|
|||
return dist;
|
||||
}
|
||||
|
||||
static Vec3 ThirdPersonCamera_GetPosition(struct LocalPlayer* p, float t) {
|
||||
static Vec3 ThirdPersonCamera_GetPosition(float t) {
|
||||
struct LocalPlayer* p = Entities.CurPlayer;
|
||||
struct Entity* e = &p->Base;
|
||||
|
||||
float dist = ThirdPersonCamera_GetZoom(p);
|
||||
Vec3 target, dir;
|
||||
Vec2 rot;
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ struct Camera {
|
|||
/* Returns the current orientation of the camera. */
|
||||
Vec2 (*GetOrientation)(struct LocalPlayer* p);
|
||||
/* Returns the current interpolated position of the camera. */
|
||||
Vec3 (*GetPosition)(struct LocalPlayer* p, float t);
|
||||
Vec3 (*GetPosition)(float t);
|
||||
|
||||
/* Called to update the camera's state. */
|
||||
/* Typically, this is used to adjust yaw/pitch based on accumulated mouse movement. */
|
||||
|
|
|
|||
|
|
@ -67,8 +67,8 @@ typedef void (*FP_Chat_AddOf)(const cc_string* text, int msgType);
|
|||
/* Shorthand for Chat_AddOf(String_FromReadonly(raw), MSG_TYPE_NORMAL) */
|
||||
void Chat_AddRaw(const char* raw);
|
||||
|
||||
void Chat_Add1(const char* format, const void* a1);
|
||||
void Chat_Add2(const char* format, const void* a1, const void* a2);
|
||||
void Chat_Add3(const char* format, const void* a1, const void* a2, const void* a3);
|
||||
void Chat_Add4(const char* format, const void* a1, const void* a2, const void* a3, const void* a4);
|
||||
CC_API void Chat_Add1(const char* format, const void* a1);
|
||||
CC_API void Chat_Add2(const char* format, const void* a1, const void* a2);
|
||||
CC_API void Chat_Add3(const char* format, const void* a1, const void* a2, const void* a3);
|
||||
CC_API void Chat_Add4(const char* format, const void* a1, const void* a2, const void* a3, const void* a4);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -561,7 +561,7 @@
|
|||
<ClCompile Include="Window_SDL3.c" />
|
||||
<ClCompile Include="Window_Switch.c" />
|
||||
<ClCompile Include="Window_Web.c" />
|
||||
<ClCompile Include="Window_WiiU.c" />
|
||||
<ClCompile Include="Window_WiiU.cpp" />
|
||||
<ClCompile Include="Window_Win.c" />
|
||||
<ClCompile Include="Window_X11.c" />
|
||||
<ClCompile Include="Window_Xbox.c" />
|
||||
|
|
|
|||
|
|
@ -728,9 +728,6 @@
|
|||
<ClCompile Include="Window_SDL3.c">
|
||||
<Filter>Source Files\Window</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Window_WiiU.c">
|
||||
<Filter>Source Files\Window</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Platform_NDS.c">
|
||||
<Filter>Source Files\Platform</Filter>
|
||||
</ClCompile>
|
||||
|
|
@ -752,6 +749,9 @@
|
|||
<ClCompile Include="Graphics_WiiU.c">
|
||||
<Filter>Source Files\Graphics</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Window_WiiU.cpp">
|
||||
<Filter>Source Files\Window</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="..\misc\windows\CCicon.rc">
|
||||
|
|
|
|||
|
|
@ -267,6 +267,23 @@ static struct ChatCommand ClearDeniedCommand = {
|
|||
}
|
||||
};
|
||||
|
||||
static void MotdCommand_Execute(const cc_string* args, int argsCount) {
|
||||
if (Server.IsSinglePlayer) {
|
||||
Chat_AddRaw("&eThis command can only be used in multiplayer.");
|
||||
return;
|
||||
}
|
||||
Chat_Add1("&eName: &f%s", &Server.Name);
|
||||
Chat_Add1("&eMOTD: &f%s", &Server.MOTD);
|
||||
}
|
||||
|
||||
static struct ChatCommand MotdCommand = {
|
||||
"Motd", MotdCommand_Execute,
|
||||
COMMAND_FLAG_UNSPLIT_ARGS,
|
||||
{
|
||||
"&a/client motd",
|
||||
"&eDisplays the server's name and MOTD."
|
||||
}
|
||||
};
|
||||
|
||||
/*########################################################################################################################*
|
||||
*-------------------------------------------------------DrawOpCommand-----------------------------------------------------*
|
||||
|
|
@ -709,6 +726,7 @@ static void OnInit(void) {
|
|||
Commands_Register(&ModelCommand);
|
||||
Commands_Register(&TeleportCommand);
|
||||
Commands_Register(&ClearDeniedCommand);
|
||||
Commands_Register(&MotdCommand);
|
||||
Commands_Register(&BlockEditCommand);
|
||||
Commands_Register(&CuboidCommand);
|
||||
Commands_Register(&ReplaceCommand);
|
||||
|
|
|
|||
|
|
@ -67,9 +67,8 @@ enum SKIN_TYPE { SKIN_64x32, SKIN_64x64, SKIN_64x64_SLIM, SKIN_INVALID = 0xF0 };
|
|||
#define Int32_MinValue ((cc_int32)-2147483647L - (cc_int32)1L)
|
||||
#define Int32_MaxValue ((cc_int32)2147483647L)
|
||||
|
||||
/* Skins were moved to use Amazon S3, so link directly to avoid a pointless redirect */
|
||||
#define SKINS_SERVER "http://cdn.classicube.net/skin"
|
||||
#define UPDATES_SERVER "http://cs.classicube.net/client"
|
||||
#define UPDATES_SERVER "http://cdn.classicube.net/client"
|
||||
#define SERVICES_SERVER "https://www.classicube.net/api"
|
||||
#define RESOURCE_SERVER "http://static.classicube.net"
|
||||
/* Webpage where users can register for a new account */
|
||||
|
|
|
|||
|
|
@ -124,6 +124,7 @@ typedef cc_uint8 cc_bool;
|
|||
#define CC_BUILD_PLUGINS
|
||||
#define CC_BUILD_ANIMATIONS
|
||||
#define CC_BUILD_FILESYSTEM
|
||||
#define CC_BUILD_ADVLIGHTING
|
||||
/*#define CC_BUILD_GL11*/
|
||||
|
||||
#ifndef CC_BUILD_MANUAL
|
||||
|
|
@ -297,7 +298,6 @@ typedef cc_uint8 cc_bool;
|
|||
#elif defined __vita__
|
||||
#define CC_BUILD_PSVITA
|
||||
#define CC_BUILD_CONSOLE
|
||||
#define CC_BUILD_LOWMEM
|
||||
#define CC_BUILD_OPENAL
|
||||
#define CC_BUILD_HTTPCLIENT
|
||||
#define CC_BUILD_BEARSSL
|
||||
|
|
@ -313,7 +313,6 @@ typedef cc_uint8 cc_bool;
|
|||
#elif defined PLAT_PS3
|
||||
#define CC_BUILD_PS3
|
||||
#define CC_BUILD_CONSOLE
|
||||
#define CC_BUILD_LOWMEM
|
||||
#define CC_BUILD_OPENAL
|
||||
#define CC_BUILD_HTTPCLIENT
|
||||
#define CC_BUILD_BEARSSL
|
||||
|
|
@ -347,6 +346,7 @@ typedef cc_uint8 cc_bool;
|
|||
#define CC_BUILD_TOUCH
|
||||
#undef CC_BUILD_RESOURCES
|
||||
#undef CC_BUILD_ANIMATIONS /* Very costly in FPU less system */
|
||||
#undef CC_BUILD_ADVLIGHTING
|
||||
#elif defined __WIIU__
|
||||
#define CC_BUILD_WIIU
|
||||
#define CC_BUILD_CONSOLE
|
||||
|
|
@ -354,6 +354,7 @@ typedef cc_uint8 cc_bool;
|
|||
#define CC_BUILD_OPENAL
|
||||
#define CC_BUILD_HTTPCLIENT
|
||||
#define CC_BUILD_BEARSSL
|
||||
#define CC_BUILD_SPLITSCREEN
|
||||
#define CC_BUILD_TOUCH
|
||||
#elif defined __SWITCH__
|
||||
#define CC_BUILD_SWITCH
|
||||
|
|
@ -375,6 +376,7 @@ typedef cc_uint8 cc_bool;
|
|||
#undef CC_BUILD_RESOURCES
|
||||
#undef CC_BUILD_NETWORKING
|
||||
#undef CC_BUILD_ANIMATIONS /* Very costly in FPU less system */
|
||||
#undef CC_BUILD_ADVLIGHTING
|
||||
#undef CC_BUILD_FILESYSTEM
|
||||
#elif defined OS2
|
||||
#define CC_BUILD_OS2
|
||||
|
|
@ -393,6 +395,7 @@ typedef cc_uint8 cc_bool;
|
|||
#undef CC_BUILD_RESOURCES
|
||||
#undef CC_BUILD_NETWORKING
|
||||
#undef CC_BUILD_ANIMATIONS /* Very costly in FPU less system */
|
||||
#undef CC_BUILD_ADVLIGHTING
|
||||
#undef CC_BUILD_FILESYSTEM
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -243,7 +243,7 @@ static cc_result Huffman_Build(struct HuffmanTable* table, const cc_uint8* bitLe
|
|||
* - set fast value to specify a 'value' value, and to skip 'len' bits
|
||||
*/
|
||||
if (len <= INFLATE_FAST_BITS) {
|
||||
cc_int16 packed = (cc_int16)((len << INFLATE_FAST_BITS) | value);
|
||||
cc_int16 packed = (cc_int16)((len << INFLATE_FAST_LEN_SHIFT) | value);
|
||||
int codeword = table->firstCodewords[len] + (bl_offsets[len] - table->firstOffsets[len]);
|
||||
codeword <<= (INFLATE_FAST_BITS - len);
|
||||
|
||||
|
|
@ -273,9 +273,9 @@ static int Huffman_Decode(struct InflateState* state, struct HuffmanTable* table
|
|||
if (state->NumBits >= INFLATE_FAST_BITS) {
|
||||
packed = table->fast[Inflate_PeekBits(state, INFLATE_FAST_BITS)];
|
||||
if (packed >= 0) {
|
||||
bits = packed >> INFLATE_FAST_BITS;
|
||||
bits = packed >> INFLATE_FAST_LEN_SHIFT;
|
||||
Inflate_ConsumeBits(state, bits);
|
||||
return packed & 0x1FF;
|
||||
return packed & INFLATE_FAST_VAL_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,11 @@ cc_result ZLibHeader_Read(struct Stream* s, struct ZLibHeader* header);
|
|||
#define INFLATE_MAX_DISTS 32
|
||||
#define INFLATE_MAX_LITS_DISTS (INFLATE_MAX_LITS + INFLATE_MAX_DISTS)
|
||||
#define INFLATE_MAX_BITS 16
|
||||
|
||||
#define INFLATE_FAST_BITS 9
|
||||
#define INFLATE_FAST_LEN_SHIFT 9
|
||||
#define INFLATE_FAST_VAL_MASK 0x1FF
|
||||
|
||||
#define INFLATE_WINDOW_SIZE 0x8000UL
|
||||
#define INFLATE_WINDOW_MASK 0x7FFFUL
|
||||
|
||||
|
|
|
|||
|
|
@ -539,6 +539,12 @@ static void DrawBitmappedTextCore(struct Bitmap* bmp, struct DrawTextArgs* args,
|
|||
static void DrawBitmappedText(struct Bitmap* bmp, struct DrawTextArgs* args, int x, int y) {
|
||||
int offset = Drawer2D_ShadowOffset(args->font->size);
|
||||
|
||||
if (!fontBitmap.scan0) {
|
||||
if (args->useShadow) FallbackFont_DrawText(args, bmp, x, y, true);
|
||||
FallbackFont_DrawText(args, bmp, x, y, false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (args->useShadow) {
|
||||
DrawBitmappedTextCore(bmp, args, x + offset, y + offset, true);
|
||||
}
|
||||
|
|
@ -550,6 +556,8 @@ static int MeasureBitmappedWidth(const struct DrawTextArgs* args) {
|
|||
int xPadding, width;
|
||||
cc_string text;
|
||||
|
||||
if (!fontBitmap.scan0) return FallbackFont_TextWidth(args);
|
||||
|
||||
/* adjust coords to make drawn text match GDI fonts */
|
||||
xPadding = Drawer2D_XPadding(point);
|
||||
width = 0;
|
||||
|
|
|
|||
12
src/Entity.c
12
src/Entity.c
|
|
@ -622,6 +622,11 @@ void LocalPlayerInput_Add(struct LocalPlayerInput* source) {
|
|||
LinkedList_Append(source, sources_head, sources_tail);
|
||||
}
|
||||
|
||||
void LocalPlayerInput_Remove(struct LocalPlayerInput* source) {
|
||||
struct LocalPlayerInput* cur;
|
||||
LinkedList_Remove(source, cur, sources_head, sources_tail);
|
||||
}
|
||||
|
||||
float LocalPlayer_JumpHeight(struct LocalPlayer* p) {
|
||||
return (float)PhysicsComp_CalcMaxHeight(p->Physics.JumpVel);
|
||||
}
|
||||
|
|
@ -887,7 +892,9 @@ cc_bool LocalPlayer_HandleSetSpawn(struct LocalPlayer* p) {
|
|||
|
||||
/* Spawn is normally centered to match vanilla Minecraft classic */
|
||||
if (!p->Hacks.CanNoclip) {
|
||||
p->Spawn = p->Base.Position;
|
||||
/* Don't want to use Position because it is interpolated between prev and next. */
|
||||
/* This means it can be halfway between stepping up a stair and clip through the floor. */
|
||||
p->Spawn = p->Base.prev.pos;
|
||||
} else {
|
||||
p->Spawn.x = Math_Floor(p->Base.Position.x) + 0.5f;
|
||||
p->Spawn.y = p->Base.Position.y;
|
||||
|
|
@ -968,7 +975,7 @@ void LocalPlayers_MoveToSpawn(struct LocationUpdate* update) {
|
|||
}
|
||||
|
||||
/* TODO: This needs to be before new map... */
|
||||
Camera.CurrentPos = Camera.Active->GetPosition(Entities.CurPlayer, 0.0f);
|
||||
Camera.CurrentPos = Camera.Active->GetPosition(0.0f);
|
||||
}
|
||||
|
||||
void LocalPlayer_CalcDefaultSpawn(struct LocalPlayer* p, struct LocationUpdate* update) {
|
||||
|
|
@ -1062,6 +1069,7 @@ static void Entities_Free(void) {
|
|||
{
|
||||
Entities_Remove((EntityID)i);
|
||||
}
|
||||
sources_head = NULL;
|
||||
}
|
||||
|
||||
struct IGameComponent Entities_Component = {
|
||||
|
|
|
|||
|
|
@ -231,6 +231,7 @@ struct LocalPlayerInput {
|
|||
struct LocalPlayerInput* next;
|
||||
};
|
||||
void LocalPlayerInput_Add(struct LocalPlayerInput* source);
|
||||
void LocalPlayerInput_Remove(struct LocalPlayerInput* source);
|
||||
|
||||
/* Represents the user/player's own entity. */
|
||||
struct LocalPlayer {
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ static cc_bool shadows_boundTex;
|
|||
static GfxResourceID shadows_VB;
|
||||
static GfxResourceID shadows_tex;
|
||||
static float shadow_radius, shadow_uvScale;
|
||||
struct ShadowData { float y; BlockID Block; cc_uint8 A; };
|
||||
struct ShadowData { float y; BlockID block; cc_uint8 alpha; };
|
||||
|
||||
/* Circle shadows extend at most 4 blocks vertically */
|
||||
#define SHADOW_MAX_RANGE 4
|
||||
|
|
@ -54,7 +54,7 @@ static void EntityShadow_DrawCoords(struct VertexTextured** vertices, struct Ent
|
|||
z2 = min(z2, cen.z + shadow_radius); v2 = v2 <= 1.0f ? v2 : 1.0f;
|
||||
|
||||
v = *vertices;
|
||||
col = PackedCol_Make(255, 255, 255, data->A);
|
||||
col = PackedCol_Make(255, 255, 255, data->alpha);
|
||||
|
||||
v->x = x1; v->y = data->y; v->z = z1; v->Col = col; v->U = u1; v->V = v1; v++;
|
||||
v->x = x2; v->y = data->y; v->z = z1; v->Col = col; v->U = u2; v->V = v1; v++;
|
||||
|
|
@ -83,13 +83,13 @@ static void EntityShadow_DrawCircle(struct VertexTextured** vertices, struct Ent
|
|||
Vec3 min, max, nMin, nMax;
|
||||
int i;
|
||||
x = (float)Math_Floor(x); z = (float)Math_Floor(z);
|
||||
min = Blocks.MinBB[data[0].Block]; max = Blocks.MaxBB[data[0].Block];
|
||||
min = Blocks.MinBB[data[0].block]; max = Blocks.MaxBB[data[0].block];
|
||||
|
||||
EntityShadow_DrawCoords(vertices, e, &data[0], x + min.x, z + min.z, x + max.x, z + max.z);
|
||||
for (i = 1; i < 4; i++)
|
||||
{
|
||||
if (data[i].Block == BLOCK_AIR) return;
|
||||
nMin = Blocks.MinBB[data[i].Block]; nMax = Blocks.MaxBB[data[i].Block];
|
||||
if (data[i].block == BLOCK_AIR) return;
|
||||
nMin = Blocks.MinBB[data[i].block]; nMax = Blocks.MaxBB[data[i].block];
|
||||
|
||||
EntityShadow_DrawCoords(vertices, e, &data[i], x + min.x, z + nMin.z, x + max.x, z + min.z);
|
||||
EntityShadow_DrawCoords(vertices, e, &data[i], x + min.x, z + max.z, x + max.x, z + nMax.z);
|
||||
|
|
@ -103,11 +103,12 @@ static void EntityShadow_DrawCircle(struct VertexTextured** vertices, struct Ent
|
|||
static void EntityShadow_CalcAlpha(float playerY, struct ShadowData* data) {
|
||||
float height = playerY - data->y;
|
||||
if (height <= 6.0f) {
|
||||
data->A = (cc_uint8)(160 - 160 * height / 6.0f);
|
||||
data->y += 1.0f / 64.0f; return;
|
||||
data->alpha = (cc_uint8)(160 - 160 * height / 6.0f);
|
||||
data->y += 1.0f / 64.0f;
|
||||
return;
|
||||
}
|
||||
|
||||
data->A = 0;
|
||||
data->alpha = 0;
|
||||
if (height <= 16.0f) data->y += 1.0f / 64.0f;
|
||||
else if (height <= 32.0f) data->y += 1.0f / 16.0f;
|
||||
else if (height <= 96.0f) data->y += 1.0f / 8.0f;
|
||||
|
|
@ -144,7 +145,7 @@ static cc_bool EntityShadow_GetBlocks(struct Entity* e, int x, int y, int z, str
|
|||
topY = y + Blocks.MaxBB[block].y;
|
||||
if (topY >= posY + 0.01f) continue;
|
||||
|
||||
cur->Block = block; cur->y = topY;
|
||||
cur->block = block; cur->y = topY;
|
||||
EntityShadow_CalcAlpha(posY, cur);
|
||||
i++; cur++;
|
||||
|
||||
|
|
@ -154,7 +155,7 @@ static cc_bool EntityShadow_GetBlocks(struct Entity* e, int x, int y, int z, str
|
|||
}
|
||||
|
||||
if (i < 4) {
|
||||
cur->Block = Env.EdgeBlock; cur->y = 0.0f;
|
||||
cur->block = Env.EdgeBlock; cur->y = 0.0f;
|
||||
EntityShadow_CalcAlpha(posY, cur);
|
||||
i++; cur++;
|
||||
}
|
||||
|
|
@ -188,16 +189,16 @@ static void EntityShadow_Draw(struct Entity* e) {
|
|||
x1 = Math_Floor(pos.x - shadow_radius); z1 = Math_Floor(pos.z - shadow_radius);
|
||||
x2 = Math_Floor(pos.x + shadow_radius); z2 = Math_Floor(pos.z + shadow_radius);
|
||||
|
||||
if (EntityShadow_GetBlocks(e, x1, y, z1, data) && data[0].A > 0) {
|
||||
if (EntityShadow_GetBlocks(e, x1, y, z1, data) && data[0].alpha > 0) {
|
||||
EntityShadow_DrawCircle(&ptr, e, data, (float)x1, (float)z1);
|
||||
}
|
||||
if (x1 != x2 && EntityShadow_GetBlocks(e, x2, y, z1, data) && data[0].A > 0) {
|
||||
if (x1 != x2 && EntityShadow_GetBlocks(e, x2, y, z1, data) && data[0].alpha > 0) {
|
||||
EntityShadow_DrawCircle(&ptr, e, data, (float)x2, (float)z1);
|
||||
}
|
||||
if (z1 != z2 && EntityShadow_GetBlocks(e, x1, y, z2, data) && data[0].A > 0) {
|
||||
if (z1 != z2 && EntityShadow_GetBlocks(e, x1, y, z2, data) && data[0].alpha > 0) {
|
||||
EntityShadow_DrawCircle(&ptr, e, data, (float)x1, (float)z2);
|
||||
}
|
||||
if (x1 != x2 && z1 != z2 && EntityShadow_GetBlocks(e, x2, y, z2, data) && data[0].A > 0) {
|
||||
if (x1 != x2 && z1 != z2 && EntityShadow_GetBlocks(e, x2, y, z2, data) && data[0].alpha > 0) {
|
||||
EntityShadow_DrawCircle(&ptr, e, data, (float)x2, (float)z2);
|
||||
}
|
||||
}
|
||||
|
|
@ -262,6 +263,7 @@ void EntityShadows_Render(void) {
|
|||
if (Entities.ShadowsMode == SHADOW_MODE_CIRCLE_ALL) {
|
||||
for (i = 0; i < ENTITIES_MAX_COUNT; i++)
|
||||
{
|
||||
e = Entities.List[i];
|
||||
if (!e || !e->ShouldRender || e == &Entities.CurPlayer->Base) continue;
|
||||
EntityShadow_Draw(e);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -132,7 +132,8 @@ enum CC_ERRORS {
|
|||
HTTP_ERR_RELATIVE = 0xCCDED069UL, /* Unsupported relative URL format */
|
||||
HTTP_ERR_INVALID_BODY= 0xCCDED06AUL, /* HTTP message doesn't have Content-Length or use Chunked transfer encoding */
|
||||
HTTP_ERR_CHUNK_SIZE = 0xCCDED06BUL, /* HTTP message chunk has negative size/length */
|
||||
HTTP_ERR_TRUNCATED = 0xCCDED06CUL, /* HTTP respone header was truncated due to being too long */
|
||||
HTTP_ERR_TRUNCATED = 0xCCDED06CUL, /* HTTP response header was truncated due to being too long */
|
||||
HTTP_ERR_NO_RESPONSE = 0xCCDED06DUL, /* First attempt to read response returned 0 bytes */
|
||||
|
||||
SSL_ERR_CONTEXT_DEAD = 0xCCDED070UL, /* Server shutdown the SSL context and it must be recreated */
|
||||
PNG_ERR_16BITSAMPLES = 0xCCDED071UL, /* Image uses 16 bit samples, which is unimplemented */
|
||||
|
|
|
|||
184
src/ExtMath.c
184
src/ExtMath.c
|
|
@ -4,6 +4,8 @@
|
|||
/* For abs(x) function */
|
||||
#include <stdlib.h>
|
||||
|
||||
#define PI 3.141592653589793238462643383279502884197169399
|
||||
|
||||
/* Sega saturn is missing these intrinsics */
|
||||
#ifdef CC_BUILD_SATURN
|
||||
#include <stdint.h>
|
||||
|
|
@ -80,8 +82,8 @@ float Math_ClampAngle(float degrees) {
|
|||
}
|
||||
|
||||
float Math_LerpAngle(float leftAngle, float rightAngle, float t) {
|
||||
/* We have to cheat a bit for angles here */
|
||||
/* Consider 350* --> 0*, we only want to travel 10* */
|
||||
/* Need to potentially adjust a bit when interpolating some angles */
|
||||
/* Consider 350* --> 0*, we only want to interpolate across the 10* */
|
||||
/* But without adjusting for this case, we would interpolate back the whole 350* degrees */
|
||||
cc_bool invertLeft = leftAngle > 270.0f && rightAngle < 90.0f;
|
||||
cc_bool invertRight = rightAngle > 270.0f && leftAngle < 90.0f;
|
||||
|
|
@ -147,8 +149,6 @@ float Random_Float(RNGState* seed) {
|
|||
/*########################################################################################################################*
|
||||
*--------------------------------------------------Transcendental functions-----------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
static const double SQRT2 = 1.4142135623730950488016887242096980785696718753769;
|
||||
|
||||
#ifdef CC_BUILD_DREAMCAST
|
||||
#include <math.h>
|
||||
|
||||
|
|
@ -156,12 +156,10 @@ static const double SQRT2 = 1.4142135623730950488016887242096980785696718753769;
|
|||
/* TODO: Properly investigate this issue */
|
||||
/* double make_dreamcast_build_compile(void) { fabs(4); } */
|
||||
|
||||
double Math_Sin(double x) { return sin(x); }
|
||||
double Math_Cos(double x) { return cos(x); }
|
||||
double Math_Sin(double x) { return sinf(x); }
|
||||
double Math_Cos(double x) { return cosf(x); }
|
||||
double Math_Exp2(double x) { return exp2(x); }
|
||||
double Math_Log2(double x) { return log2(x); }
|
||||
|
||||
double Math_Atan2(double x, double y) { return atan2(y, x); }
|
||||
#else
|
||||
/***** Caleb's Math functions *****/
|
||||
|
||||
|
|
@ -187,7 +185,7 @@ double Math_Atan2(double x, double y) { return atan2(y, x); }
|
|||
/* from the mathematical functions anyways */
|
||||
|
||||
/* Global constants */
|
||||
#define PI 3.141592653589793238462643383279502884197169399
|
||||
static const double SQRT2 = 1.4142135623730950488016887242096980785696718753769;
|
||||
#define DIV_2_PI (1.0 / (2.0 * PI))
|
||||
|
||||
static const cc_uint64 _DBL_NAN = 0x7FF8000000000000ULL;
|
||||
|
|
@ -296,149 +294,6 @@ double Math_Cos(double x) {
|
|||
return SinStage3(x_div_pi_shifted - Floord(x_div_pi_shifted));
|
||||
}
|
||||
|
||||
/**************
|
||||
* Math_Atan2 *
|
||||
**************/
|
||||
|
||||
/* Calculates the 5th degree polynomial ARCTN 4903 listed in the book's
|
||||
* appendix.
|
||||
*
|
||||
* Associated math function: arctan(x)
|
||||
* Allowed input range: [0, tan(pi/32)]
|
||||
* Precision: 16.52
|
||||
*/
|
||||
static double AtanStage1(double x) {
|
||||
const double A[] = {
|
||||
.99999999999969557,
|
||||
-.3333333333318,
|
||||
.1999999997276,
|
||||
-.14285702288,
|
||||
.11108719478,
|
||||
-.8870580341e-1,
|
||||
};
|
||||
|
||||
double P = A[5];
|
||||
double x_2 = x * x;
|
||||
int i;
|
||||
|
||||
for (i = 4; i >= 0; i--) {
|
||||
P *= x_2;
|
||||
P += A[i];
|
||||
}
|
||||
P *= x;
|
||||
return P;
|
||||
}
|
||||
|
||||
/* This function finds out in which partition the non-negative real number x
|
||||
* resides out of 8 partitions, which are precomputed. It then uses the
|
||||
* following law:
|
||||
*
|
||||
* t = x_i^{-1} - (x_i^{-2} + 1)/(x_i^{-1} + x)
|
||||
* arctan(x) = arctan(x_i) + arctan(t)
|
||||
*
|
||||
* where x_i = tan((2i - 2)*pi/32) and i is the partition number. The value of t
|
||||
* is guaranteed to be between [-tan(pi/32), tan(pi/32)].
|
||||
*
|
||||
* Associated math function: arctan(x)
|
||||
* Allowed input range: [0, infinity]
|
||||
*/
|
||||
static double AtanStage2(double x) {
|
||||
const double X_i[] = {
|
||||
0.0,
|
||||
0.0984914033571642477671304050090839155018329620361328125,
|
||||
0.3033466836073424044428747947677038609981536865234375,
|
||||
0.53451113595079158269385288804187439382076263427734375,
|
||||
0.82067879082866024287312711749109439551830291748046875,
|
||||
1.218503525587976366040265929768793284893035888671875,
|
||||
1.8708684117893887854933154812897555530071258544921875,
|
||||
3.29655820893832096629694206058047711849212646484375,
|
||||
(float)(1e+300 * 1e+300) /* Infinity */
|
||||
};
|
||||
|
||||
const double div_x_i[] = {
|
||||
0,
|
||||
0,
|
||||
5.02733949212584807497705696732737123966217041015625,
|
||||
2.41421356237309492343001693370752036571502685546875,
|
||||
1.496605762665489169904731170390732586383819580078125,
|
||||
1.0000000000000002220446049250313080847263336181640625,
|
||||
0.66817863791929898997778991542872972786426544189453125,
|
||||
0.414213562373095089963470627481001429259777069091796875,
|
||||
0.1989123673796580893391450217677629552781581878662109375,
|
||||
};
|
||||
|
||||
const double div_x_i_2_plus_1[] = {
|
||||
0,
|
||||
0,
|
||||
26.2741423690881816810360760428011417388916015625,
|
||||
6.8284271247461898468600338674150407314300537109375,
|
||||
3.23982880884355051165357508580200374126434326171875,
|
||||
2.000000000000000444089209850062616169452667236328125,
|
||||
1.446462692171689656817079594475217163562774658203125,
|
||||
1.1715728752538099310953612075536511838436126708984375,
|
||||
1.0395661298965801488947136022034101188182830810546875,
|
||||
};
|
||||
|
||||
int L = 0;
|
||||
int R = 8;
|
||||
double t;
|
||||
|
||||
while (R - L > 1) {
|
||||
int m = (L + R) / 2;
|
||||
if (X_i[m] <= x)
|
||||
L = m;
|
||||
else if (X_i[m] > x)
|
||||
R = m;
|
||||
}
|
||||
|
||||
if (R <= 1)
|
||||
return AtanStage1(x);
|
||||
|
||||
t = div_x_i[R] - div_x_i_2_plus_1[R] / (div_x_i[R] + x);
|
||||
if (t >= 0)
|
||||
return (2 * R - 2) * PI / 32.0 + AtanStage1(t);
|
||||
|
||||
return (2 * R - 2) * PI / 32.0 - AtanStage1(-t);
|
||||
}
|
||||
|
||||
/* Uses the property arctan(x) = -arctan(-x).
|
||||
*
|
||||
* Associated math function: arctan(x)
|
||||
* Allowed input range: anything
|
||||
*/
|
||||
static double Atan(double x) {
|
||||
if (x == DBL_NAN)
|
||||
return DBL_NAN;
|
||||
if (x == NEG_INF)
|
||||
return -PI / 2.0;
|
||||
if (x == POS_INF)
|
||||
return PI / 2.0;
|
||||
if (x >= 0)
|
||||
return AtanStage2(x);
|
||||
return -AtanStage2(-x);
|
||||
}
|
||||
|
||||
/* Implements the function atan2 using Atan.
|
||||
*
|
||||
* Associated math function: atan2(y, x)
|
||||
* Allowed input range: anything
|
||||
*/
|
||||
double Math_Atan2(double x, double y) {
|
||||
if (x > 0)
|
||||
return Atan(y / x);
|
||||
if (x < 0) {
|
||||
if (y >= 0)
|
||||
return Atan(y / x) + PI;
|
||||
return Atan(y / x) - PI;
|
||||
}
|
||||
|
||||
/* x = 0 case */
|
||||
if (y > 0) return PI / 2.0;
|
||||
if (y < 0) return -PI / 2.0;
|
||||
|
||||
return DBL_NAN;
|
||||
}
|
||||
|
||||
/************
|
||||
* Math_Exp *
|
||||
************/
|
||||
|
|
@ -576,7 +431,7 @@ double Math_Log2(double x) {
|
|||
if (x == POS_INF)
|
||||
return POS_INF;
|
||||
|
||||
if (x == NEG_INF || x == DBL_NAN || x <= 0.0)
|
||||
if (x == DBL_NAN || x <= 0.0)
|
||||
return DBL_NAN;
|
||||
|
||||
doi.d = x;
|
||||
|
|
@ -588,5 +443,26 @@ double Math_Log2(double x) {
|
|||
|
||||
return exponent + Log2Stage1(doi.d);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// Approximation of atan2f using the Remez algorithm
|
||||
// https://math.stackexchange.com/a/1105038
|
||||
float Math_Atan2f(float x, float y) {
|
||||
if (x == 0) {
|
||||
if (y > 0) return PI / 2.0f;
|
||||
if (y < 0) return -PI / 2.0f;
|
||||
return 0; /* Should probably be NaN */
|
||||
}
|
||||
|
||||
float ax = Math_AbsF(x);
|
||||
float ay = Math_AbsF(y);
|
||||
|
||||
float a = (ax < ay) ? (ax / ay) : (ay / ax);
|
||||
float s = a * a;
|
||||
float r = ((-0.0464964749f * s + 0.15931422f) * s - 0.327622764f) * s * a + a;
|
||||
|
||||
if (ay > ax) r = 1.57079637f - r;
|
||||
if (x < 0) r = 3.14159274f - r;
|
||||
if (y < 0) r = -r;
|
||||
return r;
|
||||
}
|
||||
|
|
@ -31,7 +31,9 @@ CC_API double Math_Sin(double x);
|
|||
CC_API double Math_Cos(double x);
|
||||
float Math_SinF(float x);
|
||||
float Math_CosF(float x);
|
||||
double Math_Atan2(double x, double y);
|
||||
/* Computes atan2(y, x), intended primarily for angle calculation*/
|
||||
/* Note that accuracy is only up to around 4 decimal places */
|
||||
float Math_Atan2f(float x, float y);
|
||||
|
||||
/* Computes log2(x). Can also be used to approximate log_y(x). */
|
||||
/* e.g. for log3(x), use: log2(x)/log2(3) */
|
||||
|
|
|
|||
|
|
@ -640,7 +640,7 @@ static void DrawSplitscreen(float delta, float t, int i, int x, int y, int w, in
|
|||
|
||||
Entities.CurPlayer = &LocalPlayer_Instances[i];
|
||||
LocalPlayer_SetInterpPosition(Entities.CurPlayer, t);
|
||||
Camera.CurrentPos = Camera.Active->GetPosition(Entities.CurPlayer, t);
|
||||
Camera.CurrentPos = Camera.Active->GetPosition(t);
|
||||
|
||||
Game_DrawFrame(delta, t);
|
||||
}
|
||||
|
|
@ -684,7 +684,7 @@ static CC_INLINE void Game_RenderFrame(double delta) {
|
|||
t = (float)(entTask.accumulator / entTask.interval);
|
||||
LocalPlayer_SetInterpPosition(Entities.CurPlayer, t);
|
||||
|
||||
Camera.CurrentPos = Camera.Active->GetPosition(Entities.CurPlayer, t);
|
||||
Camera.CurrentPos = Camera.Active->GetPosition(t);
|
||||
/* NOTE: EnvRenderer_UpdateFog also also sets clear color */
|
||||
EnvRenderer_UpdateFog();
|
||||
AudioBackend_Tick();
|
||||
|
|
|
|||
|
|
@ -439,7 +439,7 @@ void Gfx_SetFaceCulling(cc_bool enabled) {
|
|||
|
||||
void Gfx_SetAlphaArgBlend(cc_bool enabled) { }
|
||||
|
||||
void Gfx_SetAlphaBlending(cc_bool enabled) {
|
||||
static void SetAlphaBlend(cc_bool enabled) {
|
||||
if (enabled) {
|
||||
C3D_AlphaBlend(GPU_BLEND_ADD, GPU_BLEND_ADD, GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA);
|
||||
} else {
|
||||
|
|
@ -447,7 +447,7 @@ void Gfx_SetAlphaBlending(cc_bool enabled) {
|
|||
}
|
||||
}
|
||||
|
||||
void Gfx_SetAlphaTest(cc_bool enabled) {
|
||||
static void SetAlphaTest(cc_bool enabled) {
|
||||
C3D_AlphaTest(enabled, GPU_GREATER, 0x7F);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -691,7 +691,7 @@ void Gfx_SetFaceCulling(cc_bool enabled) {
|
|||
static ID3D11SamplerState* ps_samplers[2];
|
||||
static ID3D11PixelShader* ps_shaders[12];
|
||||
static ID3D11Buffer* ps_cBuffer;
|
||||
static cc_bool ps_alphaTesting, ps_mipmaps;
|
||||
static cc_bool ps_mipmaps;
|
||||
static float ps_fogEnd, ps_fogDensity;
|
||||
static PackedCol ps_fogColor;
|
||||
static int ps_fogMode;
|
||||
|
|
@ -725,7 +725,7 @@ static void PS_CreateShaders(void) {
|
|||
|
||||
static int PS_CalcShaderIndex(void) {
|
||||
int idx = gfx_format == VERTEX_FORMAT_COLOURED ? 0 : 1;
|
||||
if (ps_alphaTesting) idx += 2;
|
||||
if (gfx_alphaTest) idx += 2;
|
||||
|
||||
if (gfx_fogEnabled) {
|
||||
// uncomment when it works
|
||||
|
|
@ -822,8 +822,7 @@ static void PS_Free(void) {
|
|||
PS_FreeConstants();
|
||||
}
|
||||
|
||||
void Gfx_SetAlphaTest(cc_bool enabled) {
|
||||
ps_alphaTesting = enabled;
|
||||
static void SetAlphaTest(cc_bool enabled) {
|
||||
PS_UpdateShader();
|
||||
}
|
||||
// unnecessary? check if any performance is gained, probably irrelevant
|
||||
|
|
@ -887,10 +886,10 @@ void Gfx_DisableMipmaps(void) {
|
|||
static ID3D11RenderTargetView* backbuffer;
|
||||
static ID3D11Texture2D* depthbuffer;
|
||||
static ID3D11DepthStencilView* depthbufferView;
|
||||
static ID3D11BlendState* om_blendStates[4];
|
||||
static ID3D11BlendState* om_blendStates[16 * 2];
|
||||
static ID3D11DepthStencilState* om_depthStates[4];
|
||||
static float gfx_clearColor[4];
|
||||
static cc_bool gfx_alphaBlending, gfx_colorEnabled = true;
|
||||
static cc_bool gfx_channels[4] = { true, true, true, true };
|
||||
static cc_bool gfx_depthTest, gfx_depthWrite;
|
||||
|
||||
static void OM_Clear(GfxBuffers buffers) {
|
||||
|
|
@ -972,8 +971,14 @@ static void OM_CreateBlendStates(void) {
|
|||
|
||||
for (int i = 0; i < Array_Elems(om_blendStates); i++)
|
||||
{
|
||||
desc.RenderTarget[0].RenderTargetWriteMask = (i & 1) ? D3D11_COLOR_WRITE_ENABLE_ALL : 0;
|
||||
desc.RenderTarget[0].BlendEnable = (i & 2) != 0;
|
||||
int mask = 0;
|
||||
if (i & 0x01) mask |= D3D11_COLOR_WRITE_ENABLE_RED;
|
||||
if (i & 0x02) mask |= D3D11_COLOR_WRITE_ENABLE_GREEN;
|
||||
if (i & 0x04) mask |= D3D11_COLOR_WRITE_ENABLE_BLUE;
|
||||
if (i & 0x08) mask |= D3D11_COLOR_WRITE_ENABLE_ALPHA;
|
||||
|
||||
desc.RenderTarget[0].RenderTargetWriteMask = mask;
|
||||
desc.RenderTarget[0].BlendEnable = (i & 0x10) != 0;
|
||||
|
||||
hr = ID3D11Device_CreateBlendState(device, &desc, &om_blendStates[i]);
|
||||
if (hr) Logger_Abort2(hr, "Failed to create blend state");
|
||||
|
|
@ -981,7 +986,8 @@ static void OM_CreateBlendStates(void) {
|
|||
}
|
||||
|
||||
static void OM_UpdateBlendState(void) {
|
||||
ID3D11BlendState* blendState = om_blendStates[gfx_colorEnabled | (gfx_alphaBlending << 1)];
|
||||
int idx = (gfx_channels[0]) | (gfx_channels[1] << 1) | (gfx_channels[2] << 2) | (gfx_channels[3] << 3) | (gfx_alphaBlend << 4);
|
||||
ID3D11BlendState* blendState = om_blendStates[idx];
|
||||
ID3D11DeviceContext_OMSetBlendState(context, blendState, NULL, 0xffffffff);
|
||||
}
|
||||
|
||||
|
|
@ -1030,15 +1036,16 @@ void Gfx_SetDepthWrite(cc_bool enabled) {
|
|||
OM_UpdateDepthState();
|
||||
}
|
||||
|
||||
void Gfx_SetAlphaBlending(cc_bool enabled) {
|
||||
gfx_alphaBlending = enabled;
|
||||
static void SetAlphaBlend(cc_bool enabled) {
|
||||
OM_UpdateBlendState();
|
||||
}
|
||||
|
||||
static void SetColorWrite(cc_bool r, cc_bool g, cc_bool b, cc_bool a) {
|
||||
gfx_colorEnabled = r;
|
||||
gfx_channels[0] = r;
|
||||
gfx_channels[1] = g;
|
||||
gfx_channels[2] = b;
|
||||
gfx_channels[3] = a;
|
||||
OM_UpdateBlendState();
|
||||
// TODO all channels
|
||||
}
|
||||
|
||||
void Gfx_DepthOnlyRendering(cc_bool depthOnly) {
|
||||
|
|
|
|||
|
|
@ -394,7 +394,7 @@ void Gfx_DisableMipmaps(void) {
|
|||
*-----------------------------------------------------State management----------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
static D3DFOGMODE gfx_fogMode = D3DFOG_NONE;
|
||||
static cc_bool gfx_alphaTesting, gfx_alphaBlending;
|
||||
static cc_bool gfx_alphaBlending;
|
||||
static cc_bool gfx_depthTesting, gfx_depthWriting;
|
||||
static PackedCol gfx_clearColor, gfx_fogColor;
|
||||
static float gfx_fogEnd = -1.0f, gfx_fogDensity = -1.0f;
|
||||
|
|
@ -455,18 +455,12 @@ void Gfx_SetFogMode(FogFunc func) {
|
|||
IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, mode);
|
||||
}
|
||||
|
||||
void Gfx_SetAlphaTest(cc_bool enabled) {
|
||||
if (gfx_alphaTesting == enabled) return;
|
||||
gfx_alphaTesting = enabled;
|
||||
|
||||
static void SetAlphaTest(cc_bool enabled) {
|
||||
if (Gfx.LostContext) return;
|
||||
IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, enabled);
|
||||
}
|
||||
|
||||
void Gfx_SetAlphaBlending(cc_bool enabled) {
|
||||
if (gfx_alphaBlending == enabled) return;
|
||||
gfx_alphaBlending = enabled;
|
||||
|
||||
static void SetAlphaBlend(cc_bool enabled) {
|
||||
if (Gfx.LostContext) return;
|
||||
IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, enabled);
|
||||
}
|
||||
|
|
@ -529,7 +523,7 @@ void Gfx_DepthOnlyRendering(cc_bool depthOnly) {
|
|||
|
||||
static void D3D9_RestoreRenderStates(void) {
|
||||
union IntAndFloat raw;
|
||||
IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, gfx_alphaTesting);
|
||||
IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, gfx_alphaTest);
|
||||
IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, gfx_alphaBlending);
|
||||
|
||||
IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, gfx_fogEnabled);
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
#include "Logger.h"
|
||||
#include "Window.h"
|
||||
#include "../third_party/gldc/gldc.h"
|
||||
#include "../third_party/gldc/src/draw.c"
|
||||
#include <malloc.h>
|
||||
#include <kos.h>
|
||||
#include <dc/matrix.h>
|
||||
|
|
@ -30,6 +31,7 @@ static void InitGLState(void) {
|
|||
|
||||
void Gfx_Create(void) {
|
||||
if (!Gfx.Created) glKosInit();
|
||||
|
||||
Gfx_SetViewport(0, 0, Game.Width, Game.Height);
|
||||
InitGLState();
|
||||
|
||||
|
|
@ -59,7 +61,7 @@ void Gfx_Free(void) {
|
|||
*#########################################################################################################################*/
|
||||
static PackedCol gfx_clearColor;
|
||||
void Gfx_SetFaceCulling(cc_bool enabled) { gl_Toggle(GL_CULL_FACE); }
|
||||
void Gfx_SetAlphaBlending(cc_bool enabled) { gl_Toggle(GL_BLEND); }
|
||||
static void SetAlphaBlend(cc_bool enabled) { gl_Toggle(GL_BLEND); }
|
||||
void Gfx_SetAlphaArgBlend(cc_bool enabled) { }
|
||||
|
||||
void Gfx_ClearColor(PackedCol color) {
|
||||
|
|
@ -79,7 +81,7 @@ static void SetColorWrite(cc_bool r, cc_bool g, cc_bool b, cc_bool a) {
|
|||
void Gfx_SetDepthWrite(cc_bool enabled) { glDepthMask(enabled); }
|
||||
void Gfx_SetDepthTest(cc_bool enabled) { gl_Toggle(GL_DEPTH_TEST); }
|
||||
|
||||
void Gfx_SetAlphaTest(cc_bool enabled) { gl_Toggle(GL_ALPHA_TEST); }
|
||||
static void SetAlphaTest(cc_bool enabled) { gl_Toggle(GL_ALPHA_TEST); }
|
||||
|
||||
void Gfx_DepthOnlyRendering(cc_bool depthOnly) {
|
||||
// don't need a fake second pass in this case
|
||||
|
|
@ -352,7 +354,7 @@ static FogFunc gfx_fogMode = -1;
|
|||
|
||||
void Gfx_SetFog(cc_bool enabled) {
|
||||
gfx_fogEnabled = enabled;
|
||||
if (enabled) { glEnable(GL_FOG); } else { glDisable(GL_FOG); }
|
||||
gl_Toggle(GL_FOG);
|
||||
}
|
||||
|
||||
void Gfx_SetFogCol(PackedCol color) {
|
||||
|
|
@ -465,15 +467,35 @@ cc_bool Gfx_WarnIfNecessary(void) {
|
|||
*----------------------------------------------------------Drawing--------------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
#define VB_PTR gfx_vertices
|
||||
static const void* VERTEX_PTR;
|
||||
extern void apply_poly_header(PolyHeader* header, PolyList* activePolyList);
|
||||
|
||||
static void SetupVertices(int startVertex) {
|
||||
if (gfx_format == VERTEX_FORMAT_TEXTURED) {
|
||||
cc_uint32 offset = startVertex * SIZEOF_VERTEX_TEXTURED;
|
||||
gldcVertexPointer(SIZEOF_VERTEX_TEXTURED, (void*)(VB_PTR + offset));
|
||||
} else {
|
||||
cc_uint32 offset = startVertex * SIZEOF_VERTEX_COLOURED;
|
||||
gldcVertexPointer(SIZEOF_VERTEX_COLOURED, (void*)(VB_PTR + offset));
|
||||
extern Vertex* DrawColouredQuads(const void* src, Vertex* dst, int numQuads);
|
||||
extern Vertex* DrawTexturedQuads(const void* src, Vertex* dst, int numQuads);
|
||||
|
||||
void DrawQuads(int count) {
|
||||
if (!count) return;
|
||||
PolyList* output = _glActivePolyList();
|
||||
AlignedVectorHeader* hdr = &output->vector.hdr;
|
||||
|
||||
uint32_t header_required = (hdr->size == 0) || STATE_DIRTY;
|
||||
// Reserve room for the vertices and header
|
||||
Vertex* beg = aligned_vector_reserve(&output->vector, hdr->size + (header_required) + count);
|
||||
|
||||
if (header_required) {
|
||||
apply_poly_header((PolyHeader*)beg, output);
|
||||
STATE_DIRTY = GL_FALSE;
|
||||
beg++;
|
||||
hdr->size += 1;
|
||||
}
|
||||
Vertex* end;
|
||||
|
||||
if (TEXTURES_ENABLED) {
|
||||
end = DrawTexturedQuads(VERTEX_PTR, beg, count >> 2);
|
||||
} else {
|
||||
end = DrawColouredQuads(VERTEX_PTR, beg, count >> 2);
|
||||
}
|
||||
hdr->size += (end - beg);
|
||||
}
|
||||
|
||||
void Gfx_SetVertexFormat(VertexFormat fmt) {
|
||||
|
|
@ -489,29 +511,33 @@ void Gfx_SetVertexFormat(VertexFormat fmt) {
|
|||
}
|
||||
|
||||
void Gfx_DrawVb_Lines(int verticesCount) {
|
||||
SetupVertices(0);
|
||||
//SetupVertices(0);
|
||||
//glDrawArrays(GL_LINES, 0, verticesCount);
|
||||
}
|
||||
|
||||
void Gfx_DrawVb_IndexedTris_Range(int verticesCount, int startVertex) {
|
||||
SetupVertices(startVertex);
|
||||
glDrawArrays(GL_QUADS, 0, verticesCount);
|
||||
if (gfx_format == VERTEX_FORMAT_TEXTURED) {
|
||||
VERTEX_PTR = gfx_vertices + startVertex * SIZEOF_VERTEX_TEXTURED;
|
||||
} else {
|
||||
VERTEX_PTR = gfx_vertices + startVertex * SIZEOF_VERTEX_COLOURED;
|
||||
}
|
||||
|
||||
DrawQuads(verticesCount);
|
||||
}
|
||||
|
||||
void Gfx_DrawVb_IndexedTris(int verticesCount) {
|
||||
SetupVertices(0);
|
||||
VERTEX_PTR = gfx_vertices;
|
||||
|
||||
if (textureOffset) ShiftTextureCoords(verticesCount);
|
||||
glDrawArrays(GL_QUADS, 0, verticesCount);
|
||||
DrawQuads(verticesCount);
|
||||
if (textureOffset) UnshiftTextureCoords(verticesCount);
|
||||
}
|
||||
|
||||
void Gfx_DrawIndexedTris_T2fC4b(int verticesCount, int startVertex) {
|
||||
if (renderingDisabled) return;
|
||||
|
||||
cc_uint32 offset = startVertex * SIZEOF_VERTEX_TEXTURED;
|
||||
gldcVertexPointer(SIZEOF_VERTEX_TEXTURED, (void*)(VB_PTR + offset));
|
||||
glDrawArrays(GL_QUADS, 0, verticesCount);
|
||||
VERTEX_PTR = gfx_vertices + startVertex * SIZEOF_VERTEX_TEXTURED;
|
||||
DrawQuads(verticesCount);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -550,6 +576,7 @@ void Gfx_ClearBuffers(GfxBuffers buffers) {
|
|||
}
|
||||
|
||||
void Gfx_EndFrame(void) {
|
||||
pvr_wait_ready();
|
||||
glKosSwapBuffers();
|
||||
if (gfx_minFrameMs) LimitFPS();
|
||||
}
|
||||
|
|
@ -558,6 +585,11 @@ void Gfx_OnWindowResize(void) {
|
|||
Gfx_SetViewport(0, 0, Game.Width, Game.Height);
|
||||
}
|
||||
|
||||
extern float VP_COL_HWIDTH, VP_TEX_HWIDTH;
|
||||
extern float VP_COL_HHEIGHT, VP_TEX_HHEIGHT;
|
||||
extern float VP_COL_X_PLUS_HWIDTH, VP_TEX_X_PLUS_HWIDTH;
|
||||
extern float VP_COL_Y_PLUS_HHEIGHT, VP_TEX_Y_PLUS_HHEIGHT;
|
||||
|
||||
void Gfx_SetViewport(int x, int y, int w, int h) {
|
||||
if (x == 0 && y == 0 && w == Game.Width && h == Game.Height) {
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
|
|
@ -567,5 +599,11 @@ void Gfx_SetViewport(int x, int y, int w, int h) {
|
|||
|
||||
glViewport(x, y, w, h);
|
||||
glScissor (x, y, w, h);
|
||||
|
||||
VP_COL_HWIDTH = VP_TEX_HWIDTH = w * 0.5f;
|
||||
VP_COL_HHEIGHT = VP_TEX_HHEIGHT = h * -0.5f;
|
||||
|
||||
VP_COL_X_PLUS_HWIDTH = VP_TEX_X_PLUS_HWIDTH = x + w * 0.5f;
|
||||
VP_COL_Y_PLUS_HHEIGHT = VP_TEX_Y_PLUS_HHEIGHT = y + h * 0.5f;
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -187,7 +187,7 @@ void Gfx_SetFaceCulling(cc_bool enabled) {
|
|||
GX_SetCullMode(enabled ? GX_CULL_FRONT : GX_CULL_NONE);
|
||||
}
|
||||
|
||||
void Gfx_SetAlphaBlending(cc_bool enabled) {
|
||||
static void SetAlphaBlend(cc_bool enabled) {
|
||||
if (enabled) {
|
||||
GX_SetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR);
|
||||
} else {
|
||||
|
|
@ -409,7 +409,7 @@ void Gfx_SetFogEnd(float value) {
|
|||
void Gfx_SetFogMode(FogFunc func) {
|
||||
}
|
||||
|
||||
void Gfx_SetAlphaTest(cc_bool enabled) {
|
||||
static void SetAlphaTest(cc_bool enabled) {
|
||||
if (enabled) {
|
||||
GX_SetAlphaCompare(GX_GREATER, 127, GX_AOP_AND, GX_ALWAYS, 0);
|
||||
} else {
|
||||
|
|
@ -560,7 +560,7 @@ static void Draw_ColouredTriangles(int verticesCount, int startVertex) {
|
|||
struct VertexColoured* v = (struct VertexColoured*)gfx_vertices + startVertex + i;
|
||||
|
||||
GX_Position3f32(v->x, v->y, v->z);
|
||||
GX_Color4u8(PackedCol_R(v->Col), PackedCol_G(v->Col), PackedCol_B(v->Col), PackedCol_A(v->Col));
|
||||
GX_Color1u32(v->Col);
|
||||
}
|
||||
GX_End();
|
||||
}
|
||||
|
|
@ -572,7 +572,7 @@ static void Draw_TexturedTriangles(int verticesCount, int startVertex) {
|
|||
struct VertexTextured* v = (struct VertexTextured*)gfx_vertices + startVertex + i;
|
||||
|
||||
GX_Position3f32(v->x, v->y, v->z);
|
||||
GX_Color4u8(PackedCol_R(v->Col), PackedCol_G(v->Col), PackedCol_B(v->Col), PackedCol_A(v->Col));
|
||||
GX_Color1u32(v->Col);
|
||||
GX_TexCoord2f32(v->U, v->V);
|
||||
}
|
||||
GX_End();
|
||||
|
|
|
|||
|
|
@ -534,7 +534,7 @@ void Gfx_SetFogMode(FogFunc func) {
|
|||
gfx_fogMode = func;
|
||||
}
|
||||
|
||||
void Gfx_SetAlphaTest(cc_bool enabled) {
|
||||
static void SetAlphaTest(cc_bool enabled) {
|
||||
if (enabled) { glEnable(GL_ALPHA_TEST); } else { glDisable(GL_ALPHA_TEST); }
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -202,7 +202,7 @@ void Gfx_SetDynamicVbData(GfxResourceID vb, void* vertices, int vCount) {
|
|||
|
||||
/* cached uniforms (cached for multiple programs */
|
||||
static struct Matrix _view, _proj, _mvp;
|
||||
static cc_bool gfx_alphaTest, gfx_texTransform;
|
||||
static cc_bool gfx_texTransform;
|
||||
static float _texX, _texY;
|
||||
static PackedCol gfx_fogColor;
|
||||
static float gfx_fogEnd = -1.0f, gfx_fogDensity = -1.0f;
|
||||
|
|
@ -500,7 +500,7 @@ void Gfx_SetFogMode(FogFunc func) {
|
|||
SwitchProgram();
|
||||
}
|
||||
|
||||
void Gfx_SetAlphaTest(cc_bool enabled) { gfx_alphaTest = enabled; SwitchProgram(); }
|
||||
static void SetAlphaTest(cc_bool enabled) { SwitchProgram(); }
|
||||
|
||||
void Gfx_DepthOnlyRendering(cc_bool depthOnly) {
|
||||
cc_bool enabled = !depthOnly;
|
||||
|
|
|
|||
|
|
@ -237,7 +237,7 @@ void Gfx_DisableMipmaps(void) { }
|
|||
*-----------------------------------------------------State management----------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
void Gfx_SetFaceCulling(cc_bool enabled) { gl_Toggle(GL_CULL_FACE); }
|
||||
void Gfx_SetAlphaBlending(cc_bool enabled) { gl_Toggle(GL_BLEND); }
|
||||
static void SetAlphaBlend(cc_bool enabled) { gl_Toggle(GL_BLEND); }
|
||||
void Gfx_SetAlphaArgBlend(cc_bool enabled) { }
|
||||
|
||||
static void SetColorWrite(cc_bool r, cc_bool g, cc_bool b, cc_bool a) {
|
||||
|
|
@ -377,7 +377,7 @@ void Gfx_SetFogEnd(float value) {
|
|||
void Gfx_SetFogMode(FogFunc func) {
|
||||
}
|
||||
|
||||
void Gfx_SetAlphaTest(cc_bool enabled) {
|
||||
static void SetAlphaTest(cc_bool enabled) {
|
||||
if (enabled) { glEnable(GL_ALPHA_TEST); } else { glDisable(GL_ALPHA_TEST); }
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -176,7 +176,7 @@ void Gfx_SetFaceCulling(cc_bool enabled) {
|
|||
glPolyFmt(POLY_ALPHA(31) | (enabled ? POLY_CULL_BACK : POLY_CULL_NONE));
|
||||
}
|
||||
|
||||
void Gfx_SetAlphaBlending(cc_bool enabled) {
|
||||
static void SetAlphaBlend(cc_bool enabled) {
|
||||
/*if (enabled) {
|
||||
glEnable(GL_BLEND);
|
||||
} else {
|
||||
|
|
@ -376,7 +376,7 @@ void Gfx_SetFogEnd(float value) {
|
|||
void Gfx_SetFogMode(FogFunc func) {
|
||||
}
|
||||
|
||||
void Gfx_SetAlphaTest(cc_bool enabled) {
|
||||
static void SetAlphaTest(cc_bool enabled) {
|
||||
if (enabled) {
|
||||
//glEnable(GL_ALPHA_TEST);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -36,6 +36,9 @@ static RenderBuffer buffers[2];
|
|||
static cc_uint8* next_packet;
|
||||
static int active_buffer;
|
||||
static RenderBuffer* buffer;
|
||||
static cc_bool rendering2D;
|
||||
static void* lastPoly;
|
||||
static cc_bool cullingEnabled;
|
||||
|
||||
static void OnBufferUpdated(void) {
|
||||
buffer = &buffers[active_buffer];
|
||||
|
|
@ -100,7 +103,7 @@ void Gfx_FreeState(void) {
|
|||
|
||||
void Gfx_Create(void) {
|
||||
Gfx.MaxTexWidth = 128;
|
||||
Gfx.MaxTexHeight = 128;
|
||||
Gfx.MaxTexHeight = 256;
|
||||
Gfx.Created = true;
|
||||
|
||||
Gfx_RestoreState();
|
||||
|
|
@ -126,30 +129,41 @@ void Gfx_Free(void) {
|
|||
// VRAM can be divided into texture pages
|
||||
// 32 texture pages total - each page is 64 x 256
|
||||
// 10 texture pages are occupied by the doublebuffered display
|
||||
// 22 texture packs are usable, and are then divided into
|
||||
// - 4 pages for 256 wide textures, 8 for 128 wide, 10 for 64
|
||||
#define TPAGE_START_HOR 5
|
||||
#define TPAGES_PER_HALF 16
|
||||
|
||||
// 22 texture pages are usable for textures
|
||||
// These 22 pages are then divided into:
|
||||
// - 5 for 128+ wide horizontal, 6 otherwise
|
||||
// - 11 pages for vertical textures
|
||||
#define TPAGE_WIDTH 64
|
||||
#define TPAGE_HEIGHT 256
|
||||
#define MAX_TEX_PAGES 22
|
||||
static cc_uint8 vram_used[(MAX_TEX_PAGES * TPAGE_HEIGHT) / 8];
|
||||
#define TPAGES_PER_HALF 16
|
||||
|
||||
// Horizontally oriented textures (first group of 16)
|
||||
#define TPAGE_START_HOR 5
|
||||
#define MAX_HOR_TEX_PAGES 11
|
||||
#define MAX_HOR_TEX_LINES (MAX_HOR_TEX_PAGES * TPAGE_HEIGHT)
|
||||
|
||||
// Horizontally oriented textures (second group of 16)
|
||||
#define TPAGE_START_VER (16 + 5)
|
||||
#define MAX_VER_TEX_PAGES 11
|
||||
#define MAX_VER_TEX_LINES (MAX_VER_TEX_PAGES * TPAGE_WIDTH)
|
||||
|
||||
static cc_uint8 vram_used[(MAX_HOR_TEX_LINES + MAX_VER_TEX_LINES) / 8];
|
||||
#define VRAM_SetUsed(line) (vram_used[(line) / 8] |= (1 << ((line) % 8)))
|
||||
#define VRAM_UnUsed(line) (vram_used[(line) / 8] &= ~(1 << ((line) % 8)))
|
||||
#define VRAM_IsUsed(line) (vram_used[(line) / 8] & (1 << ((line) % 8)))
|
||||
|
||||
static void VRAM_GetBlockRange(int width, int* beg, int* end) {
|
||||
if (width >= 256) {
|
||||
*beg = 0;
|
||||
*end = 4 * TPAGE_HEIGHT;
|
||||
#define VRAM_BoundingAxis(width, height) height > width ? width : height
|
||||
|
||||
static void VRAM_GetBlockRange(int width, int height, int* beg, int* end) {
|
||||
if (height > width) {
|
||||
*beg = MAX_HOR_TEX_LINES;
|
||||
*end = MAX_HOR_TEX_LINES + MAX_VER_TEX_LINES;
|
||||
} else if (width >= 128) {
|
||||
*beg = 4 * TPAGE_HEIGHT;
|
||||
*end = 12 * TPAGE_HEIGHT;
|
||||
*beg = 0;
|
||||
*end = 5 * TPAGE_HEIGHT;
|
||||
} else {
|
||||
*beg = 12 * TPAGE_HEIGHT;
|
||||
*end = 22 * TPAGE_HEIGHT;
|
||||
*beg = 5 * TPAGE_HEIGHT;
|
||||
*end = MAX_HOR_TEX_LINES;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -163,7 +177,7 @@ static cc_bool VRAM_IsRangeFree(int beg, int end) {
|
|||
|
||||
static int VRAM_FindFreeBlock(int width, int height) {
|
||||
int beg, end;
|
||||
VRAM_GetBlockRange(width, &beg, &end);
|
||||
VRAM_GetBlockRange(width, height, &beg, &end);
|
||||
|
||||
// TODO kinda inefficient
|
||||
for (int i = beg; i < end - height; i++)
|
||||
|
|
@ -175,13 +189,41 @@ static int VRAM_FindFreeBlock(int width, int height) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
static void VRAM_AllocBlock(int line, int width, int height) {
|
||||
int lines = VRAM_BoundingAxis(width, height);
|
||||
for (int i = line; i < line + lines; i++)
|
||||
{
|
||||
VRAM_SetUsed(i);
|
||||
}
|
||||
}
|
||||
|
||||
static void VRAM_FreeBlock(int line, int width, int height) {
|
||||
int lines = VRAM_BoundingAxis(width, height);
|
||||
for (int i = line; i < line + lines; i++)
|
||||
{
|
||||
VRAM_UnUsed(i);
|
||||
}
|
||||
}
|
||||
|
||||
static int VRAM_CalcPage(int line) {
|
||||
if (line < MAX_HOR_TEX_LINES) {
|
||||
return TPAGE_START_HOR + (line / TPAGE_HEIGHT);
|
||||
} else {
|
||||
line -= MAX_HOR_TEX_LINES;
|
||||
return TPAGE_START_VER + (line / TPAGE_WIDTH);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define TEXTURES_MAX_COUNT 64
|
||||
typedef struct GPUTexture {
|
||||
cc_uint16 width, height;
|
||||
cc_uint8 width_mask, height_mask;
|
||||
cc_uint16 line, tpage;
|
||||
cc_uint8 xOffset, yOffset;
|
||||
} GPUTexture;
|
||||
static GPUTexture textures[TEXTURES_MAX_COUNT];
|
||||
static GPUTexture* active_tex;
|
||||
static GPUTexture* curTex;
|
||||
|
||||
#define BGRA8_to_PS1(src) \
|
||||
((src[2] & 0xF8) >> 3) | ((src[1] & 0xF8) << 2) | ((src[0] & 0xF8) << 7) | ((src[3] & 0x80) << 8)
|
||||
|
|
@ -205,28 +247,30 @@ static void* AllocTextureAt(int i, struct Bitmap* bmp, int rowWidth) {
|
|||
int line = VRAM_FindFreeBlock(bmp->width, bmp->height);
|
||||
if (line == -1) { Mem_Free(tmp); return NULL; }
|
||||
|
||||
tex->width = bmp->width;
|
||||
tex->height = bmp->height;
|
||||
tex->width = bmp->width; tex->width_mask = bmp->width - 1;
|
||||
tex->height = bmp->height; tex->height_mask = bmp->height - 1;
|
||||
tex->line = line;
|
||||
|
||||
int page = TPAGE_START_HOR + (line / TPAGE_HEIGHT);
|
||||
// In bottom half of VRAM? Need to offset horizontally again
|
||||
if (page >= TPAGES_PER_HALF) page += TPAGE_START_HOR;
|
||||
|
||||
int page = VRAM_CalcPage(line);
|
||||
int pageX = (page % TPAGES_PER_HALF);
|
||||
int pageY = (page / TPAGES_PER_HALF);
|
||||
|
||||
for (int i = tex->line; i < tex->line + tex->height; i++)
|
||||
{
|
||||
VRAM_SetUsed(i);
|
||||
}
|
||||
tex->tpage = (2 << 7) | (pageY << 4) | pageX;
|
||||
|
||||
VRAM_AllocBlock(line, bmp->width, bmp->height);
|
||||
if (bmp->height > bmp->width) {
|
||||
tex->xOffset = line % TPAGE_WIDTH;
|
||||
tex->yOffset = 0;
|
||||
} else {
|
||||
tex->xOffset = 0;
|
||||
tex->yOffset = line % TPAGE_HEIGHT;
|
||||
}
|
||||
|
||||
Platform_Log3("%i x %i = %i", &bmp->width, &bmp->height, &line);
|
||||
Platform_Log3(" at %i (%i, %i)", &page, &pageX, &pageY);
|
||||
|
||||
RECT rect;
|
||||
rect.x = pageX * TPAGE_WIDTH;
|
||||
rect.y = pageY * TPAGE_HEIGHT + (line % TPAGE_HEIGHT);
|
||||
rect.x = pageX * TPAGE_WIDTH + tex->xOffset;
|
||||
rect.y = pageY * TPAGE_HEIGHT + tex->yOffset;
|
||||
rect.w = bmp->width;
|
||||
rect.h = bmp->height;
|
||||
|
||||
|
|
@ -251,7 +295,7 @@ static GfxResourceID Gfx_AllocTexture(struct Bitmap* bmp, int rowWidth, cc_uint8
|
|||
|
||||
void Gfx_BindTexture(GfxResourceID texId) {
|
||||
if (!texId) texId = white_square;
|
||||
active_tex = (GPUTexture*)texId;
|
||||
curTex = (GPUTexture*)texId;
|
||||
}
|
||||
|
||||
void Gfx_DeleteTexture(GfxResourceID* texId) {
|
||||
|
|
@ -259,10 +303,7 @@ void Gfx_DeleteTexture(GfxResourceID* texId) {
|
|||
if (!data) return;
|
||||
GPUTexture* tex = (GPUTexture*)data;
|
||||
|
||||
for (int i = tex->line; i < tex->line + tex->height; i++)
|
||||
{
|
||||
VRAM_UnUsed(i);
|
||||
}
|
||||
VRAM_FreeBlock(tex->line, tex->width, tex->height);
|
||||
tex->width = 0; tex->height = 0;
|
||||
*texId = NULL;
|
||||
}
|
||||
|
|
@ -285,13 +326,13 @@ void Gfx_SetFogEnd(float value) { }
|
|||
void Gfx_SetFogMode(FogFunc func) { }
|
||||
|
||||
void Gfx_SetFaceCulling(cc_bool enabled) {
|
||||
// TODO
|
||||
cullingEnabled = enabled;
|
||||
}
|
||||
|
||||
void Gfx_SetAlphaTest(cc_bool enabled) {
|
||||
static void SetAlphaTest(cc_bool enabled) {
|
||||
}
|
||||
|
||||
void Gfx_SetAlphaBlending(cc_bool enabled) {
|
||||
static void SetAlphaBlend(cc_bool enabled) {
|
||||
}
|
||||
|
||||
void Gfx_SetAlphaArgBlend(cc_bool enabled) { }
|
||||
|
|
@ -530,8 +571,77 @@ static void Transform(Vec3* result, struct VertexTextured* a, const struct Matri
|
|||
}
|
||||
|
||||
cc_bool VERTEX_LOGGING;
|
||||
static void DrawColouredQuads(int verticesCount, int startVertex) {
|
||||
|
||||
static void DrawColouredQuads2D(int verticesCount, int startVertex) {
|
||||
return;
|
||||
for (int i = 0; i < verticesCount; i += 4)
|
||||
{
|
||||
struct VertexColoured* v = (struct VertexColoured*)gfx_vertices + startVertex + i;
|
||||
|
||||
POLY_F4* poly = new_primitive(sizeof(POLY_F4));
|
||||
setPolyF4(poly);
|
||||
|
||||
poly->x0 = v[1].x; poly->y0 = v[1].y;
|
||||
poly->x1 = v[0].x; poly->y1 = v[0].y;
|
||||
poly->x2 = v[2].x; poly->y2 = v[2].y;
|
||||
poly->x3 = v[3].x; poly->y3 = v[3].y;
|
||||
|
||||
poly->r0 = PackedCol_R(v->Col);
|
||||
poly->g0 = PackedCol_G(v->Col);
|
||||
poly->b0 = PackedCol_B(v->Col);
|
||||
|
||||
if (lastPoly) {
|
||||
setaddr(poly, getaddr(lastPoly)); setaddr(lastPoly, poly);
|
||||
} else {
|
||||
addPrim(&buffer->ot[0], poly);
|
||||
}
|
||||
lastPoly = poly;
|
||||
}
|
||||
}
|
||||
|
||||
static void DrawTexturedQuads2D(int verticesCount, int startVertex) {
|
||||
int uOffset = curTex->xOffset, vOffset = curTex->yOffset;
|
||||
|
||||
for (int i = 0; i < verticesCount; i += 4)
|
||||
{
|
||||
struct VertexTextured* v = (struct VertexTextured*)gfx_vertices + startVertex + i;
|
||||
|
||||
POLY_FT4* poly = new_primitive(sizeof(POLY_FT4));
|
||||
setPolyFT4(poly);
|
||||
poly->tpage = curTex->tpage;
|
||||
poly->clut = 0;
|
||||
|
||||
// TODO & instead of %
|
||||
poly->x0 = v[1].x; poly->y0 = v[1].y;
|
||||
poly->x1 = v[0].x; poly->y1 = v[0].y;
|
||||
poly->x2 = v[2].x; poly->y2 = v[2].y;
|
||||
poly->x3 = v[3].x; poly->y3 = v[3].y;
|
||||
|
||||
poly->u0 = ((int)(v[1].U * 0.99f * curTex->width) & curTex->width_mask) + uOffset;
|
||||
poly->v0 = ((int)(v[1].V * curTex->height) & curTex->height_mask) + vOffset;
|
||||
poly->u1 = ((int)(v[0].U * 0.99f * curTex->width) & curTex->width_mask) + uOffset;
|
||||
poly->v1 = ((int)(v[0].V * curTex->height) & curTex->height_mask) + vOffset;
|
||||
poly->u2 = ((int)(v[2].U * 0.99f * curTex->width) & curTex->width_mask) + uOffset;
|
||||
poly->v2 = ((int)(v[2].V * curTex->height) & curTex->height_mask) + vOffset;
|
||||
poly->u3 = ((int)(v[3].U * 0.99f * curTex->width) & curTex->width_mask) + uOffset;
|
||||
poly->v3 = ((int)(v[3].V * curTex->height) & curTex->height_mask) + vOffset;
|
||||
|
||||
// https://problemkaputt.de/psxspx-gpu-rendering-attributes.htm
|
||||
// "For untextured graphics, 8bit RGB values of FFh are brightest. However, for texture blending, 8bit values of 80h are brightest"
|
||||
poly->r0 = PackedCol_R(v->Col) >> 1;
|
||||
poly->g0 = PackedCol_G(v->Col) >> 1;
|
||||
poly->b0 = PackedCol_B(v->Col) >> 1;
|
||||
|
||||
if (lastPoly) {
|
||||
setaddr(poly, getaddr(lastPoly)); setaddr(lastPoly, poly);
|
||||
} else {
|
||||
addPrim(&buffer->ot[0], poly);
|
||||
}
|
||||
lastPoly = poly;
|
||||
}
|
||||
}
|
||||
|
||||
static void DrawColouredQuads3D(int verticesCount, int startVertex) {
|
||||
for (int i = 0; i < verticesCount; i += 4)
|
||||
{
|
||||
struct VertexColoured* v = (struct VertexColoured*)gfx_vertices + startVertex + i;
|
||||
|
|
@ -567,8 +677,8 @@ static void DrawColouredQuads(int verticesCount, int startVertex) {
|
|||
}
|
||||
}
|
||||
|
||||
static void DrawTexturedQuads(int verticesCount, int startVertex) {
|
||||
int pageOffset = active_tex->line % TPAGE_HEIGHT;
|
||||
static void DrawTexturedQuads3D(int verticesCount, int startVertex) {
|
||||
int uOffset = curTex->xOffset, vOffset = curTex->yOffset;
|
||||
|
||||
for (int i = 0; i < verticesCount; i += 4)
|
||||
{
|
||||
|
|
@ -576,7 +686,7 @@ static void DrawTexturedQuads(int verticesCount, int startVertex) {
|
|||
|
||||
POLY_FT4* poly = new_primitive(sizeof(POLY_FT4));
|
||||
setPolyFT4(poly);
|
||||
poly->tpage = active_tex->tpage;
|
||||
poly->tpage = curTex->tpage;
|
||||
poly->clut = 0;
|
||||
|
||||
Vec3 coords[4];
|
||||
|
|
@ -586,12 +696,28 @@ static void DrawTexturedQuads(int verticesCount, int startVertex) {
|
|||
Transform(&coords[3], &v[3], &mvp);
|
||||
|
||||
// TODO & instead of %
|
||||
poly->x0 = coords[1].x; poly->y0 = coords[1].y; poly->u0 = (int)(v[1].U * active_tex->width) % active_tex->width; poly->v0 = ((int)(v[1].V * active_tex->height) % active_tex->height) + pageOffset;
|
||||
poly->x1 = coords[0].x; poly->y1 = coords[0].y; poly->u1 = (int)(v[0].U * active_tex->width) % active_tex->width; poly->v1 = ((int)(v[0].V * active_tex->height) % active_tex->height) + pageOffset;
|
||||
poly->x2 = coords[2].x; poly->y2 = coords[2].y; poly->u2 = (int)(v[2].U * active_tex->width) % active_tex->width; poly->v2 = ((int)(v[2].V * active_tex->height) % active_tex->height) + pageOffset;
|
||||
poly->x3 = coords[3].x; poly->y3 = coords[3].y; poly->u3 = (int)(v[3].U * active_tex->width) % active_tex->width; poly->v3 = ((int)(v[3].V * active_tex->height) % active_tex->height) + pageOffset;
|
||||
poly->x0 = coords[1].x; poly->y0 = coords[1].y;
|
||||
poly->x1 = coords[0].x; poly->y1 = coords[0].y;
|
||||
poly->x2 = coords[2].x; poly->y2 = coords[2].y;
|
||||
poly->x3 = coords[3].x; poly->y3 = coords[3].y;
|
||||
|
||||
//int P = active_tex->height, page = poly->tpage & 0xFF, ll = active_tex->line % TPAGE_HEIGHT;
|
||||
if (cullingEnabled) {
|
||||
// https://gamedev.stackexchange.com/questions/203694/how-to-make-backface-culling-work-correctly-in-both-orthographic-and-perspective
|
||||
int signA = (poly->x0 - poly->x1) * (poly->y2 - poly->y1);
|
||||
int signB = (poly->x2 - poly->x1) * (poly->y0 - poly->y1);
|
||||
if (signA > signB) continue;
|
||||
}
|
||||
|
||||
poly->u0 = ((int)(v[1].U * curTex->width) & curTex->width_mask) + uOffset;
|
||||
poly->v0 = ((int)(v[1].V * curTex->height) & curTex->height_mask) + vOffset;
|
||||
poly->u1 = ((int)(v[0].U * curTex->width) & curTex->width_mask) + uOffset;
|
||||
poly->v1 = ((int)(v[0].V * curTex->height) & curTex->height_mask) + vOffset;
|
||||
poly->u2 = ((int)(v[2].U * curTex->width) & curTex->width_mask) + uOffset;
|
||||
poly->v2 = ((int)(v[2].V * curTex->height) & curTex->height_mask) + vOffset;
|
||||
poly->u3 = ((int)(v[3].U * curTex->width) & curTex->width_mask) + uOffset;
|
||||
poly->v3 = ((int)(v[3].V * curTex->height) & curTex->height_mask) + vOffset;
|
||||
|
||||
//int P = curTex->height, page = poly->tpage & 0xFF, ll = curTex->yOffset;
|
||||
//Platform_Log4("XYZ: %f3 x %i, %i, %i", &v[0].V, &P, &page, &ll);
|
||||
int p = (coords[0].z + coords[1].z + coords[2].z + coords[3].z) / 4;
|
||||
if (p < 0 || p >= OT_LENGTH) continue;
|
||||
|
|
@ -600,9 +726,9 @@ static void DrawTexturedQuads(int verticesCount, int startVertex) {
|
|||
//if (VERTEX_LOGGING) Platform_Log3("IN: %i, %i, %i", &X, &Y, &Z);
|
||||
X = poly->x1; Y = poly->y1, Z = coords[0].z;
|
||||
|
||||
poly->r0 = PackedCol_R(v->Col);
|
||||
poly->g0 = PackedCol_G(v->Col);
|
||||
poly->b0 = PackedCol_B(v->Col);
|
||||
poly->r0 = PackedCol_R(v->Col) >> 1;
|
||||
poly->g0 = PackedCol_G(v->Col) >> 1;
|
||||
poly->b0 = PackedCol_B(v->Col) >> 1;
|
||||
//if (VERTEX_LOGGING) Platform_Log4("OUT: %i, %i, %i (%i)", &X, &Y, &Z, &p);
|
||||
|
||||
// TODO: 2D shouldn't use AddPrim, draws in the wrong way
|
||||
|
|
@ -678,24 +804,29 @@ static void DrawTexturedQuads(int verticesCount, int startVertex) {
|
|||
}
|
||||
}*/
|
||||
|
||||
void Gfx_DrawVb_IndexedTris_Range(int verticesCount, int startVertex) {
|
||||
if (gfx_format == VERTEX_FORMAT_TEXTURED) {
|
||||
DrawTexturedQuads(verticesCount, startVertex);
|
||||
static void DrawQuads(int verticesCount, int startVertex) {
|
||||
if (rendering2D && gfx_format == VERTEX_FORMAT_TEXTURED) {
|
||||
DrawTexturedQuads2D(verticesCount, startVertex);
|
||||
} else if (rendering2D) {
|
||||
DrawColouredQuads2D(verticesCount, startVertex);
|
||||
} else if (gfx_format == VERTEX_FORMAT_TEXTURED) {
|
||||
DrawTexturedQuads3D(verticesCount, startVertex);
|
||||
} else {
|
||||
DrawColouredQuads(verticesCount, startVertex);
|
||||
DrawColouredQuads3D(verticesCount, startVertex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Gfx_DrawVb_IndexedTris_Range(int verticesCount, int startVertex) {
|
||||
DrawQuads(verticesCount, startVertex);
|
||||
}
|
||||
|
||||
void Gfx_DrawVb_IndexedTris(int verticesCount) {
|
||||
if (gfx_format == VERTEX_FORMAT_TEXTURED) {
|
||||
DrawTexturedQuads(verticesCount, 0);
|
||||
} else {
|
||||
DrawColouredQuads(verticesCount, 0);
|
||||
}
|
||||
DrawQuads(verticesCount, 0);
|
||||
}
|
||||
|
||||
void Gfx_DrawIndexedTris_T2fC4b(int verticesCount, int startVertex) {
|
||||
DrawTexturedQuads(verticesCount, startVertex);
|
||||
DrawTexturedQuads3D(verticesCount, startVertex);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -711,6 +842,7 @@ cc_bool Gfx_WarnIfNecessary(void) {
|
|||
}
|
||||
|
||||
void Gfx_BeginFrame(void) {
|
||||
lastPoly = NULL;
|
||||
}
|
||||
|
||||
void Gfx_EndFrame(void) {
|
||||
|
|
@ -735,4 +867,14 @@ void Gfx_GetApiInfo(cc_string* info) {
|
|||
}
|
||||
|
||||
cc_bool Gfx_TryRestoreContext(void) { return true; }
|
||||
|
||||
void Gfx_Begin2D(int width, int height) {
|
||||
rendering2D = true;
|
||||
Gfx_SetAlphaBlending(true);
|
||||
}
|
||||
|
||||
void Gfx_End2D(void) {
|
||||
rendering2D = false;
|
||||
Gfx_SetAlphaBlending(false);
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -243,8 +243,6 @@ void Gfx_DisableMipmaps(void) { }
|
|||
*------------------------------------------------------State management---------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
static int clearR, clearG, clearB;
|
||||
static cc_bool gfx_alphaBlend;
|
||||
static cc_bool gfx_alphaTest;
|
||||
static cc_bool gfx_depthTest;
|
||||
static cc_bool stateDirty;
|
||||
|
||||
|
|
@ -274,13 +272,11 @@ void Gfx_SetFaceCulling(cc_bool enabled) {
|
|||
// TODO
|
||||
}
|
||||
|
||||
void Gfx_SetAlphaTest(cc_bool enabled) {
|
||||
gfx_alphaTest = enabled;
|
||||
static void SetAlphaTest(cc_bool enabled) {
|
||||
stateDirty = true;
|
||||
}
|
||||
|
||||
void Gfx_SetAlphaBlending(cc_bool enabled) {
|
||||
gfx_alphaBlend = enabled;
|
||||
static void SetAlphaBlend(cc_bool enabled) {
|
||||
// TODO update primitive state
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -286,7 +286,7 @@ void Gfx_SetFaceCulling(cc_bool enabled) {
|
|||
rsxSetCullFaceEnable(context, enabled);
|
||||
}
|
||||
|
||||
void Gfx_SetAlphaBlending(cc_bool enabled) {
|
||||
static void SetAlphaBlend(cc_bool enabled) {
|
||||
rsxSetBlendEnable(context, enabled);
|
||||
}
|
||||
void Gfx_SetAlphaArgBlend(cc_bool enabled) { }
|
||||
|
|
@ -316,7 +316,7 @@ void Gfx_SetDepthTest(cc_bool enabled) {
|
|||
UpdateDepthState();
|
||||
}
|
||||
|
||||
void Gfx_SetAlphaTest(cc_bool enabled) {
|
||||
static void SetAlphaTest(cc_bool enabled) {
|
||||
rsxSetAlphaTestEnable(context, enabled);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -163,7 +163,7 @@ void Gfx_BindTexture(GfxResourceID texId) {
|
|||
*#########################################################################################################################*/
|
||||
static PackedCol gfx_clearColor;
|
||||
void Gfx_SetFaceCulling(cc_bool enabled) { GU_Toggle(GU_CULL_FACE); }
|
||||
void Gfx_SetAlphaBlending(cc_bool enabled) { GU_Toggle(GU_BLEND); }
|
||||
static void SetAlphaBlend(cc_bool enabled) { GU_Toggle(GU_BLEND); }
|
||||
void Gfx_SetAlphaArgBlend(cc_bool enabled) { }
|
||||
|
||||
void Gfx_ClearColor(PackedCol color) {
|
||||
|
|
@ -377,7 +377,7 @@ void Gfx_SetFogMode(FogFunc func) {
|
|||
/* TODO: Implemen fake exp/exp2 fog */
|
||||
}
|
||||
|
||||
void Gfx_SetAlphaTest(cc_bool enabled) { GU_Toggle(GU_ALPHA_TEST); }
|
||||
static void SetAlphaTest(cc_bool enabled) { GU_Toggle(GU_ALPHA_TEST); }
|
||||
|
||||
void Gfx_DepthOnlyRendering(cc_bool depthOnly) {
|
||||
cc_bool enabled = !depthOnly;
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@
|
|||
|
||||
// TODO track last frame used on
|
||||
static cc_bool gfx_depthOnly;
|
||||
static cc_bool gfx_alphaTesting, gfx_alphaBlending;
|
||||
static int frontBufferIndex, backBufferIndex;
|
||||
// Inspired from
|
||||
// https://github.com/xerpi/gxmfun/blob/master/source/main.c
|
||||
|
|
@ -242,11 +241,11 @@ static void FP_SwitchActive(void) {
|
|||
// [normal rendering, blend rendering, no rendering]
|
||||
if (gfx_depthOnly) {
|
||||
index += 2;
|
||||
} else if (gfx_alphaBlending) {
|
||||
} else if (gfx_alphaBlend) {
|
||||
index += 1;
|
||||
}
|
||||
|
||||
if (gfx_alphaTesting) index += 2 * 3;
|
||||
if (gfx_alphaTest) index += 2 * 3;
|
||||
|
||||
FragmentProgram* FP = &FP_list[index];
|
||||
if (FP == FP_Active) return;
|
||||
|
|
@ -964,13 +963,11 @@ void Gfx_SetFogMode(FogFunc func) {
|
|||
// TODO
|
||||
}
|
||||
|
||||
void Gfx_SetAlphaTest(cc_bool enabled) {
|
||||
gfx_alphaTesting = enabled;
|
||||
static void SetAlphaTest(cc_bool enabled) {
|
||||
FP_SwitchActive();
|
||||
}
|
||||
|
||||
void Gfx_SetAlphaBlending(cc_bool enabled) {
|
||||
gfx_alphaBlending = enabled;
|
||||
static void SetAlphaBlend(cc_bool enabled) {
|
||||
FP_SwitchActive();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -143,10 +143,10 @@ void Gfx_SetFaceCulling(cc_bool enabled) {
|
|||
// TODO
|
||||
}
|
||||
|
||||
void Gfx_SetAlphaTest(cc_bool enabled) {
|
||||
static void SetAlphaTest(cc_bool enabled) {
|
||||
}
|
||||
|
||||
void Gfx_SetAlphaBlending(cc_bool enabled) {
|
||||
static void SetAlphaBlend(cc_bool enabled) {
|
||||
}
|
||||
|
||||
void Gfx_SetAlphaArgBlend(cc_bool enabled) { }
|
||||
|
|
|
|||
|
|
@ -10,9 +10,6 @@ static struct Bitmap fb_bmp;
|
|||
static float vp_hwidth, vp_hheight;
|
||||
static int sc_maxX, sc_maxY;
|
||||
|
||||
static cc_bool alphaBlending;
|
||||
static cc_bool alphaTest;
|
||||
|
||||
static PackedCol* colorBuffer;
|
||||
static PackedCol clearColor;
|
||||
static cc_bool colWrite = true;
|
||||
|
|
@ -115,12 +112,12 @@ void Gfx_SetFaceCulling(cc_bool enabled) {
|
|||
faceCulling = enabled;
|
||||
}
|
||||
|
||||
void Gfx_SetAlphaTest(cc_bool enabled) {
|
||||
alphaTest = enabled;
|
||||
static void SetAlphaTest(cc_bool enabled) {
|
||||
/* Uses value from Gfx_SetAlphaTest */
|
||||
}
|
||||
|
||||
void Gfx_SetAlphaBlending(cc_bool enabled) {
|
||||
alphaBlending = enabled;
|
||||
static void SetAlphaBlend(cc_bool enabled) {
|
||||
/* Uses value from Gfx_SetAlphaBlending */
|
||||
}
|
||||
|
||||
void Gfx_SetAlphaArgBlend(cc_bool enabled) { }
|
||||
|
|
@ -391,7 +388,7 @@ static void DrawTriangle(Vector4 frag1, Vector4 frag2, Vector4 frag3,
|
|||
int B = PackedCol_B(fragColor);
|
||||
int A = PackedCol_A(fragColor);
|
||||
|
||||
if (alphaBlending) {
|
||||
if (gfx_alphaBlend) {
|
||||
PackedCol dst = colorBuffer[index];
|
||||
int dstR = BitmapCol_R(dst);
|
||||
int dstG = BitmapCol_G(dst);
|
||||
|
|
@ -401,7 +398,7 @@ static void DrawTriangle(Vector4 frag1, Vector4 frag2, Vector4 frag3,
|
|||
G = (G * A) / 255 + (dstG * (255 - A)) / 255;
|
||||
B = (B * A) / 255 + (dstB * (255 - A)) / 255;
|
||||
}
|
||||
if (alphaTest && A < 0x80) continue;
|
||||
if (gfx_alphaTest && A < 0x80) continue;
|
||||
|
||||
if (depthWrite) depthBuffer[index] = z;
|
||||
colorBuffer[index] = BitmapCol_Make(R, G, B, 0xFF);
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@ static GfxResourceID white_square;
|
|||
static WHBGfxShaderGroup* group;
|
||||
|
||||
static void InitGfx(void) {
|
||||
WHBGfxInit();
|
||||
GX2InitSampler(&sampler, GX2_TEX_CLAMP_MODE_WRAP, GX2_TEX_XY_FILTER_MODE_POINT);
|
||||
|
||||
WHBGfxLoadGFDShaderGroup(&colorShader, 0, coloured_gsh);
|
||||
|
|
@ -86,7 +85,9 @@ static void Gfx_RestoreState(void) {
|
|||
static GX2Texture* pendingTex;
|
||||
|
||||
static GfxResourceID Gfx_AllocTexture(struct Bitmap* bmp, int rowWidth, cc_uint8 flags, cc_bool mipmaps) {
|
||||
GX2Texture* tex = Mem_AllocCleared(1, sizeof(GX2Texture), "GX2 texture");
|
||||
GX2Texture* tex = Mem_TryAllocCleared(1, sizeof(GX2Texture));
|
||||
if (!tex) return NULL;
|
||||
|
||||
// TODO handle out of memory better
|
||||
int width = bmp->width, height = bmp->height;
|
||||
tex->surface.width = width;
|
||||
|
|
@ -99,8 +100,9 @@ static GfxResourceID Gfx_AllocTexture(struct Bitmap* bmp, int rowWidth, cc_uint8
|
|||
tex->compMap = GX2_COMP_MAP(GX2_SQ_SEL_R, GX2_SQ_SEL_G, GX2_SQ_SEL_B, GX2_SQ_SEL_A);
|
||||
GX2CalcSurfaceSizeAndAlignment(&tex->surface);
|
||||
GX2InitTextureRegs(tex);
|
||||
|
||||
tex->surface.image = MEMAllocFromDefaultHeapEx(tex->surface.imageSize, tex->surface.alignment);
|
||||
// TODO check result
|
||||
if (!tex->surface.image) { Mem_Free(tex); return NULL; }
|
||||
|
||||
CopyTextureData(tex->surface.image, tex->surface.pitch << 2, bmp, rowWidth << 2);
|
||||
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_TEXTURE, tex->surface.image, tex->surface.imageSize);
|
||||
|
|
@ -175,11 +177,11 @@ void Gfx_SetFogMode(FogFunc func) {
|
|||
// TODO
|
||||
}
|
||||
|
||||
void Gfx_SetAlphaTest(cc_bool enabled) {
|
||||
static void SetAlphaTest(cc_bool enabled) {
|
||||
GX2SetAlphaTest(enabled, GX2_COMPARE_FUNC_GEQUAL, 0.5f);
|
||||
}
|
||||
|
||||
void Gfx_SetAlphaBlending(cc_bool enabled) {
|
||||
static void SetAlphaBlend(cc_bool enabled) {
|
||||
GX2SetBlendControl(GX2_RENDER_TARGET_0,
|
||||
GX2_BLEND_MODE_SRC_ALPHA, GX2_BLEND_MODE_INV_SRC_ALPHA, GX2_BLEND_COMBINE_MODE_ADD,
|
||||
true,
|
||||
|
|
@ -431,12 +433,18 @@ void Gfx_ClearBuffers(GfxBuffers buffers) {
|
|||
}
|
||||
}
|
||||
|
||||
static int drc_ticks;
|
||||
void Gfx_EndFrame(void) {
|
||||
GX2ColorBuffer* buf;
|
||||
|
||||
buf = WHBGfxGetTVColourBuffer();
|
||||
GX2CopyColorBufferToScanBuffer(buf, GX2_SCAN_TARGET_TV);
|
||||
|
||||
GX2ContextState* state = WHBGfxGetDRCContextState();
|
||||
GX2SetContextState(state);
|
||||
drc_ticks = (drc_ticks + 1) % 200;
|
||||
buf = WHBGfxGetDRCColourBuffer();
|
||||
GX2ClearColor(buf, drc_ticks / 200.0f, drc_ticks / 200.0f, drc_ticks / 200.0f, 1.0f);
|
||||
GX2CopyColorBufferToScanBuffer(buf, GX2_SCAN_TARGET_DRC);
|
||||
|
||||
GX2SwapScanBuffers();
|
||||
|
|
@ -459,7 +467,10 @@ void Gfx_OnWindowResize(void) {
|
|||
|
||||
}
|
||||
|
||||
void Gfx_SetViewport(int x, int y, int w, int h) { }
|
||||
void Gfx_SetViewport(int x, int y, int w, int h) {
|
||||
GX2SetViewport(x, y, w, h, 0.0f, 1.0f);
|
||||
GX2SetScissor( x, y, w, h);
|
||||
}
|
||||
|
||||
void Gfx_3DS_SetRenderScreen1(enum Screen3DS screen) {
|
||||
GX2ContextState* tv_state = WHBGfxGetTVContextState();
|
||||
|
|
|
|||
|
|
@ -299,13 +299,13 @@ void Gfx_SetFaceCulling(cc_bool enabled) {
|
|||
|
||||
void Gfx_SetAlphaArgBlend(cc_bool enabled) { }
|
||||
|
||||
void Gfx_SetAlphaBlending(cc_bool enabled) {
|
||||
static void SetAlphaBlend(cc_bool enabled) {
|
||||
uint32_t* p = pb_begin();
|
||||
p = pb_push1(p, NV097_SET_BLEND_ENABLE, enabled);
|
||||
pb_end(p);
|
||||
}
|
||||
|
||||
void Gfx_SetAlphaTest(cc_bool enabled) {
|
||||
static void SetAlphaTest(cc_bool enabled) {
|
||||
uint32_t* p = pb_begin();
|
||||
p = pb_push1(p, NV097_SET_ALPHA_TEST_ENABLE, enabled);
|
||||
pb_end(p);
|
||||
|
|
@ -396,7 +396,6 @@ void Gfx_EndFrame(void) {
|
|||
*----------------------------------------------------------Buffers--------------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
static cc_uint8* gfx_vertices;
|
||||
static cc_uint16* gfx_indices;
|
||||
|
||||
static void* AllocBuffer(int count, int elemSize) {
|
||||
return MmAllocateContiguousMemoryEx(count * elemSize, 0, MAX_RAM_ADDR, 16, PAGE_WRITECOMBINE | PAGE_READWRITE);
|
||||
|
|
@ -410,16 +409,12 @@ static void FreeBuffer(GfxResourceID* buffer) {
|
|||
|
||||
|
||||
GfxResourceID Gfx_CreateIb2(int count, Gfx_FillIBFunc fillFunc, void* obj) {
|
||||
void* ib = AllocBuffer(count, sizeof(cc_uint16));
|
||||
if (!ib) Logger_Abort("Failed to allocate memory for index buffer");
|
||||
|
||||
fillFunc(ib, count, obj);
|
||||
return ib;
|
||||
return (void*)1;
|
||||
}
|
||||
|
||||
void Gfx_BindIb(GfxResourceID ib) { gfx_indices = ib; }
|
||||
void Gfx_BindIb(GfxResourceID ib) { }
|
||||
|
||||
void Gfx_DeleteIb(GfxResourceID* ib) { FreeBuffer(ib); }
|
||||
void Gfx_DeleteIb(GfxResourceID* ib) { }
|
||||
|
||||
|
||||
static GfxResourceID Gfx_AllocStaticVb(VertexFormat fmt, int count) {
|
||||
|
|
@ -476,6 +471,18 @@ void Gfx_SetFog(cc_bool enabled) {
|
|||
}
|
||||
|
||||
void Gfx_SetFogCol(PackedCol color) {
|
||||
int R = PackedCol_R(color);
|
||||
int G = PackedCol_G(color);
|
||||
int B = PackedCol_B(color);
|
||||
int A = PackedCol_A(color);
|
||||
|
||||
uint32_t* p = pb_begin();
|
||||
p = pb_push1(p, NV097_SET_FOG_COLOR,
|
||||
MASK(NV097_SET_FOG_COLOR_RED, R) |
|
||||
MASK(NV097_SET_FOG_COLOR_GREEN, G) |
|
||||
MASK(NV097_SET_FOG_COLOR_BLUE, B) |
|
||||
MASK(NV097_SET_FOG_COLOR_ALPHA, A));
|
||||
pb_end(p);
|
||||
}
|
||||
|
||||
void Gfx_SetFogDensity(float value) {
|
||||
|
|
@ -536,8 +543,8 @@ void Gfx_CalcPerspectiveMatrix(struct Matrix* matrix, float fov, float aspect, f
|
|||
|
||||
void Gfx_OnWindowResize(void) { }
|
||||
|
||||
static struct Vec4 vp_offset = { 320, -240, 8388608, 1 };
|
||||
static struct Vec4 vp_scale = { 320, 240, 8388608, 1 };
|
||||
static struct Vec4 vp_scale = { 320, -240, 8388608, 1 };
|
||||
static struct Vec4 vp_offset = { 320, 240, 8388608, 1 };
|
||||
static struct Matrix _view, _proj, _mvp;
|
||||
|
||||
static void UpdateVSConstants(void) {
|
||||
|
|
@ -655,10 +662,10 @@ static void DrawArrays(int mode, int start, int count) {
|
|||
uint32_t *p = pb_begin();
|
||||
p = pb_push1(p, NV097_SET_BEGIN_END, mode);
|
||||
|
||||
// NV097_DRAW_ARRAYS_COUNT is an 8 bit mask, so must be < 256
|
||||
// NV097_DRAW_ARRAYS_COUNT is an 8 bit mask, so must be <= 256
|
||||
while (count > 0)
|
||||
{
|
||||
int batch_count = min(count, 64); // TODO increase?
|
||||
int batch_count = min(count, 256);
|
||||
|
||||
p = pb_push1(p, 0x40000000 | NV097_DRAW_ARRAYS,
|
||||
MASK(NV097_DRAW_ARRAYS_COUNT, (batch_count-1)) |
|
||||
|
|
@ -676,9 +683,7 @@ void Gfx_DrawVb_Lines(int verticesCount) {
|
|||
DrawArrays(NV097_SET_BEGIN_END_OP_LINES, 0, verticesCount);
|
||||
}
|
||||
|
||||
#define MAX_BATCH 120
|
||||
static void DrawIndexedVertices(int verticesCount, int startVertex) {
|
||||
// TODO switch to indexed rendering
|
||||
DrawArrays(NV097_SET_BEGIN_END_OP_QUADS, startVertex, verticesCount);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ static void Gfx_FreeState(void) {
|
|||
static void Gfx_RestoreState(void) {
|
||||
InitDefaultResources();
|
||||
Gfx_SetFaceCulling(false);
|
||||
Gfx_SetAlphaBlending(false);
|
||||
SetAlphaBlend(false);
|
||||
|
||||
Xe_SetAlphaFunc(xe, XE_CMP_GREATER);
|
||||
Xe_SetAlphaRef(xe, 0.5f);
|
||||
|
|
@ -155,11 +155,11 @@ void Gfx_SetFogMode(FogFunc func) {
|
|||
// TODO
|
||||
}
|
||||
|
||||
void Gfx_SetAlphaTest(cc_bool enabled) {
|
||||
static void SetAlphaTest(cc_bool enabled) {
|
||||
Xe_SetAlphaTestEnable(xe, enabled);
|
||||
}
|
||||
|
||||
void Gfx_SetAlphaBlending(cc_bool enabled) {
|
||||
static void SetAlphaBlend(cc_bool enabled) {
|
||||
if (enabled) {
|
||||
Xe_SetBlendControl(xe,
|
||||
XE_BLEND_SRCALPHA, XE_BLENDOP_ADD, XE_BLEND_INVSRCALPHA,
|
||||
|
|
|
|||
|
|
@ -249,7 +249,6 @@ void Gui_Remove(struct Screen* s) {
|
|||
|
||||
void Gui_Add(struct Screen* s, int priority) {
|
||||
struct Screen* existing;
|
||||
int i;
|
||||
Gui_RemoveCore(s);
|
||||
|
||||
existing = Gui_GetScreen(priority);
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ CC_VAR extern struct _GuiData {
|
|||
float RawHotbarScale, RawChatScale, RawInventoryScale, RawCrosshairScale;
|
||||
GfxResourceID GuiTex, GuiClassicTex, IconsTex, TouchTex;
|
||||
int DefaultLines;
|
||||
int __unused;
|
||||
int _unused;
|
||||
float RawTouchScale;
|
||||
/* The highest priority screen that has grabbed input. */
|
||||
struct Screen* InputGrab;
|
||||
|
|
|
|||
|
|
@ -43,7 +43,6 @@ static void HeldBlockRenderer_RenderModel(void) {
|
|||
SetHeldModel(model);
|
||||
Vec3_Set(held_entity.ModelScale, 1.0f,1.0f,1.0f);
|
||||
|
||||
Gfx_SetAlphaTest(true);
|
||||
Model_RenderArm(model, &held_entity);
|
||||
Gfx_SetAlphaTest(false);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -41,6 +41,14 @@ static void Http_ParseCookie(struct HttpRequest* req, const cc_string* value) {
|
|||
EntryList_Set(req->cookies, &name, &data, '=');
|
||||
}
|
||||
|
||||
static void Http_ParseContentLength(struct HttpRequest* req, const cc_string* value) {
|
||||
int contentLen = 0;
|
||||
Convert_ParseInt(value, &contentLen);
|
||||
|
||||
if (contentLen <= 0) return;
|
||||
req->contentLength = contentLen;
|
||||
}
|
||||
|
||||
/* Parses a HTTP header */
|
||||
static void Http_ParseHeader(struct HttpRequest* req, const cc_string* line) {
|
||||
static const cc_string httpVersion = String_FromConst("HTTP");
|
||||
|
|
@ -58,11 +66,11 @@ static void Http_ParseHeader(struct HttpRequest* req, const cc_string* line) {
|
|||
if (String_CaselessEqualsConst(&name, "ETag")) {
|
||||
String_CopyToRawArray(req->etag, &value);
|
||||
} else if (String_CaselessEqualsConst(&name, "Content-Length")) {
|
||||
Convert_ParseInt(&value, &req->contentLength);
|
||||
Http_ParseContentLength(req, &value);
|
||||
} else if (String_CaselessEqualsConst(&name, "X-Dropbox-Content-Length")) {
|
||||
/* dropbox stopped returning Content-Length header since switching to chunked transfer */
|
||||
/* https://www.dropboxforum.com/t5/Discuss-Dropbox-Developer-API/Dropbox-media-can-t-be-access-by-azure-blob/td-p/575458 */
|
||||
Convert_ParseInt(&value, &req->contentLength);
|
||||
Http_ParseContentLength(req, &value);
|
||||
} else if (String_CaselessEqualsConst(&name, "Last-Modified")) {
|
||||
String_CopyToRawArray(req->lastModified, &value);
|
||||
} else if (req->cookies && String_CaselessEqualsConst(&name, "Set-Cookie")) {
|
||||
|
|
@ -496,13 +504,15 @@ static cc_result HttpConnection_Open(struct HttpConnection* conn, const struct H
|
|||
static cc_result HttpConnection_Read(struct HttpConnection* conn, cc_uint8* data, cc_uint32 count, cc_uint32* read) {
|
||||
if (conn->sslCtx)
|
||||
return SSL_Read(conn->sslCtx, data, count, read);
|
||||
|
||||
return Socket_Read(conn->socket, data, count, read);
|
||||
}
|
||||
|
||||
static cc_result HttpConnection_Write(struct HttpConnection* conn, const cc_uint8* data, cc_uint32 count, cc_uint32* wrote) {
|
||||
static cc_result HttpConnection_Write(struct HttpConnection* conn, const cc_uint8* data, cc_uint32 count) {
|
||||
if (conn->sslCtx)
|
||||
return SSL_Write(conn->sslCtx, data, count, wrote);
|
||||
return Socket_Write(conn->socket, data, count, wrote);
|
||||
return SSL_WriteAll(conn->sslCtx, data, count);
|
||||
|
||||
return Socket_WriteAll(conn->socket, data, count);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -556,6 +566,7 @@ static cc_result ConnectionPool_Open(struct HttpConnection** conn, const struct
|
|||
*--------------------------------------------------------HttpClient-------------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
enum HTTP_RESPONSE_STATE {
|
||||
HTTP_RESPONSE_STATE_INITIAL,
|
||||
HTTP_RESPONSE_STATE_HEADER,
|
||||
HTTP_RESPONSE_STATE_DATA,
|
||||
HTTP_RESPONSE_STATE_CHUNK_HEADER,
|
||||
|
|
@ -581,7 +592,7 @@ struct HttpClientState {
|
|||
};
|
||||
|
||||
static void HttpClientState_Reset(struct HttpClientState* state) {
|
||||
state->state = HTTP_RESPONSE_STATE_HEADER;
|
||||
state->state = HTTP_RESPONSE_STATE_INITIAL;
|
||||
state->chunked = 0;
|
||||
state->dataLeft = 0;
|
||||
state->autoClose = false;
|
||||
|
|
@ -621,15 +632,13 @@ static void HttpClient_Serialise(struct HttpClientState* state) {
|
|||
static cc_result HttpClient_SendRequest(struct HttpClientState* state) {
|
||||
char inputBuffer[16384];
|
||||
cc_string inputMsg;
|
||||
cc_uint32 wrote;
|
||||
|
||||
String_InitArray(inputMsg, inputBuffer);
|
||||
state->req->meta = &inputMsg;
|
||||
state->req->progress = HTTP_PROGRESS_FETCHING_DATA;
|
||||
HttpClient_Serialise(state);
|
||||
|
||||
/* TODO check that wrote is >= inputMsg.length */
|
||||
return HttpConnection_Write(state->conn, (cc_uint8*)inputBuffer, inputMsg.length, &wrote);
|
||||
return HttpConnection_Write(state->conn, (cc_uint8*)inputBuffer, inputMsg.length);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -705,6 +714,9 @@ static cc_result HttpClient_Process(struct HttpClientState* state, char* buffer,
|
|||
|
||||
while (offset < total) {
|
||||
switch (state->state) {
|
||||
case HTTP_RESPONSE_STATE_INITIAL:
|
||||
state->state = HTTP_RESPONSE_STATE_HEADER;
|
||||
break;
|
||||
|
||||
case HTTP_RESPONSE_STATE_HEADER:
|
||||
{
|
||||
|
|
@ -833,9 +845,12 @@ static cc_result HttpClient_ParseResponse(struct HttpClientState* state) {
|
|||
{
|
||||
dst = state->dataLeft > INPUT_BUFFER_LEN ? (req->data + req->size) : buffer;
|
||||
res = HttpConnection_Read(state->conn, dst, INPUT_BUFFER_LEN, &total);
|
||||
|
||||
if (res) return res;
|
||||
if (total == 0) return ERR_END_OF_STREAM;
|
||||
|
||||
if (total == 0) {
|
||||
Platform_Log1("Http read unexpectedly returned 0 in state %i", &state->state);
|
||||
return state->state == HTTP_RESPONSE_STATE_INITIAL ? HTTP_ERR_NO_RESPONSE : ERR_END_OF_STREAM;
|
||||
}
|
||||
|
||||
if (dst != buffer) {
|
||||
/* When there is more than INPUT_BUFFER_LEN bytes of unread data/content, */
|
||||
|
|
@ -912,6 +927,11 @@ static cc_result HttpBackend_Do(struct HttpRequest* req, cc_string* urlStr) {
|
|||
res = HttpBackend_PerformRequest(&state);
|
||||
retried = true;
|
||||
}
|
||||
if (res == HTTP_ERR_NO_RESPONSE && !retried) {
|
||||
Platform_LogConst("Resetting connection due to empty response..");
|
||||
res = HttpBackend_PerformRequest(&state);
|
||||
retried = true;
|
||||
}
|
||||
|
||||
if (res || !HttpClient_IsRedirect(req)) break;
|
||||
if (redirects >= 20) return HTTP_ERR_REDIRECTS;
|
||||
|
|
@ -1278,7 +1298,7 @@ static void PerformRequest(struct HttpRequest* req, cc_string* url) {
|
|||
end = Stopwatch_Measure();
|
||||
|
||||
elapsed = Stopwatch_ElapsedMS(beg, end);
|
||||
Platform_Log4("HTTP: result %i (http %i) in %i ms (%i bytes)",
|
||||
Platform_Log4("HTTP: result %e (http %i) in %i ms (%i bytes)",
|
||||
&req->result, &req->statusCode, &elapsed, &req->size);
|
||||
|
||||
Http_FinishRequest(req);
|
||||
|
|
|
|||
50
src/Input.c
50
src/Input.c
|
|
@ -216,7 +216,8 @@ static const char* const storageNames[INPUT_COUNT] = {
|
|||
"Keypad5", "Keypad6", "Keypad7", "Keypad8", "Keypad9",
|
||||
"KeypadDivide", "KeypadMultiply", "KeypadSubtract",
|
||||
"KeypadAdd", "KeypadDecimal", "KeypadEnter",
|
||||
"XButton1", "XButton2", "LeftMouse", "RightMouse", "MiddleMouse",
|
||||
"XButton1", "XButton2", "XButton3", "XButton4", "XButton5", "XButton6",
|
||||
"LeftMouse", "RightMouse", "MiddleMouse",
|
||||
Pad_Names
|
||||
};
|
||||
|
||||
|
|
@ -239,7 +240,8 @@ const char* const Input_DisplayNames[INPUT_COUNT] = {
|
|||
"NUMPAD5", "NUMPAD6", "NUMPAD7", "NUMPAD8", "NUMPAD9",
|
||||
"DIVIDE", "MULTIPLY", "SUBTRACT",
|
||||
"ADD", "DECIMAL", "NUMPADENTER",
|
||||
"XBUTTON1", "XBUTTON2", "LMOUSE", "RMOUSE", "MMOUSE",
|
||||
"XBUTTON1", "XBUTTON2", "XBUTTON3", "XBUTTON4", "XBUTTON5", "XBUTTON6",
|
||||
"LMOUSE", "RMOUSE", "MMOUSE",
|
||||
Pad_Names
|
||||
};
|
||||
|
||||
|
|
@ -291,6 +293,15 @@ void Input_Clear(void) {
|
|||
ClearTouches();
|
||||
}
|
||||
|
||||
int Input_CalcDelta(int key, int horDelta, int verDelta) {
|
||||
if (Input_IsLeftButton(key) || key == CCKEY_KP4) return -horDelta;
|
||||
if (Input_IsRightButton(key) || key == CCKEY_KP6) return +horDelta;
|
||||
if (Input_IsUpButton(key) || key == CCKEY_KP8) return -verDelta;
|
||||
if (Input_IsDownButton(key) || key == CCKEY_KP2) return +verDelta;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*########################################################################################################################*
|
||||
*----------------------------------------------------------Mouse----------------------------------------------------------*
|
||||
|
|
@ -418,38 +429,49 @@ static void KeyBind_Init(void) {
|
|||
*---------------------------------------------------------Gamepad---------------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
#define GAMEPAD_BEG_BTN CCPAD_A
|
||||
#define GAMEPAD_BTN_COUNT (INPUT_COUNT - GAMEPAD_BEG_BTN)
|
||||
|
||||
int Gamepad_AxisBehaviour[2] = { AXIS_BEHAVIOUR_MOVEMENT, AXIS_BEHAVIOUR_CAMERA };
|
||||
int Gamepad_AxisSensitivity[2] = { AXIS_SENSI_NORMAL, AXIS_SENSI_NORMAL };
|
||||
static const float axis_sensiFactor[] = { 0.25f, 0.5f, 1.0f, 2.0f, 4.0f };
|
||||
|
||||
struct GamepadState {
|
||||
float axisX[2], axisY[2];
|
||||
/*cc_bool pressed[INPUT_COUNT - GAMEPAD_BEG_BTN];*/
|
||||
float holdtime[INPUT_COUNT - GAMEPAD_BEG_BTN];
|
||||
cc_bool pressed[GAMEPAD_BTN_COUNT];
|
||||
float holdtime[GAMEPAD_BTN_COUNT];
|
||||
};
|
||||
static struct GamepadState gamepads[INPUT_MAX_GAMEPADS];
|
||||
|
||||
static void Gamepad_Update(struct GamepadState* pad, float delta) {
|
||||
int btn;
|
||||
for (btn = GAMEPAD_BEG_BTN; btn < INPUT_COUNT; btn++)
|
||||
for (btn = 0; btn < GAMEPAD_BTN_COUNT; btn++)
|
||||
{
|
||||
if (!Input.Pressed[btn]) continue;
|
||||
pad->holdtime[btn - GAMEPAD_BEG_BTN] += delta;
|
||||
if (pad->holdtime[btn - GAMEPAD_BEG_BTN] < 1.0f) continue;
|
||||
if (!pad->pressed[btn]) continue;
|
||||
pad->holdtime[btn] += delta;
|
||||
if (pad->holdtime[btn] < 1.0f) continue;
|
||||
|
||||
/* Held for over a second, trigger a fake press */
|
||||
pad->holdtime[btn - GAMEPAD_BEG_BTN] = 0;
|
||||
Input_SetPressed(btn);
|
||||
pad->holdtime[btn] = 0;
|
||||
Input_SetPressed(btn + GAMEPAD_BEG_BTN);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Gamepad_SetButton(int port, int btn, int pressed) {
|
||||
struct GamepadState* pad = &gamepads[port];
|
||||
/* Reset hold tracking time */
|
||||
if (pressed && !Input.Pressed[btn]) pad->holdtime[btn - GAMEPAD_BEG_BTN] = 0;
|
||||
int i;
|
||||
btn -= GAMEPAD_BEG_BTN;
|
||||
|
||||
Input_SetNonRepeatable(btn, pressed);
|
||||
/* Reset hold tracking time */
|
||||
if (pressed && !pad->pressed[btn]) pad->holdtime[btn] = 0;
|
||||
pad->pressed[btn] = pressed != 0;;
|
||||
|
||||
/* Set pressed if button pressed on any gamepad, to avoid constant flip flopping */
|
||||
/* between pressed and non-pressed when multiple controllers are plugged in */
|
||||
for (i = 0; i < INPUT_MAX_GAMEPADS; i++)
|
||||
pressed |= gamepads[i].pressed[btn];
|
||||
|
||||
Input_SetNonRepeatable(btn + GAMEPAD_BEG_BTN, pressed);
|
||||
}
|
||||
|
||||
void Gamepad_SetAxis(int port, int axis, float x, float y, float delta) {
|
||||
|
|
@ -480,7 +502,7 @@ static void PlayerInputPad(int port, int axis, struct LocalPlayer* p, float* xMo
|
|||
y = gamepads[port].axisY[axis];
|
||||
|
||||
if (x != 0 || y != 0) {
|
||||
angle = Math_Atan2(x, y);
|
||||
angle = Math_Atan2f(x, y);
|
||||
*xMoving = Math_CosF(angle);
|
||||
*zMoving = Math_SinF(angle);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,7 +43,8 @@ enum InputButtons {
|
|||
CCKEY_KP_PLUS, CCKEY_KP_DECIMAL, CCKEY_KP_ENTER,
|
||||
|
||||
/* NOTE: RMOUSE must be before MMOUSE for PlayerClick compatibility */
|
||||
CCMOUSE_X1, CCMOUSE_X2, CCMOUSE_L, CCMOUSE_R, CCMOUSE_M,
|
||||
CCMOUSE_X1, CCMOUSE_X2, CCMOUSE_X3, CCMOUSE_X4, CCMOUSE_X5, CCMOUSE_X6,
|
||||
CCMOUSE_L, CCMOUSE_R, CCMOUSE_M,
|
||||
|
||||
CCPAD_A, CCPAD_B, CCPAD_X, CCPAD_Y, CCPAD_L, CCPAD_R, CCPAD_Z,
|
||||
CCPAD_LEFT, CCPAD_RIGHT, CCPAD_UP, CCPAD_DOWN,
|
||||
|
|
@ -106,6 +107,7 @@ void Input_Clear(void);
|
|||
#else
|
||||
#define Input_IsActionPressed() Input_IsCtrlPressed()
|
||||
#endif
|
||||
int Input_CalcDelta(int btn, int horDelta, int verDelta);
|
||||
|
||||
|
||||
#ifdef CC_BUILD_TOUCH
|
||||
|
|
|
|||
|
|
@ -334,6 +334,7 @@ static void OnPointerDown(void* obj, int idx) {
|
|||
struct LScreen* s = Launcher_Active;
|
||||
struct LWidget* over;
|
||||
struct LWidget* prev;
|
||||
if (Window_Main.SoftKeyboardFocus) return;
|
||||
|
||||
if (!s) return;
|
||||
over = GetWidgetAt(s, idx);
|
||||
|
|
@ -347,6 +348,7 @@ static void OnPointerUp(void* obj, int idx) {
|
|||
struct LScreen* s = Launcher_Active;
|
||||
struct LWidget* over;
|
||||
struct LWidget* prev;
|
||||
if (Window_Main.SoftKeyboardFocus) return;
|
||||
|
||||
if (!s) return;
|
||||
over = GetWidgetAt(s, idx);
|
||||
|
|
@ -367,6 +369,7 @@ static void OnPointerMove(void* obj, int idx) {
|
|||
struct LWidget* over;
|
||||
struct LWidget* prev;
|
||||
cc_bool overSame;
|
||||
if (Window_Main.SoftKeyboardFocus) return;
|
||||
|
||||
if (!s) return;
|
||||
over = GetWidgetAt(s, idx);
|
||||
|
|
|
|||
|
|
@ -380,14 +380,9 @@ static void ColoursScreen_MouseWheel(struct LScreen* s_, float delta) {
|
|||
}
|
||||
|
||||
static void ColoursScreen_KeyDown(struct LScreen* s, int key, cc_bool was) {
|
||||
if (Input_IsLeftButton(key)) {
|
||||
ColoursScreen_AdjustSelected(s, -1);
|
||||
} else if (Input_IsRightButton(key)) {
|
||||
ColoursScreen_AdjustSelected(s, +1);
|
||||
} else if (Input_IsUpButton(key)) {
|
||||
ColoursScreen_AdjustSelected(s, +10);
|
||||
} else if (Input_IsDownButton(key)) {
|
||||
ColoursScreen_AdjustSelected(s, -10);
|
||||
int delta = Input_CalcDelta(key, 1, 10);
|
||||
if (delta) {
|
||||
ColoursScreen_AdjustSelected(s, delta);
|
||||
} else {
|
||||
LScreen_KeyDown(s, key, was);
|
||||
}
|
||||
|
|
@ -886,6 +881,12 @@ static void MainScreen_ApplyUpdateLabel(struct MainScreen* s) {
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef CC_BUILD_CONSOLE
|
||||
static void MainScreen_ExitApp(void* w) {
|
||||
Window_Main.Exists = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void MainScreen_Activated(struct LScreen* s_) {
|
||||
struct MainScreen* s = (struct MainScreen*)s_;
|
||||
|
||||
|
|
@ -909,8 +910,6 @@ static void MainScreen_Activated(struct LScreen* s_) {
|
|||
SwitchToSplitScreen, main_btnSplit);
|
||||
#endif
|
||||
|
||||
LLabel_Add(s, &s->lblUpdate, "&eChecking..",
|
||||
Updater_Supported ? main_lblUpdate_N : main_lblUpdate_H);
|
||||
if (Process_OpenSupported) {
|
||||
LButton_Add(s, &s->btnRegister, 100, 35, "Register",
|
||||
MainScreen_Register, main_btnRegister);
|
||||
|
|
@ -918,10 +917,19 @@ static void MainScreen_Activated(struct LScreen* s_) {
|
|||
|
||||
LButton_Add(s, &s->btnOptions, 100, 35, "Options",
|
||||
SwitchToSettings, main_btnOptions);
|
||||
|
||||
#ifdef CC_BUILD_CONSOLE
|
||||
LLabel_Add(s, &s->lblUpdate, "&eChecking..", main_lblUpdate_N);
|
||||
LButton_Add(s, &s->btnUpdates, 100, 35, "Exit",
|
||||
MainScreen_ExitApp, main_btnUpdates);
|
||||
#else
|
||||
LLabel_Add(s, &s->lblUpdate, "&eChecking..",
|
||||
Updater_Supported ? main_lblUpdate_N : main_lblUpdate_H);
|
||||
if (Updater_Supported) {
|
||||
LButton_Add(s, &s->btnUpdates, 100, 35, "Updates",
|
||||
SwitchToUpdates, main_btnUpdates);
|
||||
}
|
||||
#endif
|
||||
|
||||
s->btnResume.OnHover = MainScreen_ResumeHover;
|
||||
s->btnResume.OnUnhover = MainScreen_ResumeUnhover;
|
||||
|
|
|
|||
|
|
@ -65,8 +65,7 @@ void Launcher_DisplayHttpError(struct HttpRequest* req, const char* action, cc_s
|
|||
if (res) {
|
||||
/* Non HTTP error - this is not good */
|
||||
Http_LogError(action, req);
|
||||
String_Format2(dst, res >= 0x80000000 ? "&cError %h when %c" : "&cError %i when %c",
|
||||
&res, action);
|
||||
String_Format2(dst, "&cError %e when %c", &res, action);
|
||||
} else if (status != 200) {
|
||||
String_Format2(dst, "&c%i error when %c", &status, action);
|
||||
} else {
|
||||
|
|
@ -272,8 +271,9 @@ void Launcher_Run(void) {
|
|||
#endif
|
||||
|
||||
for (;;) {
|
||||
Window_ProcessEvents(10 / 1000.0);
|
||||
Window_ProcessGamepads(10 / 1000.0);
|
||||
Window_ProcessEvents(10 / 1000.0f);
|
||||
Window_ProcessGamepads(10 / 1000.0f);
|
||||
Gamepad_Tick(10 / 1000.0f);
|
||||
if (!Window_Main.Exists || Launcher_ShouldExit) break;
|
||||
|
||||
Launcher_Active->Tick(Launcher_Active);
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#include "Logger.h"
|
||||
#include "Event.h"
|
||||
#include "Game.h"
|
||||
#include "Options.h"
|
||||
struct _Lighting Lighting;
|
||||
#define Lighting_Pack(x, z) ((x) + World.Width * (z))
|
||||
|
||||
|
|
@ -66,6 +67,12 @@ static PackedCol ClassicLighting_Color(int x, int y, int z) {
|
|||
return y > ClassicLighting_GetLightHeight(x, z) ? Env.SunCol : Env.ShadowCol;
|
||||
}
|
||||
|
||||
static PackedCol SmoothLighting_Color(int x, int y, int z) {
|
||||
if (!World_Contains(x, y, z)) return Env.SunCol;
|
||||
if (Blocks.FullBright[World_GetBlock(x, y, z)]) return Env.SunCol;
|
||||
return y > ClassicLighting_GetLightHeight(x, z) ? Env.SunCol : Env.ShadowCol;
|
||||
}
|
||||
|
||||
static PackedCol ClassicLighting_Color_XSide(int x, int y, int z) {
|
||||
if (!World_Contains(x, y, z)) return Env.SunXSide;
|
||||
return y > ClassicLighting_GetLightHeight(x, z) ? Env.SunXSide : Env.ShadowXSide;
|
||||
|
|
@ -375,10 +382,13 @@ static void ClassicLighting_AllocState(void) {
|
|||
}
|
||||
|
||||
static void ClassicLighting_SetActive(void) {
|
||||
cc_bool smoothLighting = false;
|
||||
if (!Game_ClassicMode) smoothLighting = Options_GetBool(OPT_SMOOTH_LIGHTING, false);
|
||||
|
||||
Lighting.OnBlockChanged = ClassicLighting_OnBlockChanged;
|
||||
Lighting.Refresh = ClassicLighting_Refresh;
|
||||
Lighting.IsLit = ClassicLighting_IsLit;
|
||||
Lighting.Color = ClassicLighting_Color;
|
||||
Lighting.Color = smoothLighting ? SmoothLighting_Color : ClassicLighting_Color;
|
||||
Lighting.Color_XSide = ClassicLighting_Color_XSide;
|
||||
|
||||
Lighting.IsLit_Fast = ClassicLighting_IsLit_Fast;
|
||||
|
|
@ -398,6 +408,10 @@ static void ClassicLighting_SetActive(void) {
|
|||
*---------------------------------------------------Lighting component----------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
|
||||
void Lighting_ApplyActive() {
|
||||
ClassicLighting_SetActive();
|
||||
}
|
||||
|
||||
static void OnInit(void) { ClassicLighting_SetActive(); }
|
||||
static void OnReset(void) { Lighting.FreeState(); }
|
||||
static void OnNewMapLoaded(void) { Lighting.AllocState(); }
|
||||
|
|
|
|||
|
|
@ -49,4 +49,6 @@ CC_VAR extern struct _Lighting {
|
|||
PackedCol (*Color_XSide_Fast)(int x, int y, int z);
|
||||
PackedCol (*Color_ZSide_Fast)(int x, int y, int z);
|
||||
} Lighting;
|
||||
|
||||
void Lighting_ApplyActive(void);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -126,14 +126,12 @@ static void AppendErrorDesc(cc_string* msg, cc_result res, Logger_DescribeError
|
|||
}
|
||||
|
||||
void Logger_FormatWarn(cc_string* msg, cc_result res, const char* action, Logger_DescribeError describeErr) {
|
||||
String_Format2(msg, res < 20000 ? "Error %i when %c" : "Error %h when %c",
|
||||
&res, action);
|
||||
String_Format2(msg, "Error %e when %c", &res, action);
|
||||
AppendErrorDesc(msg, res, describeErr);
|
||||
}
|
||||
|
||||
void Logger_FormatWarn2(cc_string* msg, cc_result res, const char* action, const cc_string* path, Logger_DescribeError describeErr) {
|
||||
String_Format3(msg, res < 20000 ? "Error %i when %c '%s'" : "Error %h when %c '%s'",
|
||||
&res, action, path);
|
||||
String_Format3(msg, "Error %e when %c '%s'", &res, action, path);
|
||||
AppendErrorDesc(msg, res, describeErr);
|
||||
}
|
||||
|
||||
|
|
@ -508,7 +506,7 @@ static void PrintRegisters(cc_string* str, void* ctx) {
|
|||
#define REG_GET_PC() &r->Pc
|
||||
Dump_ARM32()
|
||||
#elif defined _M_ARM64
|
||||
#define REG_GNUM(num) &r->x[num]
|
||||
#define REG_GNUM(num) &r->X[num]
|
||||
#define REG_GET_FP() &r->Fp
|
||||
#define REG_GET_LR() &r->Lr
|
||||
#define REG_GET_SP() &r->Sp
|
||||
|
|
|
|||
26
src/Menus.c
26
src/Menus.c
|
|
@ -33,6 +33,7 @@
|
|||
#include "Utils.h"
|
||||
#include "Errors.h"
|
||||
#include "SystemFonts.h"
|
||||
#include "Lighting.h"
|
||||
|
||||
/* Describes a menu option button */
|
||||
struct MenuOptionDesc {
|
||||
|
|
@ -514,7 +515,7 @@ static void PauseScreen_CheckHacksAllowed(void* screen) {
|
|||
struct PauseScreen* s = (struct PauseScreen*)screen;
|
||||
if (Gui.ClassicMenu) return;
|
||||
|
||||
Widget_SetDisabled(&s->btns[4],
|
||||
Widget_SetDisabled(&s->btns[1],
|
||||
!Entities.CurPlayer->Hacks.CanAnyHacks); /* select texture pack */
|
||||
s->dirty = true;
|
||||
}
|
||||
|
|
@ -541,11 +542,11 @@ static void PauseScreen_Init(void* screen) {
|
|||
struct PauseScreen* s = (struct PauseScreen*)screen;
|
||||
static const struct SimpleButtonDesc descs[] = {
|
||||
{ -160, -50, "Options...", Menu_SwitchOptions },
|
||||
{ -160, 0, "Change texture pack...", Menu_SwitchTexPacks },
|
||||
{ -160, 50, "Hotkeys...", Menu_SwitchHotkeys },
|
||||
{ 160, -50, "Generate new level...", Menu_SwitchGenLevel },
|
||||
{ 160, 0, "Load level...", Menu_SwitchLoadLevel },
|
||||
{ 160, 50, "Save level...", Menu_SwitchSaveLevel },
|
||||
{ -160, 0, "Change texture pack...", Menu_SwitchTexPacks },
|
||||
{ -160, 50, "Hotkeys...", Menu_SwitchHotkeys }
|
||||
{ 160, 50, "Save level...", Menu_SwitchSaveLevel }
|
||||
};
|
||||
s->widgets = pause_widgets;
|
||||
s->numWidgets = 0;
|
||||
|
|
@ -559,8 +560,8 @@ static void PauseScreen_Init(void* screen) {
|
|||
s->maxVertices = Screen_CalcDefaultMaxVertices(s);
|
||||
|
||||
if (Server.IsSinglePlayer) return;
|
||||
s->btns[1].flags = WIDGET_FLAG_DISABLED;
|
||||
s->btns[2].flags = WIDGET_FLAG_DISABLED;
|
||||
s->btns[3].flags = WIDGET_FLAG_DISABLED;
|
||||
s->btns[5].flags = WIDGET_FLAG_DISABLED;
|
||||
}
|
||||
|
||||
static void PauseScreen_Free(void* screen) {
|
||||
|
|
@ -1655,8 +1656,18 @@ static void FontListScreen_LoadEntries(struct ListScreen* s) {
|
|||
ListScreen_Select(s, SysFonts_UNSAFE_GetDefault());
|
||||
}
|
||||
|
||||
static void FontListScreen_RegisterCallback(const cc_string* path) {
|
||||
Chat_Add1("Loaded font from %s", path);
|
||||
}
|
||||
|
||||
static void FontListScreen_UploadCallback(const cc_string* path) {
|
||||
SysFonts_Register(path);
|
||||
cc_result res = SysFonts_Register(path, FontListScreen_RegisterCallback);
|
||||
|
||||
if (res) {
|
||||
Logger_SimpleWarn2(res, "loading font from", path);
|
||||
} else {
|
||||
SysFonts_SaveCache();
|
||||
}
|
||||
}
|
||||
|
||||
static void FontListScreen_ActionFunc(void* s, void* w) {
|
||||
|
|
@ -2862,6 +2873,7 @@ static void GraphicsOptionsScreen_SetViewDist(const cc_string* v) { Game_UserSet
|
|||
static void GraphicsOptionsScreen_GetSmooth(cc_string* v) { Menu_GetBool(v, Builder_SmoothLighting); }
|
||||
static void GraphicsOptionsScreen_SetSmooth(const cc_string* v) {
|
||||
Builder_SmoothLighting = Menu_SetBool(v, OPT_SMOOTH_LIGHTING);
|
||||
Lighting_ApplyActive();
|
||||
Builder_ApplyActive();
|
||||
MapRenderer_Refresh();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -818,6 +818,7 @@ static void CustomModel_DrawArm(struct Entity* e) {
|
|||
struct CustomModel* cm = (struct CustomModel*)Models.Active;
|
||||
int i;
|
||||
if (!cm->numArmParts) return;
|
||||
Gfx_SetAlphaTest(true);
|
||||
|
||||
Models.uScale = 1.0f / cm->uScale;
|
||||
Models.vScale = 1.0f / cm->vScale;
|
||||
|
|
@ -952,6 +953,7 @@ static void HumanModel_DrawCore(struct Entity* e, struct ModelSet* model, cc_boo
|
|||
static void HumanModel_DrawArmCore(struct Entity* e, struct ModelSet* model) {
|
||||
struct ModelLimbs* set;
|
||||
int type, num;
|
||||
Gfx_SetAlphaTest(true);
|
||||
|
||||
type = Models.skinType;
|
||||
set = &model->limbs[type & 0x3];
|
||||
|
|
@ -1854,6 +1856,7 @@ static void SkeletonModel_Draw(struct Entity* e) {
|
|||
}
|
||||
|
||||
static void SkeletonModel_DrawArm(struct Entity* e) {
|
||||
Gfx_SetAlphaTest(true);
|
||||
Model_LockVB(e, MODEL_BOX_VERTICES);
|
||||
|
||||
Model_DrawArmPart(&skeleton_rightArm);
|
||||
|
|
|
|||
|
|
@ -201,7 +201,7 @@ void Options_SetSecure(const char* opt, const cc_string* src) {
|
|||
|
||||
String_InitArray(enc, encData);
|
||||
res = Platform_Encrypt(src->buffer, src->length, &enc);
|
||||
if (res) { Platform_Log2("Error %h encrypting option %c", &res, opt); return; }
|
||||
if (res) { Platform_Log2("Error %e encrypting option %c", &res, opt); return; }
|
||||
|
||||
/* base64 encode the data, as user might edit options.txt with a text editor */
|
||||
if (enc.length > 1500) Logger_Abort("too large to base64");
|
||||
|
|
@ -223,5 +223,5 @@ void Options_GetSecure(const char* opt, cc_string* dst) {
|
|||
|
||||
dataLen = Convert_FromBase64(raw.buffer, raw.length, data);
|
||||
res = Platform_Decrypt(data, dataLen, dst);
|
||||
if (res) Platform_Log2("Error %h decrypting option %c", &res, opt);
|
||||
if (res) Platform_Log2("Error %e decrypting option %c", &res, opt);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -270,6 +270,8 @@ cc_result Socket_Read(cc_socket s, cc_uint8* data, cc_uint32 count, cc_uint32* m
|
|||
cc_result Socket_Write(cc_socket s, const cc_uint8* data, cc_uint32 count, cc_uint32* modified);
|
||||
/* Attempts to close the given socket */
|
||||
void Socket_Close(cc_socket s);
|
||||
/* Attempts to write all data to the given socket, returning ERR_END_OF_STREAM if it could not */
|
||||
cc_result Socket_WriteAll(cc_socket socket, const cc_uint8* data, cc_uint32 count);
|
||||
|
||||
#ifdef CC_BUILD_MOBILE
|
||||
void Platform_ShareScreenshot(const cc_string* filename);
|
||||
|
|
|
|||
|
|
@ -260,9 +260,6 @@ void Platform_Init(void) {
|
|||
DisableFpuExceptions();
|
||||
|
||||
Platform_ReadonlyFilesystem = true;
|
||||
// TODO: Redesign Drawer2D to better handle this
|
||||
Options_SetBool(OPT_USE_CHAT_FONT, true);
|
||||
|
||||
dfs_init(DFS_DEFAULT_LOCATION);
|
||||
timer_init();
|
||||
rtc_init();
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <nds/bios.h>
|
||||
#include <nds/cothread.h>
|
||||
#include <nds/interrupts.h>
|
||||
#include <nds/timers.h>
|
||||
#include <nds/debug.h>
|
||||
|
|
@ -66,17 +67,18 @@ cc_uint64 Stopwatch_Measure(void) {
|
|||
static void LogNocash(const char* msg, int len) {
|
||||
// Can only be up to 120 bytes total
|
||||
char buffer[120];
|
||||
len = min(len, 119);
|
||||
len = min(len, 118);
|
||||
|
||||
Mem_Copy(buffer, msg, len);
|
||||
buffer[len] = '\n';
|
||||
nocashWrite(buffer, len + 1);
|
||||
buffer[len + 0] = '\n';
|
||||
buffer[len + 1] = '\0';
|
||||
nocashWrite(buffer, len + 2);
|
||||
}
|
||||
|
||||
extern void consolePrintString(const char* ptr, int len);
|
||||
void Platform_Log(const char* msg, int len) {
|
||||
LogNocash(msg, len);
|
||||
if (!keyboardOpen) consolePrintString(msg, len);
|
||||
consolePrintString(msg, len);
|
||||
}
|
||||
|
||||
TimeMS DateTime_CurrentUTC(void) {
|
||||
|
|
@ -110,14 +112,15 @@ static void GetNativePath(char* str, const cc_string* path) {
|
|||
Mem_Copy(str, root_path.buffer, root_path.length);
|
||||
str += root_path.length;
|
||||
String_EncodeUtf8(str, path);
|
||||
Platform_Log1("Open %c", str - root_path.length);
|
||||
}
|
||||
|
||||
cc_result Directory_Create(const cc_string* path) {
|
||||
if (!fat_available) return ENOSYS;
|
||||
if (!fat_available) return 0;
|
||||
|
||||
char str[NATIVE_STR_LEN];
|
||||
GetNativePath(str, path);
|
||||
Platform_Log1("mkdir %c", str);
|
||||
|
||||
return mkdir(str, 0) == -1 ? errno : 0;
|
||||
}
|
||||
|
||||
|
|
@ -127,6 +130,8 @@ int File_Exists(const cc_string* path) {
|
|||
char str[NATIVE_STR_LEN];
|
||||
struct stat sb;
|
||||
GetNativePath(str, path);
|
||||
Platform_Log1("Check %c", str);
|
||||
|
||||
return stat(str, &sb) == 0 && S_ISREG(sb.st_mode);
|
||||
}
|
||||
|
||||
|
|
@ -137,6 +142,8 @@ cc_result Directory_Enum(const cc_string* dirPath, void* obj, Directory_EnumCall
|
|||
static cc_result File_Do(cc_file* file, const cc_string* path, int mode) {
|
||||
char str[NATIVE_STR_LEN];
|
||||
GetNativePath(str, path);
|
||||
Platform_Log1("Open %c", str);
|
||||
|
||||
*file = open(str, mode, 0);
|
||||
return *file == -1 ? errno : 0;
|
||||
}
|
||||
|
|
@ -186,24 +193,36 @@ cc_result File_Length(cc_file file, cc_uint32* len) {
|
|||
*len = st.st_size; return 0;
|
||||
}
|
||||
|
||||
static void InitFilesystem(void) {
|
||||
// I don't know why I have to call this function, but if I don't,
|
||||
// then when running in DSi mode AND an SD card is readable,
|
||||
// fatInitDefault gets stuck somewhere (in disk_initialize it seems)
|
||||
if (isDSiMode()) {
|
||||
const DISC_INTERFACE* sd_io = get_io_dsisd();
|
||||
if (sd_io) sd_io->startup();
|
||||
static int LoadFatFilesystem(void* arg) {
|
||||
fat_available = fatInitDefault();
|
||||
return 0;
|
||||
}
|
||||
|
||||
fat_available = fatInitDefault();
|
||||
Platform_ReadonlyFilesystem = !fat_available;
|
||||
if (!fat_available) return;
|
||||
static void InitFilesystem(void) {
|
||||
cothread_t thread = cothread_create(LoadFatFilesystem, NULL, 0, 0);
|
||||
// If running with DSi mode in melonDS and the internal SD card is enabled, then
|
||||
// fatInitDefault gets stuck in sdmmc_ReadSectors - because the fifoWaitValue32Async will never return
|
||||
// (You can tell when this happens - "MMC: unknown CMD 17 00000000" is logged to console)
|
||||
// However, since it does yield to cothreads, workaround this by running fatInitDefault on another thread
|
||||
// and then giving up if it takes too long.. not the most elegant solution, but it does work
|
||||
if (thread == -1) {
|
||||
LoadFatFilesystem(NULL);
|
||||
} else {
|
||||
for (int i = 0; i < 100; i++)
|
||||
{
|
||||
cothread_yield();
|
||||
if (cothread_has_joined(thread)) break;
|
||||
|
||||
swiDelay(2000);
|
||||
}
|
||||
}
|
||||
|
||||
char* dir = fatGetDefaultCwd();
|
||||
if (dir && dir[0]) {
|
||||
if (dir) {
|
||||
root_path.buffer = dir;
|
||||
root_path.length = String_Length(dir);
|
||||
}
|
||||
Platform_ReadonlyFilesystem = !fat_available;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -406,9 +425,6 @@ void Platform_Init(void) {
|
|||
InitNetworking();
|
||||
|
||||
cpuStartTiming(1);
|
||||
// TODO: Redesign Drawer2D to better handle this
|
||||
Options_Load();
|
||||
Options_SetBool(OPT_USE_CHAT_FONT, true);
|
||||
}
|
||||
void Platform_Free(void) { }
|
||||
|
||||
|
|
|
|||
|
|
@ -227,8 +227,6 @@ cc_result Socket_CheckWritable(cc_socket s, cc_bool* writable) {
|
|||
void Platform_Init(void) {
|
||||
ResetGraph(0);
|
||||
Stopwatch_Init();
|
||||
|
||||
Options_SetBool(OPT_USE_CHAT_FONT, true);
|
||||
}
|
||||
|
||||
void Platform_Free(void) { }
|
||||
|
|
|
|||
|
|
@ -497,7 +497,7 @@ void Waitable_WaitFor(void* handle, cc_uint32 milliseconds) {
|
|||
*--------------------------------------------------------Font/Text--------------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
static void FontDirCallback(const cc_string* path, void* obj) {
|
||||
SysFonts_Register(path);
|
||||
SysFonts_Register(path, NULL);
|
||||
}
|
||||
|
||||
void Platform_LoadSysFonts(void) {
|
||||
|
|
|
|||
|
|
@ -213,8 +213,6 @@ cc_result Socket_CheckWritable(cc_socket s, cc_bool* writable) {
|
|||
*#########################################################################################################################*/
|
||||
void Platform_Init(void) {
|
||||
Stopwatch_Init();
|
||||
|
||||
Options_SetBool(OPT_USE_CHAT_FONT, true);
|
||||
}
|
||||
|
||||
void Platform_Free(void) { }
|
||||
|
|
|
|||
|
|
@ -500,9 +500,6 @@ static void CreateRootDirectory(void) {
|
|||
}
|
||||
|
||||
void Platform_Init(void) {
|
||||
// TODO: Redesign Drawer2D to better handle this
|
||||
//Options_SetBool(OPT_USE_CHAT_FONT, true);
|
||||
|
||||
CreateRootDirectory();
|
||||
socketInitializeDefault();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -360,7 +360,7 @@ static void FontDirCallback(const cc_string* path, void* obj) {
|
|||
static const cc_string fonExt = String_FromConst(".fon");
|
||||
/* Completely skip windows .FON files */
|
||||
if (String_CaselessEnds(path, &fonExt)) return;
|
||||
SysFonts_Register(path);
|
||||
SysFonts_Register(path, NULL);
|
||||
}
|
||||
|
||||
void Platform_LoadSysFonts(void) {
|
||||
|
|
@ -839,7 +839,7 @@ cc_bool DynamicLib_DescribeError(cc_string* dst) {
|
|||
dynamicErr = 0; /* Reset error (match posix behaviour) */
|
||||
|
||||
Platform_DescribeError(res, dst);
|
||||
String_Format1(dst, " (error %i)", &res);
|
||||
String_Format1(dst, " (error %e)", &res);
|
||||
|
||||
/* Plugin may have been compiled to load symbols from ClassiCube.exe, */
|
||||
/* but the user might have renamed it to something else */
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ cc_result Directory_Create(const cc_string* path) {
|
|||
}
|
||||
|
||||
int File_Exists(const cc_string* path) {
|
||||
if (!hdd_mounted) return ERR_NOT_SUPPORTED;
|
||||
if (!hdd_mounted) return 0;
|
||||
|
||||
char str[NATIVE_STR_LEN];
|
||||
DWORD attribs;
|
||||
|
|
@ -164,7 +164,7 @@ cc_result Directory_Enum(const cc_string* dirPath, void* obj, Directory_EnumCall
|
|||
} while (FindNextFileA(find, &eA));
|
||||
|
||||
res = GetLastError(); /* return code from FindNextFile */
|
||||
FindClose(find);
|
||||
NtClose(find);
|
||||
return res == ERROR_NO_MORE_FILES ? 0 : res;
|
||||
}
|
||||
|
||||
|
|
@ -203,7 +203,8 @@ cc_result File_Write(cc_file file, const void* data, cc_uint32 count, cc_uint32*
|
|||
}
|
||||
|
||||
cc_result File_Close(cc_file file) {
|
||||
return CloseHandle(file) ? 0 : GetLastError();
|
||||
NTSTATUS status = NtClose(file);
|
||||
return NT_SUCCESS(status) ? 0 : status;
|
||||
}
|
||||
|
||||
cc_result File_Seek(cc_file file, int offset, int seekType) {
|
||||
|
|
@ -225,7 +226,15 @@ cc_result File_Length(cc_file file, cc_uint32* len) {
|
|||
|
||||
/*########################################################################################################################*
|
||||
*--------------------------------------------------------Threading--------------------------------------------------------*
|
||||
*#############################################################################################################p############*/
|
||||
*##########################################################################################################################*/
|
||||
static void WaitForSignal(HANDLE handle, LARGE_INTEGER* duration) {
|
||||
for (;;)
|
||||
{
|
||||
NTSTATUS status = NtWaitForSingleObjectEx((HANDLE)handle, UserMode, FALSE, duration);
|
||||
if (status != STATUS_ALERTED) break;
|
||||
}
|
||||
}
|
||||
|
||||
void Thread_Sleep(cc_uint32 milliseconds) { Sleep(milliseconds); }
|
||||
static DWORD WINAPI ExecThread(void* param) {
|
||||
Thread_StartFunc func = (Thread_StartFunc)param;
|
||||
|
|
@ -243,13 +252,12 @@ void Thread_Run(void** handle, Thread_StartFunc func, int stackSize, const char*
|
|||
}
|
||||
|
||||
void Thread_Detach(void* handle) {
|
||||
if (!CloseHandle((HANDLE)handle)) {
|
||||
Logger_Abort2(GetLastError(), "Freeing thread handle");
|
||||
}
|
||||
NTSTATUS status = NtClose((HANDLE)handle);
|
||||
if (!NT_SUCCESS(status)) Logger_Abort2(status, "Freeing thread handle");
|
||||
}
|
||||
|
||||
void Thread_Join(void* handle) {
|
||||
WaitForSingleObject((HANDLE)handle, INFINITE);
|
||||
WaitForSignal((HANDLE)handle, NULL);
|
||||
Thread_Detach(handle);
|
||||
}
|
||||
|
||||
|
|
@ -263,30 +271,41 @@ void Mutex_Free(void* handle) {
|
|||
RtlDeleteCriticalSection((CRITICAL_SECTION*)handle);
|
||||
Mem_Free(handle);
|
||||
}
|
||||
void Mutex_Lock(void* handle) { RtlEnterCriticalSection((CRITICAL_SECTION*)handle); }
|
||||
void Mutex_Unlock(void* handle) { RtlLeaveCriticalSection((CRITICAL_SECTION*)handle); }
|
||||
|
||||
void Mutex_Lock(void* handle) {
|
||||
RtlEnterCriticalSection((CRITICAL_SECTION*)handle);
|
||||
}
|
||||
|
||||
void Mutex_Unlock(void* handle) {
|
||||
RtlLeaveCriticalSection((CRITICAL_SECTION*)handle);
|
||||
}
|
||||
|
||||
void* Waitable_Create(void) {
|
||||
void* handle = CreateEventA(NULL, false, false, NULL);
|
||||
if (!handle) {
|
||||
Logger_Abort2(GetLastError(), "Creating waitable");
|
||||
}
|
||||
HANDLE handle;
|
||||
NTSTATUS status = NtCreateEvent(&handle, NULL, SynchronizationEvent, false);
|
||||
|
||||
if (!NT_SUCCESS(status)) Logger_Abort2(status, "Creating waitable");
|
||||
return handle;
|
||||
}
|
||||
|
||||
void Waitable_Free(void* handle) {
|
||||
if (!CloseHandle((HANDLE)handle)) {
|
||||
Logger_Abort2(GetLastError(), "Freeing waitable");
|
||||
}
|
||||
NTSTATUS status = NtClose((HANDLE)handle);
|
||||
if (!NT_SUCCESS(status)) Logger_Abort2(status, "Freeing waitable");
|
||||
}
|
||||
|
||||
void Waitable_Signal(void* handle) {
|
||||
NtSetEvent((HANDLE)handle, NULL);
|
||||
}
|
||||
|
||||
void Waitable_Signal(void* handle) { NtSetEvent((HANDLE)handle, NULL); }
|
||||
void Waitable_Wait(void* handle) {
|
||||
WaitForSingleObject((HANDLE)handle, INFINITE);
|
||||
WaitForSignal((HANDLE)handle, NULL);
|
||||
}
|
||||
|
||||
void Waitable_WaitFor(void* handle, cc_uint32 milliseconds) {
|
||||
WaitForSingleObject((HANDLE)handle, milliseconds);
|
||||
LARGE_INTEGER duration;
|
||||
duration.QuadPart = ((LONGLONG)milliseconds) * -10000; // negative for relative timeout
|
||||
|
||||
WaitForSignal((HANDLE)handle, &duration);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -408,7 +427,9 @@ static void InitHDD(void) {
|
|||
void Platform_Init(void) {
|
||||
InitHDD();
|
||||
Stopwatch_Init();
|
||||
#ifndef CC_BUILD_CXBX
|
||||
nxNetInit(NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Platform_Free(void) {
|
||||
|
|
|
|||
|
|
@ -358,7 +358,7 @@ static void DisconnectInvalidMap(cc_result res) {
|
|||
cc_string tmp; char tmpBuffer[STRING_SIZE];
|
||||
String_InitArray(tmp, tmpBuffer);
|
||||
|
||||
String_Format1(&tmp, "Server sent corrupted map data (error %h)", &res);
|
||||
String_Format1(&tmp, "Server sent corrupted map data (error %e)", &res);
|
||||
Game_Disconnect(&title, &tmp); return;
|
||||
}
|
||||
|
||||
|
|
|
|||
30
src/SSL.c
30
src/SSL.c
|
|
@ -105,21 +105,6 @@ static SECURITY_STATUS SSL_CreateHandle(struct SSLContext* ctx) {
|
|||
&cred, NULL, NULL, &ctx->handle, NULL);
|
||||
}
|
||||
|
||||
static cc_result SSL_SendRaw(cc_socket socket, const cc_uint8* data, cc_uint32 count) {
|
||||
cc_uint32 sent;
|
||||
cc_result res;
|
||||
|
||||
while (count)
|
||||
{
|
||||
if ((res = Socket_Write(socket, data, count, &sent))) return res;
|
||||
if (!sent) return ERR_END_OF_STREAM;
|
||||
|
||||
data += sent;
|
||||
count -= sent;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static cc_result SSL_RecvRaw(struct SSLContext* ctx) {
|
||||
cc_uint32 read;
|
||||
cc_result res;
|
||||
|
|
@ -160,7 +145,7 @@ static SECURITY_STATUS SSL_Connect(struct SSLContext* ctx, const char* hostname)
|
|||
|
||||
/* Send initial handshake to the server (if there is one) */
|
||||
if (out_buffers[0].pvBuffer) {
|
||||
res = SSL_SendRaw(ctx->socket, out_buffers[0].pvBuffer, out_buffers[0].cbBuffer);
|
||||
res = Socket_WriteAll(ctx->socket, out_buffers[0].pvBuffer, out_buffers[0].cbBuffer);
|
||||
FP_FreeContextBuffer(out_buffers[0].pvBuffer);
|
||||
}
|
||||
return res;
|
||||
|
|
@ -221,7 +206,7 @@ static SECURITY_STATUS SSL_Negotiate(struct SSLContext* ctx) {
|
|||
|
||||
/* Need to send data to the server */
|
||||
if (sec == SEC_I_CONTINUE_NEEDED) {
|
||||
res = SSL_SendRaw(ctx->socket, out_buffers[0].pvBuffer, out_buffers[0].cbBuffer);
|
||||
res = Socket_WriteAll(ctx->socket, out_buffers[0].pvBuffer, out_buffers[0].cbBuffer);
|
||||
FP_FreeContextBuffer(out_buffers[0].pvBuffer); /* TODO always free? */
|
||||
|
||||
if (res) return res;
|
||||
|
|
@ -392,13 +377,12 @@ static cc_result SSL_WriteChunk(struct SSLContext* s, const cc_uint8* data, cc_u
|
|||
/* NOTE: Okay to write in one go, since all three buffers will be contiguous */
|
||||
/* (as TLS record header size will always be the same size) */
|
||||
total = buffers[0].cbBuffer + buffers[1].cbBuffer + buffers[2].cbBuffer;
|
||||
return SSL_SendRaw(s->socket, buffer, total);
|
||||
return Socket_WriteAll(s->socket, buffer, total);
|
||||
}
|
||||
|
||||
cc_result SSL_Write(void* ctx, const cc_uint8* data, cc_uint32 count, cc_uint32* wrote) {
|
||||
cc_result SSL_WriteAll(void* ctx, const cc_uint8* data, cc_uint32 count) {
|
||||
struct SSLContext* s = ctx;
|
||||
cc_result res;
|
||||
*wrote = 0;
|
||||
|
||||
/* TODO: Don't loop here? move to HTTPConnection instead?? */
|
||||
while (count)
|
||||
|
|
@ -406,7 +390,6 @@ cc_result SSL_Write(void* ctx, const cc_uint8* data, cc_uint32 count, cc_uint32*
|
|||
int len = min(count, s->sizes.cbMaximumMessage);
|
||||
if ((res = SSL_WriteChunk(s, data, len))) return res;
|
||||
|
||||
*wrote += len;
|
||||
data += len;
|
||||
count -= len;
|
||||
}
|
||||
|
|
@ -558,7 +541,7 @@ cc_result SSL_Read(void* ctx_, cc_uint8* data, cc_uint32 count, cc_uint32* read)
|
|||
return 0;
|
||||
}
|
||||
|
||||
cc_result SSL_Write(void* ctx_, const cc_uint8* data, cc_uint32 count, cc_uint32* wrote) {
|
||||
cc_result SSL_WriteAll(void* ctx_, const cc_uint8* data, cc_uint32 count) {
|
||||
SSLContext* ctx = (SSLContext*)ctx_;
|
||||
// TODO: just br_sslio_write ??
|
||||
int res = br_sslio_write_all(&ctx->ioc, data, count);
|
||||
|
|
@ -569,7 +552,6 @@ cc_result SSL_Write(void* ctx_, const cc_uint8* data, cc_uint32 count, cc_uint32
|
|||
}
|
||||
|
||||
br_sslio_flush(&ctx->ioc);
|
||||
*wrote = res;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -592,7 +574,7 @@ cc_result SSL_Read(void* ctx, cc_uint8* data, cc_uint32 count, cc_uint32* read)
|
|||
return ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
cc_result SSL_Write(void* ctx, const cc_uint8* data, cc_uint32 count, cc_uint32* wrote) {
|
||||
cc_result SSL_WriteAll(void* ctx, const cc_uint8* data, cc_uint32 count) {
|
||||
return ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,6 @@ cc_bool SSLBackend_DescribeError(cc_result res, cc_string* dst);
|
|||
|
||||
cc_result SSL_Init(cc_socket socket, const cc_string* host, void** ctx);
|
||||
cc_result SSL_Read(void* ctx, cc_uint8* data, cc_uint32 count, cc_uint32* read);
|
||||
cc_result SSL_Write(void* ctx, const cc_uint8* data, cc_uint32 count, cc_uint32* wrote);
|
||||
cc_result SSL_WriteAll(void* ctx, const cc_uint8* data, cc_uint32 count);
|
||||
cc_result SSL_Free(void* ctx);
|
||||
#endif
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue