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)
|
name: Build latest (3DS)
|
||||||
on: [push]
|
# trigger via either push to selected branches or on manual run
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.ref }}-3ds
|
group: ${{ github.ref }}-3ds
|
||||||
|
|
@ -7,7 +12,6 @@ concurrency:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-3DS:
|
build-3DS:
|
||||||
if: github.ref_name == github.event.repository.default_branch
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container:
|
container:
|
||||||
image: devkitpro/devkitarm:latest
|
image: devkitpro/devkitarm:latest
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,10 @@
|
||||||
name: Build latest (Dreamcast)
|
name: Build latest (Dreamcast)
|
||||||
on: [push]
|
# trigger via either push to selected branches or on manual run
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.ref }}-dreamcast
|
group: ${{ github.ref }}-dreamcast
|
||||||
|
|
@ -7,7 +12,6 @@ concurrency:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
if: github.ref_name == github.event.repository.default_branch
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container:
|
container:
|
||||||
image: kazade/dreamcast-sdk
|
image: kazade/dreamcast-sdk
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,10 @@
|
||||||
name: Build latest (FreeBSD)
|
name: Build latest (FreeBSD)
|
||||||
on: [push]
|
# trigger via either push to selected branches or on manual run
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.ref }}-freebsd
|
group: ${{ github.ref }}-freebsd
|
||||||
|
|
@ -7,7 +12,6 @@ concurrency:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
if: github.ref_name == github.event.repository.default_branch
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container:
|
container:
|
||||||
image: empterdose/freebsd-cross-build:11.4
|
image: empterdose/freebsd-cross-build:11.4
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,10 @@
|
||||||
name: Build latest (Haiku)
|
name: Build latest (Haiku)
|
||||||
on: [push]
|
# trigger via either push to selected branches or on manual run
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.ref }}-haiku
|
group: ${{ github.ref }}-haiku
|
||||||
|
|
@ -7,7 +12,6 @@ concurrency:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-haiku:
|
build-haiku:
|
||||||
if: github.ref_name == github.event.repository.default_branch
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container:
|
container:
|
||||||
image: haiku/cross-compiler:x86_64-r1beta4
|
image: haiku/cross-compiler:x86_64-r1beta4
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,10 @@
|
||||||
name: Build latest (iOS)
|
name: Build latest (iOS)
|
||||||
on: [push]
|
# trigger via either push to selected branches or on manual run
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.ref }}-ios
|
group: ${{ github.ref }}-ios
|
||||||
|
|
@ -7,7 +12,6 @@ concurrency:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
if: github.ref_name == github.event.repository.default_branch
|
|
||||||
runs-on: macOS-11
|
runs-on: macOS-11
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,11 @@
|
||||||
name: Build latest (Linux)
|
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:
|
concurrency:
|
||||||
group: ${{ github.ref }}-linux
|
group: ${{ github.ref }}-linux
|
||||||
|
|
@ -10,7 +16,6 @@ jobs:
|
||||||
# =============== 32 BIT LINUX ==============
|
# =============== 32 BIT LINUX ==============
|
||||||
# ===========================================
|
# ===========================================
|
||||||
build-32:
|
build-32:
|
||||||
if: github.ref_name == github.event.repository.default_branch
|
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
@ -64,7 +69,6 @@ jobs:
|
||||||
# =============== 64 BIT LINUX ==============
|
# =============== 64 BIT LINUX ==============
|
||||||
# ===========================================
|
# ===========================================
|
||||||
build-64:
|
build-64:
|
||||||
if: github.ref_name == github.event.repository.default_branch
|
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,10 @@
|
||||||
name: Build latest (macOS 64 bit)
|
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:
|
concurrency:
|
||||||
group: ${{ github.ref }}-mac64
|
group: ${{ github.ref }}-mac64
|
||||||
|
|
@ -7,7 +12,6 @@ concurrency:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
if: github.ref_name == github.event.repository.default_branch
|
|
||||||
runs-on: macOS-latest
|
runs-on: macOS-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,10 @@
|
||||||
name: Build latest (N64)
|
name: Build latest (N64)
|
||||||
on: [push]
|
# trigger via either push to selected branches or on manual run
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.ref }}-n64
|
group: ${{ github.ref }}-n64
|
||||||
|
|
@ -7,7 +12,6 @@ concurrency:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
if: github.ref_name == github.event.repository.default_branch
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container:
|
container:
|
||||||
image: ghcr.io/dragonminded/libdragon:latest
|
image: ghcr.io/dragonminded/libdragon:latest
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,10 @@
|
||||||
name: Build latest (NDS)
|
name: Build latest (NDS)
|
||||||
on: [push]
|
# trigger via either push to selected branches or on manual run
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.ref }}-nds
|
group: ${{ github.ref }}-nds
|
||||||
|
|
@ -7,7 +12,6 @@ concurrency:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-DS:
|
build-DS:
|
||||||
if: github.ref_name == github.event.repository.default_branch
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container:
|
container:
|
||||||
image: skylyrac/blocksds:dev-latest
|
image: skylyrac/blocksds:dev-latest
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,10 @@
|
||||||
name: Build latest (NetBSD)
|
name: Build latest (NetBSD)
|
||||||
on: [push]
|
# trigger via either push to selected branches or on manual run
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.ref }}-netbsd
|
group: ${{ github.ref }}-netbsd
|
||||||
|
|
@ -7,7 +12,6 @@ concurrency:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
if: github.ref_name == github.event.repository.default_branch
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container:
|
container:
|
||||||
image: ghcr.io/cross-rs/x86_64-unknown-netbsd
|
image: ghcr.io/cross-rs/x86_64-unknown-netbsd
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,10 @@
|
||||||
name: Build latest (PS2)
|
name: Build latest (PS2)
|
||||||
on: [push]
|
# trigger via either push to selected branches or on manual run
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.ref }}-ps2
|
group: ${{ github.ref }}-ps2
|
||||||
|
|
@ -7,7 +12,6 @@ concurrency:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
if: github.ref_name == github.event.repository.default_branch
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container:
|
container:
|
||||||
image: ghcr.io/ps2dev/ps2sdk:latest
|
image: ghcr.io/ps2dev/ps2sdk:latest
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,10 @@
|
||||||
name: Build latest (PS3)
|
name: Build latest (PS3)
|
||||||
on: [push]
|
# trigger via either push to selected branches or on manual run
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.ref }}-ps3
|
group: ${{ github.ref }}-ps3
|
||||||
|
|
@ -7,7 +12,6 @@ concurrency:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-PS3:
|
build-PS3:
|
||||||
if: github.ref_name == github.event.repository.default_branch
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container:
|
container:
|
||||||
image: ghcr.io/classicube/minimal-psl1ght:latest
|
image: ghcr.io/classicube/minimal-psl1ght:latest
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,10 @@
|
||||||
name: Build latest (PSP)
|
name: Build latest (PSP)
|
||||||
on: [push]
|
# trigger via either push to selected branches or on manual run
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.ref }}-psp
|
group: ${{ github.ref }}-psp
|
||||||
|
|
@ -7,7 +12,6 @@ concurrency:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-PSP:
|
build-PSP:
|
||||||
if: github.ref_name == github.event.repository.default_branch
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container:
|
container:
|
||||||
image: pspdev/pspdev:latest
|
image: pspdev/pspdev:latest
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,10 @@
|
||||||
name: Build latest (RPI)
|
name: Build latest (RPI)
|
||||||
on: [push]
|
# trigger via either push to selected branches or on manual run
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.ref }}-rpi
|
group: ${{ github.ref }}-rpi
|
||||||
|
|
@ -10,7 +15,6 @@ jobs:
|
||||||
# ================ 32 BIT RPI ===============
|
# ================ 32 BIT RPI ===============
|
||||||
# ===========================================
|
# ===========================================
|
||||||
build-RPI32:
|
build-RPI32:
|
||||||
if: github.ref_name == github.event.repository.default_branch
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container:
|
container:
|
||||||
image: dockcross/linux-armv6-lts
|
image: dockcross/linux-armv6-lts
|
||||||
|
|
@ -59,7 +63,6 @@ jobs:
|
||||||
# ================ 64 BIT RPI ===============
|
# ================ 64 BIT RPI ===============
|
||||||
# ===========================================
|
# ===========================================
|
||||||
build-RPI64:
|
build-RPI64:
|
||||||
if: github.ref_name == github.event.repository.default_branch
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container:
|
container:
|
||||||
image: dockcross/linux-arm64-lts
|
image: dockcross/linux-arm64-lts
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,10 @@
|
||||||
name: Build latest (Saturn)
|
name: Build latest (Saturn)
|
||||||
on: [push]
|
# trigger via either push to selected branches or on manual run
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.ref }}-saturn
|
group: ${{ github.ref }}-saturn
|
||||||
|
|
@ -7,7 +12,6 @@ concurrency:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
if: github.ref_name == github.event.repository.default_branch
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container:
|
container:
|
||||||
image: ijacquez/yaul
|
image: ijacquez/yaul
|
||||||
|
|
@ -35,4 +39,10 @@ jobs:
|
||||||
if: ${{ always() && steps.compile.outcome == 'success' }}
|
if: ${{ always() && steps.compile.outcome == 'success' }}
|
||||||
with:
|
with:
|
||||||
SOURCE_FILE: 'ClassiCube-saturn.iso'
|
SOURCE_FILE: 'ClassiCube-saturn.iso'
|
||||||
DEST_NAME: '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)
|
name: Build latest (Switch)
|
||||||
on: [push]
|
# trigger via either push to selected branches or on manual run
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.ref }}-switch
|
group: ${{ github.ref }}-switch
|
||||||
|
|
@ -7,7 +12,6 @@ concurrency:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-switch:
|
build-switch:
|
||||||
if: github.ref_name == github.event.repository.default_branch
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container:
|
container:
|
||||||
image: devkitpro/devkita64:latest
|
image: devkitpro/devkita64:latest
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,10 @@
|
||||||
name: Build latest (Vita)
|
name: Build latest (Vita)
|
||||||
on: [push]
|
# trigger via either push to selected branches or on manual run
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.ref }}-vita
|
group: ${{ github.ref }}-vita
|
||||||
|
|
@ -7,7 +12,6 @@ concurrency:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-Vita:
|
build-Vita:
|
||||||
if: github.ref_name == github.event.repository.default_branch
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container:
|
container:
|
||||||
image: vitasdk/vitasdk:latest
|
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)
|
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:
|
concurrency:
|
||||||
group: ${{ github.ref }}-wiigc
|
group: ${{ github.ref }}-wiigc
|
||||||
|
|
@ -7,7 +12,6 @@ concurrency:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
if: github.ref_name == github.event.repository.default_branch
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container:
|
container:
|
||||||
image: devkitpro/devkitppc:latest
|
image: devkitpro/devkitppc:latest
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,10 @@
|
||||||
name: Build latest (WiiU)
|
name: Build latest (WiiU)
|
||||||
on: [push]
|
# trigger via either push to selected branches or on manual run
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.ref }}-wiiu
|
group: ${{ github.ref }}-wiiu
|
||||||
|
|
@ -7,7 +12,6 @@ concurrency:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
if: github.ref_name == github.event.repository.default_branch
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container:
|
container:
|
||||||
image: devkitpro/devkitppc:latest
|
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)
|
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:
|
concurrency:
|
||||||
group: ${{ github.ref }}-windows
|
group: ${{ github.ref }}-windows
|
||||||
|
|
@ -10,7 +16,6 @@ jobs:
|
||||||
# ============== 32 BIT WINDOWS =============
|
# ============== 32 BIT WINDOWS =============
|
||||||
# ===========================================
|
# ===========================================
|
||||||
build-32:
|
build-32:
|
||||||
if: github.ref_name == github.event.repository.default_branch
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
@ -77,7 +82,6 @@ jobs:
|
||||||
# ============== 64 BIT WINDOWS =============
|
# ============== 64 BIT WINDOWS =============
|
||||||
# ===========================================
|
# ===========================================
|
||||||
build-64:
|
build-64:
|
||||||
if: github.ref_name == github.event.repository.default_branch
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,10 @@
|
||||||
name: Build latest (Xbox)
|
name: Build latest (Xbox)
|
||||||
on: [push]
|
# trigger via either push to selected branches or on manual run
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.ref }}-xbox
|
group: ${{ github.ref }}-xbox
|
||||||
|
|
@ -7,7 +12,6 @@ concurrency:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-Xbox:
|
build-Xbox:
|
||||||
if: github.ref_name == github.event.repository.default_branch
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container:
|
container:
|
||||||
image: ghcr.io/xboxdev/nxdk:git-e955705a
|
image: ghcr.io/xboxdev/nxdk:git-e955705a
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,17 @@
|
||||||
name: Build latest (Xbox 360)
|
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:
|
concurrency:
|
||||||
group: ${{ github.ref }}-xbox360
|
group: ${{ github.ref }}-xbox360
|
||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-Xbox:
|
build-360:
|
||||||
if: github.ref_name == github.event.repository.default_branch
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container:
|
container:
|
||||||
image: free60/libxenon
|
image: free60/libxenon
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ concurrency:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
if: github.ref_name == github.event.repository.default_branch
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,12 @@ build-saturn/
|
||||||
cd/
|
cd/
|
||||||
# Microsoft console build results
|
# Microsoft console build results
|
||||||
build-360/
|
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
|
# Sony console build results
|
||||||
build-ps2/
|
build-ps2/
|
||||||
build-ps3/
|
build-ps3/
|
||||||
|
|
@ -91,6 +97,8 @@ CMakeCache.txt
|
||||||
|
|
||||||
#GCC object files
|
#GCC object files
|
||||||
*.o
|
*.o
|
||||||
|
# Build dependency files
|
||||||
|
*.d
|
||||||
|
|
||||||
# Roslyn cache directories
|
# Roslyn cache directories
|
||||||
*.ide/
|
*.ide/
|
||||||
|
|
|
||||||
|
|
@ -506,7 +506,7 @@
|
||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
|
||||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||||
MTL_FAST_MATH = YES;
|
MTL_FAST_MATH = YES;
|
||||||
ONLY_ACTIVE_ARCH = YES;
|
ONLY_ACTIVE_ARCH = YES;
|
||||||
|
|
@ -559,7 +559,7 @@
|
||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
|
||||||
MTL_ENABLE_DEBUG_INFO = NO;
|
MTL_ENABLE_DEBUG_INFO = NO;
|
||||||
MTL_FAST_MATH = YES;
|
MTL_FAST_MATH = YES;
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
|
|
@ -573,7 +573,7 @@
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
INFOPLIST_FILE = Info.plist;
|
INFOPLIST_FILE = Info.plist;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
|
|
@ -590,7 +590,7 @@
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
INFOPLIST_FILE = Info.plist;
|
INFOPLIST_FILE = Info.plist;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
Copyright (c) 2014 - 2022, UnknownShadow200
|
Copyright (c) 2014 - 2024, UnknownShadow200
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without modification,
|
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
|
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))
|
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
|
CFLAGS :=-g -O1 -pipe -fno-math-errno -Ithird_party/bearssl/inc
|
||||||
|
|
||||||
GLDC_LIB=third_party/gldc/libGLdc.a
|
GLDC_LIB=third_party/gldc/libGLdc.a
|
||||||
|
|
@ -21,8 +22,9 @@ default: $(CC_TEXTURES) $(GLDC_LIB) $(BUILD_DIR) $(TARGET).cdi
|
||||||
$(BUILD_DIR):
|
$(BUILD_DIR):
|
||||||
mkdir -p $(BUILD_DIR)
|
mkdir -p $(BUILD_DIR)
|
||||||
|
|
||||||
$(GLDC_LIB):
|
$(GLDC_LIB): FORCE
|
||||||
$(MAKE) -C third_party/gldc
|
$(MAKE) -C third_party/gldc
|
||||||
|
FORCE: ;
|
||||||
|
|
||||||
# TODO add textures to misc folder ?
|
# TODO add textures to misc folder ?
|
||||||
$(CC_TEXTURES):
|
$(CC_TEXTURES):
|
||||||
|
|
@ -31,6 +33,9 @@ $(CC_TEXTURES):
|
||||||
$(BUILD_DIR)/%.o: src/%.c
|
$(BUILD_DIR)/%.o: src/%.c
|
||||||
kos-cc $(CFLAGS) -c $< -o $@
|
kos-cc $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
$(BUILD_DIR)/%.o: misc/dreamcast/%.S
|
||||||
|
kos-cc -c $< -o $@
|
||||||
|
|
||||||
$(BUILD_DIR)/%.o: third_party/bearssl/src/%.c
|
$(BUILD_DIR)/%.o: third_party/bearssl/src/%.c
|
||||||
kos-cc $(CFLAGS) -c $< -o $@
|
kos-cc $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
|
@ -58,4 +63,4 @@ $(TARGET).iso: $(TARGET)-scr.bin
|
||||||
# genisoimage -V ClassiCube -G IP.BIN -joliet -rock -l -o $(TARGET).iso ISO_FILES
|
# genisoimage -V ClassiCube -G IP.BIN -joliet -rock -l -o $(TARGET).iso ISO_FILES
|
||||||
|
|
||||||
$(TARGET).cdi: $(TARGET).iso
|
$(TARGET).cdi: $(TARGET).iso
|
||||||
cdi4dc $(TARGET).iso $(TARGET).cdi
|
cdi4dc $(TARGET).iso $(TARGET).cdi
|
||||||
|
|
|
||||||
|
|
@ -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+=
|
SH_LDFLAGS+=
|
||||||
|
|
||||||
IP_VERSION:= V1.000
|
IP_VERSION:= V1.000
|
||||||
IP_RELEASE_DATE:= 20160101
|
IP_RELEASE_DATE:= 20230101
|
||||||
IP_AREAS:= JTUBKAEL
|
IP_AREAS:= JTUBKAEL
|
||||||
IP_PERIPHERALS:= JAMKST
|
IP_PERIPHERALS:= JAMKST
|
||||||
IP_TITLE:= VDP1 drawing
|
IP_TITLE:= ClassiCube
|
||||||
IP_MASTER_STACK_ADDR:= 0x06004000
|
IP_MASTER_STACK_ADDR:= 0x06004000
|
||||||
IP_SLAVE_STACK_ADDR:= 0x06001E00
|
IP_SLAVE_STACK_ADDR:= 0x06001E00
|
||||||
IP_1ST_READ_ADDR:= 0x06004000
|
IP_1ST_READ_ADDR:= 0x06004000
|
||||||
|
|
|
||||||
|
|
@ -78,14 +78,15 @@ export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
|
||||||
export DEPSDIR := $(CURDIR)/$(BUILD)
|
export DEPSDIR := $(CURDIR)/$(BUILD)
|
||||||
|
|
||||||
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
|
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
|
||||||
|
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
|
||||||
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
|
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
|
||||||
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) \
|
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) \
|
||||||
$(foreach dir,$(SHADERS),$(notdir $(wildcard $(dir)/*.gsh)))
|
$(foreach dir,$(SHADERS),$(notdir $(wildcard $(dir)/*.gsh)))
|
||||||
|
|
||||||
export LD := $(CC)
|
export LD := $(CXX)
|
||||||
|
|
||||||
export OFILES_BIN := $(addsuffix .o,$(BINFILES))
|
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 OFILES := $(OFILES_BIN) $(OFILES_SRC)
|
||||||
export HFILES_BIN := $(addsuffix .h,$(subst .,_,$(BINFILES)))
|
export HFILES_BIN := $(addsuffix .h,$(subst .,_,$(BINFILES)))
|
||||||
|
|
||||||
|
|
@ -170,4 +171,4 @@ $(OFILES_SRC) : $(HFILES_BIN)
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
endif
|
endif
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
|
|
|
||||||
14
src/Bitmap.c
14
src/Bitmap.c
|
|
@ -163,8 +163,8 @@ static void Png_Reconstruct(cc_uint8 type, cc_uint8 bytesPerPixel, cc_uint8* lin
|
||||||
|
|
||||||
/* 7.2 Scanlines */
|
/* 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(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_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 -= 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__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_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--];
|
#define PNG_Do_Palette__8() *dst-- = palette[*src--];
|
||||||
|
|
@ -488,12 +488,14 @@ cc_result Png_Decode(struct Bitmap* bmp, struct Stream* stream) {
|
||||||
/* immediately into the destination colour format */
|
/* immediately into the destination colour format */
|
||||||
if (colorspace == PNG_COLOR_RGB_A) {
|
if (colorspace == PNG_COLOR_RGB_A) {
|
||||||
/* Prior line is no longer needed and can be overwritten now */
|
/* Prior line is no longer needed and can be overwritten now */
|
||||||
rowExpander(bmp->width, palette, &prior[1], Bitmap_GetRow(bmp, rowY - 1));
|
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 */
|
/* 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) {
|
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];
|
BlockID chunk[EXTCHUNK_SIZE_3];
|
||||||
cc_uint8 counts[CHUNK_SIZE_3 * FACE_COUNT];
|
cc_uint8 counts[CHUNK_SIZE_3 * FACE_COUNT];
|
||||||
int bitFlags[EXTCHUNK_SIZE_3];
|
int bitFlags[EXTCHUNK_SIZE_3];
|
||||||
|
#endif
|
||||||
|
|
||||||
cc_bool allAir, allSolid, onBorder;
|
cc_bool allAir, allSolid, onBorder;
|
||||||
int xMax, yMax, zMax, totalVerts;
|
int xMax, yMax, zMax, totalVerts;
|
||||||
|
|
@ -761,6 +768,7 @@ static void NormalBuilder_SetActive(void) {
|
||||||
/*########################################################################################################################*
|
/*########################################################################################################################*
|
||||||
*-------------------------------------------------Advanced mesh builder---------------------------------------------------*
|
*-------------------------------------------------Advanced mesh builder---------------------------------------------------*
|
||||||
*#########################################################################################################################*/
|
*#########################################################################################################################*/
|
||||||
|
#ifdef CC_BUILD_ADVLIGHTING
|
||||||
static Vec3 adv_minBB, adv_maxBB;
|
static Vec3 adv_minBB, adv_maxBB;
|
||||||
static int adv_initBitFlags, adv_baseOffset;
|
static int adv_initBitFlags, adv_baseOffset;
|
||||||
static int* adv_bitFlags;
|
static int* adv_bitFlags;
|
||||||
|
|
@ -1259,6 +1267,9 @@ static void AdvBuilder_SetActive(void) {
|
||||||
Builder_RenderBlock = Adv_RenderBlock;
|
Builder_RenderBlock = Adv_RenderBlock;
|
||||||
Builder_PrePrepareChunk = Adv_PrePrepareChunk;
|
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;
|
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;
|
struct Entity* e = &p->Base;
|
||||||
|
|
||||||
Vec3 camPos = Entity_GetEyePosition(e);
|
Vec3 camPos = Entity_GetEyePosition(e);
|
||||||
float yaw = e->Yaw * MATH_DEG2RAD;
|
float yaw = e->Yaw * MATH_DEG2RAD;
|
||||||
PerspectiveCamera_CalcViewBobbing(p, t, 1);
|
PerspectiveCamera_CalcViewBobbing(p, t, 1);
|
||||||
|
|
@ -202,8 +204,10 @@ static float ThirdPersonCamera_GetZoom(struct LocalPlayer* p) {
|
||||||
return dist;
|
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;
|
struct Entity* e = &p->Base;
|
||||||
|
|
||||||
float dist = ThirdPersonCamera_GetZoom(p);
|
float dist = ThirdPersonCamera_GetZoom(p);
|
||||||
Vec3 target, dir;
|
Vec3 target, dir;
|
||||||
Vec2 rot;
|
Vec2 rot;
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ struct Camera {
|
||||||
/* Returns the current orientation of the camera. */
|
/* Returns the current orientation of the camera. */
|
||||||
Vec2 (*GetOrientation)(struct LocalPlayer* p);
|
Vec2 (*GetOrientation)(struct LocalPlayer* p);
|
||||||
/* Returns the current interpolated position of the camera. */
|
/* 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. */
|
/* Called to update the camera's state. */
|
||||||
/* Typically, this is used to adjust yaw/pitch based on accumulated mouse movement. */
|
/* 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) */
|
/* Shorthand for Chat_AddOf(String_FromReadonly(raw), MSG_TYPE_NORMAL) */
|
||||||
void Chat_AddRaw(const char* raw);
|
void Chat_AddRaw(const char* raw);
|
||||||
|
|
||||||
void Chat_Add1(const char* format, const void* a1);
|
CC_API void Chat_Add1(const char* format, const void* a1);
|
||||||
void Chat_Add2(const char* format, const void* a1, const void* a2);
|
CC_API 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);
|
CC_API 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_Add4(const char* format, const void* a1, const void* a2, const void* a3, const void* a4);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -561,7 +561,7 @@
|
||||||
<ClCompile Include="Window_SDL3.c" />
|
<ClCompile Include="Window_SDL3.c" />
|
||||||
<ClCompile Include="Window_Switch.c" />
|
<ClCompile Include="Window_Switch.c" />
|
||||||
<ClCompile Include="Window_Web.c" />
|
<ClCompile Include="Window_Web.c" />
|
||||||
<ClCompile Include="Window_WiiU.c" />
|
<ClCompile Include="Window_WiiU.cpp" />
|
||||||
<ClCompile Include="Window_Win.c" />
|
<ClCompile Include="Window_Win.c" />
|
||||||
<ClCompile Include="Window_X11.c" />
|
<ClCompile Include="Window_X11.c" />
|
||||||
<ClCompile Include="Window_Xbox.c" />
|
<ClCompile Include="Window_Xbox.c" />
|
||||||
|
|
|
||||||
|
|
@ -728,9 +728,6 @@
|
||||||
<ClCompile Include="Window_SDL3.c">
|
<ClCompile Include="Window_SDL3.c">
|
||||||
<Filter>Source Files\Window</Filter>
|
<Filter>Source Files\Window</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="Window_WiiU.c">
|
|
||||||
<Filter>Source Files\Window</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="Platform_NDS.c">
|
<ClCompile Include="Platform_NDS.c">
|
||||||
<Filter>Source Files\Platform</Filter>
|
<Filter>Source Files\Platform</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
|
@ -752,6 +749,9 @@
|
||||||
<ClCompile Include="Graphics_WiiU.c">
|
<ClCompile Include="Graphics_WiiU.c">
|
||||||
<Filter>Source Files\Graphics</Filter>
|
<Filter>Source Files\Graphics</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="Window_WiiU.cpp">
|
||||||
|
<Filter>Source Files\Window</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="..\misc\windows\CCicon.rc">
|
<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-----------------------------------------------------*
|
*-------------------------------------------------------DrawOpCommand-----------------------------------------------------*
|
||||||
|
|
@ -709,6 +726,7 @@ static void OnInit(void) {
|
||||||
Commands_Register(&ModelCommand);
|
Commands_Register(&ModelCommand);
|
||||||
Commands_Register(&TeleportCommand);
|
Commands_Register(&TeleportCommand);
|
||||||
Commands_Register(&ClearDeniedCommand);
|
Commands_Register(&ClearDeniedCommand);
|
||||||
|
Commands_Register(&MotdCommand);
|
||||||
Commands_Register(&BlockEditCommand);
|
Commands_Register(&BlockEditCommand);
|
||||||
Commands_Register(&CuboidCommand);
|
Commands_Register(&CuboidCommand);
|
||||||
Commands_Register(&ReplaceCommand);
|
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_MinValue ((cc_int32)-2147483647L - (cc_int32)1L)
|
||||||
#define Int32_MaxValue ((cc_int32)2147483647L)
|
#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 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 SERVICES_SERVER "https://www.classicube.net/api"
|
||||||
#define RESOURCE_SERVER "http://static.classicube.net"
|
#define RESOURCE_SERVER "http://static.classicube.net"
|
||||||
/* Webpage where users can register for a new account */
|
/* 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_PLUGINS
|
||||||
#define CC_BUILD_ANIMATIONS
|
#define CC_BUILD_ANIMATIONS
|
||||||
#define CC_BUILD_FILESYSTEM
|
#define CC_BUILD_FILESYSTEM
|
||||||
|
#define CC_BUILD_ADVLIGHTING
|
||||||
/*#define CC_BUILD_GL11*/
|
/*#define CC_BUILD_GL11*/
|
||||||
|
|
||||||
#ifndef CC_BUILD_MANUAL
|
#ifndef CC_BUILD_MANUAL
|
||||||
|
|
@ -297,7 +298,6 @@ typedef cc_uint8 cc_bool;
|
||||||
#elif defined __vita__
|
#elif defined __vita__
|
||||||
#define CC_BUILD_PSVITA
|
#define CC_BUILD_PSVITA
|
||||||
#define CC_BUILD_CONSOLE
|
#define CC_BUILD_CONSOLE
|
||||||
#define CC_BUILD_LOWMEM
|
|
||||||
#define CC_BUILD_OPENAL
|
#define CC_BUILD_OPENAL
|
||||||
#define CC_BUILD_HTTPCLIENT
|
#define CC_BUILD_HTTPCLIENT
|
||||||
#define CC_BUILD_BEARSSL
|
#define CC_BUILD_BEARSSL
|
||||||
|
|
@ -313,7 +313,6 @@ typedef cc_uint8 cc_bool;
|
||||||
#elif defined PLAT_PS3
|
#elif defined PLAT_PS3
|
||||||
#define CC_BUILD_PS3
|
#define CC_BUILD_PS3
|
||||||
#define CC_BUILD_CONSOLE
|
#define CC_BUILD_CONSOLE
|
||||||
#define CC_BUILD_LOWMEM
|
|
||||||
#define CC_BUILD_OPENAL
|
#define CC_BUILD_OPENAL
|
||||||
#define CC_BUILD_HTTPCLIENT
|
#define CC_BUILD_HTTPCLIENT
|
||||||
#define CC_BUILD_BEARSSL
|
#define CC_BUILD_BEARSSL
|
||||||
|
|
@ -347,6 +346,7 @@ typedef cc_uint8 cc_bool;
|
||||||
#define CC_BUILD_TOUCH
|
#define CC_BUILD_TOUCH
|
||||||
#undef CC_BUILD_RESOURCES
|
#undef CC_BUILD_RESOURCES
|
||||||
#undef CC_BUILD_ANIMATIONS /* Very costly in FPU less system */
|
#undef CC_BUILD_ANIMATIONS /* Very costly in FPU less system */
|
||||||
|
#undef CC_BUILD_ADVLIGHTING
|
||||||
#elif defined __WIIU__
|
#elif defined __WIIU__
|
||||||
#define CC_BUILD_WIIU
|
#define CC_BUILD_WIIU
|
||||||
#define CC_BUILD_CONSOLE
|
#define CC_BUILD_CONSOLE
|
||||||
|
|
@ -354,6 +354,7 @@ typedef cc_uint8 cc_bool;
|
||||||
#define CC_BUILD_OPENAL
|
#define CC_BUILD_OPENAL
|
||||||
#define CC_BUILD_HTTPCLIENT
|
#define CC_BUILD_HTTPCLIENT
|
||||||
#define CC_BUILD_BEARSSL
|
#define CC_BUILD_BEARSSL
|
||||||
|
#define CC_BUILD_SPLITSCREEN
|
||||||
#define CC_BUILD_TOUCH
|
#define CC_BUILD_TOUCH
|
||||||
#elif defined __SWITCH__
|
#elif defined __SWITCH__
|
||||||
#define CC_BUILD_SWITCH
|
#define CC_BUILD_SWITCH
|
||||||
|
|
@ -375,6 +376,7 @@ typedef cc_uint8 cc_bool;
|
||||||
#undef CC_BUILD_RESOURCES
|
#undef CC_BUILD_RESOURCES
|
||||||
#undef CC_BUILD_NETWORKING
|
#undef CC_BUILD_NETWORKING
|
||||||
#undef CC_BUILD_ANIMATIONS /* Very costly in FPU less system */
|
#undef CC_BUILD_ANIMATIONS /* Very costly in FPU less system */
|
||||||
|
#undef CC_BUILD_ADVLIGHTING
|
||||||
#undef CC_BUILD_FILESYSTEM
|
#undef CC_BUILD_FILESYSTEM
|
||||||
#elif defined OS2
|
#elif defined OS2
|
||||||
#define CC_BUILD_OS2
|
#define CC_BUILD_OS2
|
||||||
|
|
@ -393,6 +395,7 @@ typedef cc_uint8 cc_bool;
|
||||||
#undef CC_BUILD_RESOURCES
|
#undef CC_BUILD_RESOURCES
|
||||||
#undef CC_BUILD_NETWORKING
|
#undef CC_BUILD_NETWORKING
|
||||||
#undef CC_BUILD_ANIMATIONS /* Very costly in FPU less system */
|
#undef CC_BUILD_ANIMATIONS /* Very costly in FPU less system */
|
||||||
|
#undef CC_BUILD_ADVLIGHTING
|
||||||
#undef CC_BUILD_FILESYSTEM
|
#undef CC_BUILD_FILESYSTEM
|
||||||
#endif
|
#endif
|
||||||
#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
|
* - set fast value to specify a 'value' value, and to skip 'len' bits
|
||||||
*/
|
*/
|
||||||
if (len <= INFLATE_FAST_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]);
|
int codeword = table->firstCodewords[len] + (bl_offsets[len] - table->firstOffsets[len]);
|
||||||
codeword <<= (INFLATE_FAST_BITS - 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) {
|
if (state->NumBits >= INFLATE_FAST_BITS) {
|
||||||
packed = table->fast[Inflate_PeekBits(state, INFLATE_FAST_BITS)];
|
packed = table->fast[Inflate_PeekBits(state, INFLATE_FAST_BITS)];
|
||||||
if (packed >= 0) {
|
if (packed >= 0) {
|
||||||
bits = packed >> INFLATE_FAST_BITS;
|
bits = packed >> INFLATE_FAST_LEN_SHIFT;
|
||||||
Inflate_ConsumeBits(state, bits);
|
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_DISTS 32
|
||||||
#define INFLATE_MAX_LITS_DISTS (INFLATE_MAX_LITS + INFLATE_MAX_DISTS)
|
#define INFLATE_MAX_LITS_DISTS (INFLATE_MAX_LITS + INFLATE_MAX_DISTS)
|
||||||
#define INFLATE_MAX_BITS 16
|
#define INFLATE_MAX_BITS 16
|
||||||
|
|
||||||
#define INFLATE_FAST_BITS 9
|
#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_SIZE 0x8000UL
|
||||||
#define INFLATE_WINDOW_MASK 0x7FFFUL
|
#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) {
|
static void DrawBitmappedText(struct Bitmap* bmp, struct DrawTextArgs* args, int x, int y) {
|
||||||
int offset = Drawer2D_ShadowOffset(args->font->size);
|
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) {
|
if (args->useShadow) {
|
||||||
DrawBitmappedTextCore(bmp, args, x + offset, y + offset, true);
|
DrawBitmappedTextCore(bmp, args, x + offset, y + offset, true);
|
||||||
}
|
}
|
||||||
|
|
@ -550,6 +556,8 @@ static int MeasureBitmappedWidth(const struct DrawTextArgs* args) {
|
||||||
int xPadding, width;
|
int xPadding, width;
|
||||||
cc_string text;
|
cc_string text;
|
||||||
|
|
||||||
|
if (!fontBitmap.scan0) return FallbackFont_TextWidth(args);
|
||||||
|
|
||||||
/* adjust coords to make drawn text match GDI fonts */
|
/* adjust coords to make drawn text match GDI fonts */
|
||||||
xPadding = Drawer2D_XPadding(point);
|
xPadding = Drawer2D_XPadding(point);
|
||||||
width = 0;
|
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);
|
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) {
|
float LocalPlayer_JumpHeight(struct LocalPlayer* p) {
|
||||||
return (float)PhysicsComp_CalcMaxHeight(p->Physics.JumpVel);
|
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 */
|
/* Spawn is normally centered to match vanilla Minecraft classic */
|
||||||
if (!p->Hacks.CanNoclip) {
|
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 {
|
} else {
|
||||||
p->Spawn.x = Math_Floor(p->Base.Position.x) + 0.5f;
|
p->Spawn.x = Math_Floor(p->Base.Position.x) + 0.5f;
|
||||||
p->Spawn.y = p->Base.Position.y;
|
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... */
|
/* 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) {
|
void LocalPlayer_CalcDefaultSpawn(struct LocalPlayer* p, struct LocationUpdate* update) {
|
||||||
|
|
@ -1062,6 +1069,7 @@ static void Entities_Free(void) {
|
||||||
{
|
{
|
||||||
Entities_Remove((EntityID)i);
|
Entities_Remove((EntityID)i);
|
||||||
}
|
}
|
||||||
|
sources_head = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct IGameComponent Entities_Component = {
|
struct IGameComponent Entities_Component = {
|
||||||
|
|
|
||||||
|
|
@ -231,6 +231,7 @@ struct LocalPlayerInput {
|
||||||
struct LocalPlayerInput* next;
|
struct LocalPlayerInput* next;
|
||||||
};
|
};
|
||||||
void LocalPlayerInput_Add(struct LocalPlayerInput* source);
|
void LocalPlayerInput_Add(struct LocalPlayerInput* source);
|
||||||
|
void LocalPlayerInput_Remove(struct LocalPlayerInput* source);
|
||||||
|
|
||||||
/* Represents the user/player's own entity. */
|
/* Represents the user/player's own entity. */
|
||||||
struct LocalPlayer {
|
struct LocalPlayer {
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ static cc_bool shadows_boundTex;
|
||||||
static GfxResourceID shadows_VB;
|
static GfxResourceID shadows_VB;
|
||||||
static GfxResourceID shadows_tex;
|
static GfxResourceID shadows_tex;
|
||||||
static float shadow_radius, shadow_uvScale;
|
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 */
|
/* Circle shadows extend at most 4 blocks vertically */
|
||||||
#define SHADOW_MAX_RANGE 4
|
#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;
|
z2 = min(z2, cen.z + shadow_radius); v2 = v2 <= 1.0f ? v2 : 1.0f;
|
||||||
|
|
||||||
v = *vertices;
|
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 = 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++;
|
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;
|
Vec3 min, max, nMin, nMax;
|
||||||
int i;
|
int i;
|
||||||
x = (float)Math_Floor(x); z = (float)Math_Floor(z);
|
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);
|
EntityShadow_DrawCoords(vertices, e, &data[0], x + min.x, z + min.z, x + max.x, z + max.z);
|
||||||
for (i = 1; i < 4; i++)
|
for (i = 1; i < 4; i++)
|
||||||
{
|
{
|
||||||
if (data[i].Block == BLOCK_AIR) return;
|
if (data[i].block == BLOCK_AIR) return;
|
||||||
nMin = Blocks.MinBB[data[i].Block]; nMax = Blocks.MaxBB[data[i].Block];
|
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 + 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);
|
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) {
|
static void EntityShadow_CalcAlpha(float playerY, struct ShadowData* data) {
|
||||||
float height = playerY - data->y;
|
float height = playerY - data->y;
|
||||||
if (height <= 6.0f) {
|
if (height <= 6.0f) {
|
||||||
data->A = (cc_uint8)(160 - 160 * height / 6.0f);
|
data->alpha = (cc_uint8)(160 - 160 * height / 6.0f);
|
||||||
data->y += 1.0f / 64.0f; return;
|
data->y += 1.0f / 64.0f;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
data->A = 0;
|
data->alpha = 0;
|
||||||
if (height <= 16.0f) data->y += 1.0f / 64.0f;
|
if (height <= 16.0f) data->y += 1.0f / 64.0f;
|
||||||
else if (height <= 32.0f) data->y += 1.0f / 16.0f;
|
else if (height <= 32.0f) data->y += 1.0f / 16.0f;
|
||||||
else if (height <= 96.0f) data->y += 1.0f / 8.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;
|
topY = y + Blocks.MaxBB[block].y;
|
||||||
if (topY >= posY + 0.01f) continue;
|
if (topY >= posY + 0.01f) continue;
|
||||||
|
|
||||||
cur->Block = block; cur->y = topY;
|
cur->block = block; cur->y = topY;
|
||||||
EntityShadow_CalcAlpha(posY, cur);
|
EntityShadow_CalcAlpha(posY, cur);
|
||||||
i++; 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) {
|
if (i < 4) {
|
||||||
cur->Block = Env.EdgeBlock; cur->y = 0.0f;
|
cur->block = Env.EdgeBlock; cur->y = 0.0f;
|
||||||
EntityShadow_CalcAlpha(posY, cur);
|
EntityShadow_CalcAlpha(posY, cur);
|
||||||
i++; 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);
|
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);
|
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);
|
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);
|
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);
|
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);
|
EntityShadow_DrawCircle(&ptr, e, data, (float)x2, (float)z2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -262,6 +263,7 @@ void EntityShadows_Render(void) {
|
||||||
if (Entities.ShadowsMode == SHADOW_MODE_CIRCLE_ALL) {
|
if (Entities.ShadowsMode == SHADOW_MODE_CIRCLE_ALL) {
|
||||||
for (i = 0; i < ENTITIES_MAX_COUNT; i++)
|
for (i = 0; i < ENTITIES_MAX_COUNT; i++)
|
||||||
{
|
{
|
||||||
|
e = Entities.List[i];
|
||||||
if (!e || !e->ShouldRender || e == &Entities.CurPlayer->Base) continue;
|
if (!e || !e->ShouldRender || e == &Entities.CurPlayer->Base) continue;
|
||||||
EntityShadow_Draw(e);
|
EntityShadow_Draw(e);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -132,7 +132,8 @@ enum CC_ERRORS {
|
||||||
HTTP_ERR_RELATIVE = 0xCCDED069UL, /* Unsupported relative URL format */
|
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_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_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 */
|
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 */
|
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 */
|
/* For abs(x) function */
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#define PI 3.141592653589793238462643383279502884197169399
|
||||||
|
|
||||||
/* Sega saturn is missing these intrinsics */
|
/* Sega saturn is missing these intrinsics */
|
||||||
#ifdef CC_BUILD_SATURN
|
#ifdef CC_BUILD_SATURN
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
@ -80,8 +82,8 @@ float Math_ClampAngle(float degrees) {
|
||||||
}
|
}
|
||||||
|
|
||||||
float Math_LerpAngle(float leftAngle, float rightAngle, float t) {
|
float Math_LerpAngle(float leftAngle, float rightAngle, float t) {
|
||||||
/* We have to cheat a bit for angles here */
|
/* Need to potentially adjust a bit when interpolating some angles */
|
||||||
/* Consider 350* --> 0*, we only want to travel 10* */
|
/* 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 */
|
/* 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 invertLeft = leftAngle > 270.0f && rightAngle < 90.0f;
|
||||||
cc_bool invertRight = rightAngle > 270.0f && leftAngle < 90.0f;
|
cc_bool invertRight = rightAngle > 270.0f && leftAngle < 90.0f;
|
||||||
|
|
@ -147,8 +149,6 @@ float Random_Float(RNGState* seed) {
|
||||||
/*########################################################################################################################*
|
/*########################################################################################################################*
|
||||||
*--------------------------------------------------Transcendental functions-----------------------------------------------*
|
*--------------------------------------------------Transcendental functions-----------------------------------------------*
|
||||||
*#########################################################################################################################*/
|
*#########################################################################################################################*/
|
||||||
static const double SQRT2 = 1.4142135623730950488016887242096980785696718753769;
|
|
||||||
|
|
||||||
#ifdef CC_BUILD_DREAMCAST
|
#ifdef CC_BUILD_DREAMCAST
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
|
|
@ -156,12 +156,10 @@ static const double SQRT2 = 1.4142135623730950488016887242096980785696718753769;
|
||||||
/* TODO: Properly investigate this issue */
|
/* TODO: Properly investigate this issue */
|
||||||
/* double make_dreamcast_build_compile(void) { fabs(4); } */
|
/* double make_dreamcast_build_compile(void) { fabs(4); } */
|
||||||
|
|
||||||
double Math_Sin(double x) { return sin(x); }
|
double Math_Sin(double x) { return sinf(x); }
|
||||||
double Math_Cos(double x) { return cos(x); }
|
double Math_Cos(double x) { return cosf(x); }
|
||||||
double Math_Exp2(double x) { return exp2(x); }
|
double Math_Exp2(double x) { return exp2(x); }
|
||||||
double Math_Log2(double x) { return log2(x); }
|
double Math_Log2(double x) { return log2(x); }
|
||||||
|
|
||||||
double Math_Atan2(double x, double y) { return atan2(y, x); }
|
|
||||||
#else
|
#else
|
||||||
/***** Caleb's Math functions *****/
|
/***** Caleb's Math functions *****/
|
||||||
|
|
||||||
|
|
@ -187,7 +185,7 @@ double Math_Atan2(double x, double y) { return atan2(y, x); }
|
||||||
/* from the mathematical functions anyways */
|
/* from the mathematical functions anyways */
|
||||||
|
|
||||||
/* Global constants */
|
/* Global constants */
|
||||||
#define PI 3.141592653589793238462643383279502884197169399
|
static const double SQRT2 = 1.4142135623730950488016887242096980785696718753769;
|
||||||
#define DIV_2_PI (1.0 / (2.0 * PI))
|
#define DIV_2_PI (1.0 / (2.0 * PI))
|
||||||
|
|
||||||
static const cc_uint64 _DBL_NAN = 0x7FF8000000000000ULL;
|
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));
|
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 *
|
* Math_Exp *
|
||||||
************/
|
************/
|
||||||
|
|
@ -576,7 +431,7 @@ double Math_Log2(double x) {
|
||||||
if (x == POS_INF)
|
if (x == POS_INF)
|
||||||
return 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;
|
return DBL_NAN;
|
||||||
|
|
||||||
doi.d = x;
|
doi.d = x;
|
||||||
|
|
@ -588,5 +443,26 @@ double Math_Log2(double x) {
|
||||||
|
|
||||||
return exponent + Log2Stage1(doi.d);
|
return exponent + Log2Stage1(doi.d);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#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);
|
CC_API double Math_Cos(double x);
|
||||||
float Math_SinF(float x);
|
float Math_SinF(float x);
|
||||||
float Math_CosF(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). */
|
/* Computes log2(x). Can also be used to approximate log_y(x). */
|
||||||
/* e.g. for log3(x), use: log2(x)/log2(3) */
|
/* 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];
|
Entities.CurPlayer = &LocalPlayer_Instances[i];
|
||||||
LocalPlayer_SetInterpPosition(Entities.CurPlayer, t);
|
LocalPlayer_SetInterpPosition(Entities.CurPlayer, t);
|
||||||
Camera.CurrentPos = Camera.Active->GetPosition(Entities.CurPlayer, t);
|
Camera.CurrentPos = Camera.Active->GetPosition(t);
|
||||||
|
|
||||||
Game_DrawFrame(delta, t);
|
Game_DrawFrame(delta, t);
|
||||||
}
|
}
|
||||||
|
|
@ -684,7 +684,7 @@ static CC_INLINE void Game_RenderFrame(double delta) {
|
||||||
t = (float)(entTask.accumulator / entTask.interval);
|
t = (float)(entTask.accumulator / entTask.interval);
|
||||||
LocalPlayer_SetInterpPosition(Entities.CurPlayer, t);
|
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 */
|
/* NOTE: EnvRenderer_UpdateFog also also sets clear color */
|
||||||
EnvRenderer_UpdateFog();
|
EnvRenderer_UpdateFog();
|
||||||
AudioBackend_Tick();
|
AudioBackend_Tick();
|
||||||
|
|
|
||||||
|
|
@ -439,7 +439,7 @@ void Gfx_SetFaceCulling(cc_bool enabled) {
|
||||||
|
|
||||||
void Gfx_SetAlphaArgBlend(cc_bool enabled) { }
|
void Gfx_SetAlphaArgBlend(cc_bool enabled) { }
|
||||||
|
|
||||||
void Gfx_SetAlphaBlending(cc_bool enabled) {
|
static void SetAlphaBlend(cc_bool enabled) {
|
||||||
if (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);
|
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 {
|
} 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);
|
C3D_AlphaTest(enabled, GPU_GREATER, 0x7F);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -806,7 +806,7 @@ void Gfx_CalcOrthoMatrix(struct Matrix* matrix, float width, float height, float
|
||||||
matrix->row1.y = -2.0f / width;
|
matrix->row1.y = -2.0f / width;
|
||||||
matrix->row4.y = 1.0f;
|
matrix->row4.y = 1.0f;
|
||||||
|
|
||||||
matrix->row3.z = 1.0f / (zNear - zFar);
|
matrix->row3.z = 1.0f / (zNear - zFar);
|
||||||
matrix->row4.z = 0.5f * (zNear + zFar) / (zNear - zFar) - 0.5f;
|
matrix->row4.z = 0.5f * (zNear + zFar) / (zNear - zFar) - 0.5f;
|
||||||
matrix->row4.w = 1.0f;
|
matrix->row4.w = 1.0f;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -691,7 +691,7 @@ void Gfx_SetFaceCulling(cc_bool enabled) {
|
||||||
static ID3D11SamplerState* ps_samplers[2];
|
static ID3D11SamplerState* ps_samplers[2];
|
||||||
static ID3D11PixelShader* ps_shaders[12];
|
static ID3D11PixelShader* ps_shaders[12];
|
||||||
static ID3D11Buffer* ps_cBuffer;
|
static ID3D11Buffer* ps_cBuffer;
|
||||||
static cc_bool ps_alphaTesting, ps_mipmaps;
|
static cc_bool ps_mipmaps;
|
||||||
static float ps_fogEnd, ps_fogDensity;
|
static float ps_fogEnd, ps_fogDensity;
|
||||||
static PackedCol ps_fogColor;
|
static PackedCol ps_fogColor;
|
||||||
static int ps_fogMode;
|
static int ps_fogMode;
|
||||||
|
|
@ -725,7 +725,7 @@ static void PS_CreateShaders(void) {
|
||||||
|
|
||||||
static int PS_CalcShaderIndex(void) {
|
static int PS_CalcShaderIndex(void) {
|
||||||
int idx = gfx_format == VERTEX_FORMAT_COLOURED ? 0 : 1;
|
int idx = gfx_format == VERTEX_FORMAT_COLOURED ? 0 : 1;
|
||||||
if (ps_alphaTesting) idx += 2;
|
if (gfx_alphaTest) idx += 2;
|
||||||
|
|
||||||
if (gfx_fogEnabled) {
|
if (gfx_fogEnabled) {
|
||||||
// uncomment when it works
|
// uncomment when it works
|
||||||
|
|
@ -822,8 +822,7 @@ static void PS_Free(void) {
|
||||||
PS_FreeConstants();
|
PS_FreeConstants();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gfx_SetAlphaTest(cc_bool enabled) {
|
static void SetAlphaTest(cc_bool enabled) {
|
||||||
ps_alphaTesting = enabled;
|
|
||||||
PS_UpdateShader();
|
PS_UpdateShader();
|
||||||
}
|
}
|
||||||
// unnecessary? check if any performance is gained, probably irrelevant
|
// unnecessary? check if any performance is gained, probably irrelevant
|
||||||
|
|
@ -887,10 +886,10 @@ void Gfx_DisableMipmaps(void) {
|
||||||
static ID3D11RenderTargetView* backbuffer;
|
static ID3D11RenderTargetView* backbuffer;
|
||||||
static ID3D11Texture2D* depthbuffer;
|
static ID3D11Texture2D* depthbuffer;
|
||||||
static ID3D11DepthStencilView* depthbufferView;
|
static ID3D11DepthStencilView* depthbufferView;
|
||||||
static ID3D11BlendState* om_blendStates[4];
|
static ID3D11BlendState* om_blendStates[16 * 2];
|
||||||
static ID3D11DepthStencilState* om_depthStates[4];
|
static ID3D11DepthStencilState* om_depthStates[4];
|
||||||
static float gfx_clearColor[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 cc_bool gfx_depthTest, gfx_depthWrite;
|
||||||
|
|
||||||
static void OM_Clear(GfxBuffers buffers) {
|
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++)
|
for (int i = 0; i < Array_Elems(om_blendStates); i++)
|
||||||
{
|
{
|
||||||
desc.RenderTarget[0].RenderTargetWriteMask = (i & 1) ? D3D11_COLOR_WRITE_ENABLE_ALL : 0;
|
int mask = 0;
|
||||||
desc.RenderTarget[0].BlendEnable = (i & 2) != 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]);
|
hr = ID3D11Device_CreateBlendState(device, &desc, &om_blendStates[i]);
|
||||||
if (hr) Logger_Abort2(hr, "Failed to create blend state");
|
if (hr) Logger_Abort2(hr, "Failed to create blend state");
|
||||||
|
|
@ -981,7 +986,8 @@ static void OM_CreateBlendStates(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OM_UpdateBlendState(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);
|
ID3D11DeviceContext_OMSetBlendState(context, blendState, NULL, 0xffffffff);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1030,15 +1036,16 @@ void Gfx_SetDepthWrite(cc_bool enabled) {
|
||||||
OM_UpdateDepthState();
|
OM_UpdateDepthState();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gfx_SetAlphaBlending(cc_bool enabled) {
|
static void SetAlphaBlend(cc_bool enabled) {
|
||||||
gfx_alphaBlending = enabled;
|
|
||||||
OM_UpdateBlendState();
|
OM_UpdateBlendState();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SetColorWrite(cc_bool r, cc_bool g, cc_bool b, cc_bool a) {
|
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();
|
OM_UpdateBlendState();
|
||||||
// TODO all channels
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gfx_DepthOnlyRendering(cc_bool depthOnly) {
|
void Gfx_DepthOnlyRendering(cc_bool depthOnly) {
|
||||||
|
|
|
||||||
|
|
@ -394,7 +394,7 @@ void Gfx_DisableMipmaps(void) {
|
||||||
*-----------------------------------------------------State management----------------------------------------------------*
|
*-----------------------------------------------------State management----------------------------------------------------*
|
||||||
*#########################################################################################################################*/
|
*#########################################################################################################################*/
|
||||||
static D3DFOGMODE gfx_fogMode = D3DFOG_NONE;
|
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 cc_bool gfx_depthTesting, gfx_depthWriting;
|
||||||
static PackedCol gfx_clearColor, gfx_fogColor;
|
static PackedCol gfx_clearColor, gfx_fogColor;
|
||||||
static float gfx_fogEnd = -1.0f, gfx_fogDensity = -1.0f;
|
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);
|
IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gfx_SetAlphaTest(cc_bool enabled) {
|
static void SetAlphaTest(cc_bool enabled) {
|
||||||
if (gfx_alphaTesting == enabled) return;
|
|
||||||
gfx_alphaTesting = enabled;
|
|
||||||
|
|
||||||
if (Gfx.LostContext) return;
|
if (Gfx.LostContext) return;
|
||||||
IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, enabled);
|
IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gfx_SetAlphaBlending(cc_bool enabled) {
|
static void SetAlphaBlend(cc_bool enabled) {
|
||||||
if (gfx_alphaBlending == enabled) return;
|
|
||||||
gfx_alphaBlending = enabled;
|
|
||||||
|
|
||||||
if (Gfx.LostContext) return;
|
if (Gfx.LostContext) return;
|
||||||
IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, enabled);
|
IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, enabled);
|
||||||
}
|
}
|
||||||
|
|
@ -529,7 +523,7 @@ void Gfx_DepthOnlyRendering(cc_bool depthOnly) {
|
||||||
|
|
||||||
static void D3D9_RestoreRenderStates(void) {
|
static void D3D9_RestoreRenderStates(void) {
|
||||||
union IntAndFloat raw;
|
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_ALPHABLENDENABLE, gfx_alphaBlending);
|
||||||
|
|
||||||
IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, gfx_fogEnabled);
|
IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, gfx_fogEnabled);
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
#include "Logger.h"
|
#include "Logger.h"
|
||||||
#include "Window.h"
|
#include "Window.h"
|
||||||
#include "../third_party/gldc/gldc.h"
|
#include "../third_party/gldc/gldc.h"
|
||||||
|
#include "../third_party/gldc/src/draw.c"
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include <kos.h>
|
#include <kos.h>
|
||||||
#include <dc/matrix.h>
|
#include <dc/matrix.h>
|
||||||
|
|
@ -30,6 +31,7 @@ static void InitGLState(void) {
|
||||||
|
|
||||||
void Gfx_Create(void) {
|
void Gfx_Create(void) {
|
||||||
if (!Gfx.Created) glKosInit();
|
if (!Gfx.Created) glKosInit();
|
||||||
|
|
||||||
Gfx_SetViewport(0, 0, Game.Width, Game.Height);
|
Gfx_SetViewport(0, 0, Game.Width, Game.Height);
|
||||||
InitGLState();
|
InitGLState();
|
||||||
|
|
||||||
|
|
@ -59,7 +61,7 @@ void Gfx_Free(void) {
|
||||||
*#########################################################################################################################*/
|
*#########################################################################################################################*/
|
||||||
static PackedCol gfx_clearColor;
|
static PackedCol gfx_clearColor;
|
||||||
void Gfx_SetFaceCulling(cc_bool enabled) { gl_Toggle(GL_CULL_FACE); }
|
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_SetAlphaArgBlend(cc_bool enabled) { }
|
||||||
|
|
||||||
void Gfx_ClearColor(PackedCol color) {
|
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_SetDepthWrite(cc_bool enabled) { glDepthMask(enabled); }
|
||||||
void Gfx_SetDepthTest(cc_bool enabled) { gl_Toggle(GL_DEPTH_TEST); }
|
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) {
|
void Gfx_DepthOnlyRendering(cc_bool depthOnly) {
|
||||||
// don't need a fake second pass in this case
|
// 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) {
|
void Gfx_SetFog(cc_bool enabled) {
|
||||||
gfx_fogEnabled = enabled;
|
gfx_fogEnabled = enabled;
|
||||||
if (enabled) { glEnable(GL_FOG); } else { glDisable(GL_FOG); }
|
gl_Toggle(GL_FOG);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gfx_SetFogCol(PackedCol color) {
|
void Gfx_SetFogCol(PackedCol color) {
|
||||||
|
|
@ -371,7 +373,7 @@ static void UpdateFog(void) {
|
||||||
if (gfx_fogMode == FOG_LINEAR) {
|
if (gfx_fogMode == FOG_LINEAR) {
|
||||||
pvr_fog_table_linear(0.0f, gfx_fogEnd);
|
pvr_fog_table_linear(0.0f, gfx_fogEnd);
|
||||||
} else if (gfx_fogMode == FOG_EXP) {
|
} else if (gfx_fogMode == FOG_EXP) {
|
||||||
pvr_fog_table_exp(gfx_fogDensity);
|
pvr_fog_table_exp(gfx_fogDensity);
|
||||||
} else if (gfx_fogMode == FOG_EXP2) {
|
} else if (gfx_fogMode == FOG_EXP2) {
|
||||||
pvr_fog_table_exp2(gfx_fogDensity);
|
pvr_fog_table_exp2(gfx_fogDensity);
|
||||||
}
|
}
|
||||||
|
|
@ -465,15 +467,35 @@ cc_bool Gfx_WarnIfNecessary(void) {
|
||||||
*----------------------------------------------------------Drawing--------------------------------------------------------*
|
*----------------------------------------------------------Drawing--------------------------------------------------------*
|
||||||
*#########################################################################################################################*/
|
*#########################################################################################################################*/
|
||||||
#define VB_PTR gfx_vertices
|
#define VB_PTR gfx_vertices
|
||||||
|
static const void* VERTEX_PTR;
|
||||||
|
extern void apply_poly_header(PolyHeader* header, PolyList* activePolyList);
|
||||||
|
|
||||||
static void SetupVertices(int startVertex) {
|
extern Vertex* DrawColouredQuads(const void* src, Vertex* dst, int numQuads);
|
||||||
if (gfx_format == VERTEX_FORMAT_TEXTURED) {
|
extern Vertex* DrawTexturedQuads(const void* src, Vertex* dst, int numQuads);
|
||||||
cc_uint32 offset = startVertex * SIZEOF_VERTEX_TEXTURED;
|
|
||||||
gldcVertexPointer(SIZEOF_VERTEX_TEXTURED, (void*)(VB_PTR + offset));
|
void DrawQuads(int count) {
|
||||||
} else {
|
if (!count) return;
|
||||||
cc_uint32 offset = startVertex * SIZEOF_VERTEX_COLOURED;
|
PolyList* output = _glActivePolyList();
|
||||||
gldcVertexPointer(SIZEOF_VERTEX_COLOURED, (void*)(VB_PTR + offset));
|
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) {
|
void Gfx_SetVertexFormat(VertexFormat fmt) {
|
||||||
|
|
@ -489,29 +511,33 @@ void Gfx_SetVertexFormat(VertexFormat fmt) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gfx_DrawVb_Lines(int verticesCount) {
|
void Gfx_DrawVb_Lines(int verticesCount) {
|
||||||
SetupVertices(0);
|
//SetupVertices(0);
|
||||||
//glDrawArrays(GL_LINES, 0, verticesCount);
|
//glDrawArrays(GL_LINES, 0, verticesCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gfx_DrawVb_IndexedTris_Range(int verticesCount, int startVertex) {
|
void Gfx_DrawVb_IndexedTris_Range(int verticesCount, int startVertex) {
|
||||||
SetupVertices(startVertex);
|
if (gfx_format == VERTEX_FORMAT_TEXTURED) {
|
||||||
glDrawArrays(GL_QUADS, 0, verticesCount);
|
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) {
|
void Gfx_DrawVb_IndexedTris(int verticesCount) {
|
||||||
SetupVertices(0);
|
VERTEX_PTR = gfx_vertices;
|
||||||
|
|
||||||
if (textureOffset) ShiftTextureCoords(verticesCount);
|
if (textureOffset) ShiftTextureCoords(verticesCount);
|
||||||
glDrawArrays(GL_QUADS, 0, verticesCount);
|
DrawQuads(verticesCount);
|
||||||
if (textureOffset) UnshiftTextureCoords(verticesCount);
|
if (textureOffset) UnshiftTextureCoords(verticesCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gfx_DrawIndexedTris_T2fC4b(int verticesCount, int startVertex) {
|
void Gfx_DrawIndexedTris_T2fC4b(int verticesCount, int startVertex) {
|
||||||
if (renderingDisabled) return;
|
if (renderingDisabled) return;
|
||||||
|
|
||||||
cc_uint32 offset = startVertex * SIZEOF_VERTEX_TEXTURED;
|
VERTEX_PTR = gfx_vertices + startVertex * SIZEOF_VERTEX_TEXTURED;
|
||||||
gldcVertexPointer(SIZEOF_VERTEX_TEXTURED, (void*)(VB_PTR + offset));
|
DrawQuads(verticesCount);
|
||||||
glDrawArrays(GL_QUADS, 0, verticesCount);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -550,6 +576,7 @@ void Gfx_ClearBuffers(GfxBuffers buffers) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gfx_EndFrame(void) {
|
void Gfx_EndFrame(void) {
|
||||||
|
pvr_wait_ready();
|
||||||
glKosSwapBuffers();
|
glKosSwapBuffers();
|
||||||
if (gfx_minFrameMs) LimitFPS();
|
if (gfx_minFrameMs) LimitFPS();
|
||||||
}
|
}
|
||||||
|
|
@ -558,6 +585,11 @@ void Gfx_OnWindowResize(void) {
|
||||||
Gfx_SetViewport(0, 0, Game.Width, Game.Height);
|
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) {
|
void Gfx_SetViewport(int x, int y, int w, int h) {
|
||||||
if (x == 0 && y == 0 && w == Game.Width && h == Game.Height) {
|
if (x == 0 && y == 0 && w == Game.Width && h == Game.Height) {
|
||||||
glDisable(GL_SCISSOR_TEST);
|
glDisable(GL_SCISSOR_TEST);
|
||||||
|
|
@ -567,5 +599,11 @@ void Gfx_SetViewport(int x, int y, int w, int h) {
|
||||||
|
|
||||||
glViewport(x, y, w, h);
|
glViewport(x, y, w, h);
|
||||||
glScissor (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
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -187,7 +187,7 @@ void Gfx_SetFaceCulling(cc_bool enabled) {
|
||||||
GX_SetCullMode(enabled ? GX_CULL_FRONT : GX_CULL_NONE);
|
GX_SetCullMode(enabled ? GX_CULL_FRONT : GX_CULL_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gfx_SetAlphaBlending(cc_bool enabled) {
|
static void SetAlphaBlend(cc_bool enabled) {
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
GX_SetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR);
|
GX_SetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -409,7 +409,7 @@ void Gfx_SetFogEnd(float value) {
|
||||||
void Gfx_SetFogMode(FogFunc func) {
|
void Gfx_SetFogMode(FogFunc func) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gfx_SetAlphaTest(cc_bool enabled) {
|
static void SetAlphaTest(cc_bool enabled) {
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
GX_SetAlphaCompare(GX_GREATER, 127, GX_AOP_AND, GX_ALWAYS, 0);
|
GX_SetAlphaCompare(GX_GREATER, 127, GX_AOP_AND, GX_ALWAYS, 0);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -560,7 +560,7 @@ static void Draw_ColouredTriangles(int verticesCount, int startVertex) {
|
||||||
struct VertexColoured* v = (struct VertexColoured*)gfx_vertices + startVertex + i;
|
struct VertexColoured* v = (struct VertexColoured*)gfx_vertices + startVertex + i;
|
||||||
|
|
||||||
GX_Position3f32(v->x, v->y, v->z);
|
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();
|
GX_End();
|
||||||
}
|
}
|
||||||
|
|
@ -572,7 +572,7 @@ static void Draw_TexturedTriangles(int verticesCount, int startVertex) {
|
||||||
struct VertexTextured* v = (struct VertexTextured*)gfx_vertices + startVertex + i;
|
struct VertexTextured* v = (struct VertexTextured*)gfx_vertices + startVertex + i;
|
||||||
|
|
||||||
GX_Position3f32(v->x, v->y, v->z);
|
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_TexCoord2f32(v->U, v->V);
|
||||||
}
|
}
|
||||||
GX_End();
|
GX_End();
|
||||||
|
|
|
||||||
|
|
@ -534,7 +534,7 @@ void Gfx_SetFogMode(FogFunc func) {
|
||||||
gfx_fogMode = 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); }
|
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 */
|
/* cached uniforms (cached for multiple programs */
|
||||||
static struct Matrix _view, _proj, _mvp;
|
static struct Matrix _view, _proj, _mvp;
|
||||||
static cc_bool gfx_alphaTest, gfx_texTransform;
|
static cc_bool gfx_texTransform;
|
||||||
static float _texX, _texY;
|
static float _texX, _texY;
|
||||||
static PackedCol gfx_fogColor;
|
static PackedCol gfx_fogColor;
|
||||||
static float gfx_fogEnd = -1.0f, gfx_fogDensity = -1.0f;
|
static float gfx_fogEnd = -1.0f, gfx_fogDensity = -1.0f;
|
||||||
|
|
@ -500,7 +500,7 @@ void Gfx_SetFogMode(FogFunc func) {
|
||||||
SwitchProgram();
|
SwitchProgram();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gfx_SetAlphaTest(cc_bool enabled) { gfx_alphaTest = enabled; SwitchProgram(); }
|
static void SetAlphaTest(cc_bool enabled) { SwitchProgram(); }
|
||||||
|
|
||||||
void Gfx_DepthOnlyRendering(cc_bool depthOnly) {
|
void Gfx_DepthOnlyRendering(cc_bool depthOnly) {
|
||||||
cc_bool enabled = !depthOnly;
|
cc_bool enabled = !depthOnly;
|
||||||
|
|
|
||||||
|
|
@ -237,7 +237,7 @@ void Gfx_DisableMipmaps(void) { }
|
||||||
*-----------------------------------------------------State management----------------------------------------------------*
|
*-----------------------------------------------------State management----------------------------------------------------*
|
||||||
*#########################################################################################################################*/
|
*#########################################################################################################################*/
|
||||||
void Gfx_SetFaceCulling(cc_bool enabled) { gl_Toggle(GL_CULL_FACE); }
|
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_SetAlphaArgBlend(cc_bool enabled) { }
|
||||||
|
|
||||||
static void SetColorWrite(cc_bool r, cc_bool g, cc_bool b, cc_bool a) {
|
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_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); }
|
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));
|
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) {
|
/*if (enabled) {
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -376,7 +376,7 @@ void Gfx_SetFogEnd(float value) {
|
||||||
void Gfx_SetFogMode(FogFunc func) {
|
void Gfx_SetFogMode(FogFunc func) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gfx_SetAlphaTest(cc_bool enabled) {
|
static void SetAlphaTest(cc_bool enabled) {
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
//glEnable(GL_ALPHA_TEST);
|
//glEnable(GL_ALPHA_TEST);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,9 @@ static RenderBuffer buffers[2];
|
||||||
static cc_uint8* next_packet;
|
static cc_uint8* next_packet;
|
||||||
static int active_buffer;
|
static int active_buffer;
|
||||||
static RenderBuffer* buffer;
|
static RenderBuffer* buffer;
|
||||||
|
static cc_bool rendering2D;
|
||||||
|
static void* lastPoly;
|
||||||
|
static cc_bool cullingEnabled;
|
||||||
|
|
||||||
static void OnBufferUpdated(void) {
|
static void OnBufferUpdated(void) {
|
||||||
buffer = &buffers[active_buffer];
|
buffer = &buffers[active_buffer];
|
||||||
|
|
@ -100,7 +103,7 @@ void Gfx_FreeState(void) {
|
||||||
|
|
||||||
void Gfx_Create(void) {
|
void Gfx_Create(void) {
|
||||||
Gfx.MaxTexWidth = 128;
|
Gfx.MaxTexWidth = 128;
|
||||||
Gfx.MaxTexHeight = 128;
|
Gfx.MaxTexHeight = 256;
|
||||||
Gfx.Created = true;
|
Gfx.Created = true;
|
||||||
|
|
||||||
Gfx_RestoreState();
|
Gfx_RestoreState();
|
||||||
|
|
@ -126,30 +129,41 @@ void Gfx_Free(void) {
|
||||||
// VRAM can be divided into texture pages
|
// VRAM can be divided into texture pages
|
||||||
// 32 texture pages total - each page is 64 x 256
|
// 32 texture pages total - each page is 64 x 256
|
||||||
// 10 texture pages are occupied by the doublebuffered display
|
// 10 texture pages are occupied by the doublebuffered display
|
||||||
// 22 texture packs are usable, and are then divided into
|
// 22 texture pages are usable for textures
|
||||||
// - 4 pages for 256 wide textures, 8 for 128 wide, 10 for 64
|
// These 22 pages are then divided into:
|
||||||
#define TPAGE_START_HOR 5
|
// - 5 for 128+ wide horizontal, 6 otherwise
|
||||||
#define TPAGES_PER_HALF 16
|
// - 11 pages for vertical textures
|
||||||
|
|
||||||
#define TPAGE_WIDTH 64
|
#define TPAGE_WIDTH 64
|
||||||
#define TPAGE_HEIGHT 256
|
#define TPAGE_HEIGHT 256
|
||||||
#define MAX_TEX_PAGES 22
|
#define TPAGES_PER_HALF 16
|
||||||
static cc_uint8 vram_used[(MAX_TEX_PAGES * TPAGE_HEIGHT) / 8];
|
|
||||||
|
|
||||||
|
// 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_SetUsed(line) (vram_used[(line) / 8] |= (1 << ((line) % 8)))
|
||||||
#define VRAM_UnUsed(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)))
|
#define VRAM_IsUsed(line) (vram_used[(line) / 8] & (1 << ((line) % 8)))
|
||||||
|
|
||||||
static void VRAM_GetBlockRange(int width, int* beg, int* end) {
|
#define VRAM_BoundingAxis(width, height) height > width ? width : height
|
||||||
if (width >= 256) {
|
|
||||||
*beg = 0;
|
static void VRAM_GetBlockRange(int width, int height, int* beg, int* end) {
|
||||||
*end = 4 * TPAGE_HEIGHT;
|
if (height > width) {
|
||||||
|
*beg = MAX_HOR_TEX_LINES;
|
||||||
|
*end = MAX_HOR_TEX_LINES + MAX_VER_TEX_LINES;
|
||||||
} else if (width >= 128) {
|
} else if (width >= 128) {
|
||||||
*beg = 4 * TPAGE_HEIGHT;
|
*beg = 0;
|
||||||
*end = 12 * TPAGE_HEIGHT;
|
*end = 5 * TPAGE_HEIGHT;
|
||||||
} else {
|
} else {
|
||||||
*beg = 12 * TPAGE_HEIGHT;
|
*beg = 5 * TPAGE_HEIGHT;
|
||||||
*end = 22 * 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) {
|
static int VRAM_FindFreeBlock(int width, int height) {
|
||||||
int beg, end;
|
int beg, end;
|
||||||
VRAM_GetBlockRange(width, &beg, &end);
|
VRAM_GetBlockRange(width, height, &beg, &end);
|
||||||
|
|
||||||
// TODO kinda inefficient
|
// TODO kinda inefficient
|
||||||
for (int i = beg; i < end - height; i++)
|
for (int i = beg; i < end - height; i++)
|
||||||
|
|
@ -175,13 +189,41 @@ static int VRAM_FindFreeBlock(int width, int height) {
|
||||||
return -1;
|
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
|
#define TEXTURES_MAX_COUNT 64
|
||||||
typedef struct GPUTexture {
|
typedef struct GPUTexture {
|
||||||
cc_uint16 width, height;
|
cc_uint16 width, height;
|
||||||
|
cc_uint8 width_mask, height_mask;
|
||||||
cc_uint16 line, tpage;
|
cc_uint16 line, tpage;
|
||||||
|
cc_uint8 xOffset, yOffset;
|
||||||
} GPUTexture;
|
} GPUTexture;
|
||||||
static GPUTexture textures[TEXTURES_MAX_COUNT];
|
static GPUTexture textures[TEXTURES_MAX_COUNT];
|
||||||
static GPUTexture* active_tex;
|
static GPUTexture* curTex;
|
||||||
|
|
||||||
#define BGRA8_to_PS1(src) \
|
#define BGRA8_to_PS1(src) \
|
||||||
((src[2] & 0xF8) >> 3) | ((src[1] & 0xF8) << 2) | ((src[0] & 0xF8) << 7) | ((src[3] & 0x80) << 8)
|
((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);
|
int line = VRAM_FindFreeBlock(bmp->width, bmp->height);
|
||||||
if (line == -1) { Mem_Free(tmp); return NULL; }
|
if (line == -1) { Mem_Free(tmp); return NULL; }
|
||||||
|
|
||||||
tex->width = bmp->width;
|
tex->width = bmp->width; tex->width_mask = bmp->width - 1;
|
||||||
tex->height = bmp->height;
|
tex->height = bmp->height; tex->height_mask = bmp->height - 1;
|
||||||
tex->line = line;
|
tex->line = line;
|
||||||
|
|
||||||
int page = TPAGE_START_HOR + (line / TPAGE_HEIGHT);
|
int page = VRAM_CalcPage(line);
|
||||||
// In bottom half of VRAM? Need to offset horizontally again
|
int pageX = (page % TPAGES_PER_HALF);
|
||||||
if (page >= TPAGES_PER_HALF) page += TPAGE_START_HOR;
|
int pageY = (page / TPAGES_PER_HALF);
|
||||||
|
|
||||||
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;
|
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("%i x %i = %i", &bmp->width, &bmp->height, &line);
|
||||||
Platform_Log3(" at %i (%i, %i)", &page, &pageX, &pageY);
|
Platform_Log3(" at %i (%i, %i)", &page, &pageX, &pageY);
|
||||||
|
|
||||||
RECT rect;
|
RECT rect;
|
||||||
rect.x = pageX * TPAGE_WIDTH;
|
rect.x = pageX * TPAGE_WIDTH + tex->xOffset;
|
||||||
rect.y = pageY * TPAGE_HEIGHT + (line % TPAGE_HEIGHT);
|
rect.y = pageY * TPAGE_HEIGHT + tex->yOffset;
|
||||||
rect.w = bmp->width;
|
rect.w = bmp->width;
|
||||||
rect.h = bmp->height;
|
rect.h = bmp->height;
|
||||||
|
|
||||||
|
|
@ -251,7 +295,7 @@ static GfxResourceID Gfx_AllocTexture(struct Bitmap* bmp, int rowWidth, cc_uint8
|
||||||
|
|
||||||
void Gfx_BindTexture(GfxResourceID texId) {
|
void Gfx_BindTexture(GfxResourceID texId) {
|
||||||
if (!texId) texId = white_square;
|
if (!texId) texId = white_square;
|
||||||
active_tex = (GPUTexture*)texId;
|
curTex = (GPUTexture*)texId;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gfx_DeleteTexture(GfxResourceID* texId) {
|
void Gfx_DeleteTexture(GfxResourceID* texId) {
|
||||||
|
|
@ -259,10 +303,7 @@ void Gfx_DeleteTexture(GfxResourceID* texId) {
|
||||||
if (!data) return;
|
if (!data) return;
|
||||||
GPUTexture* tex = (GPUTexture*)data;
|
GPUTexture* tex = (GPUTexture*)data;
|
||||||
|
|
||||||
for (int i = tex->line; i < tex->line + tex->height; i++)
|
VRAM_FreeBlock(tex->line, tex->width, tex->height);
|
||||||
{
|
|
||||||
VRAM_UnUsed(i);
|
|
||||||
}
|
|
||||||
tex->width = 0; tex->height = 0;
|
tex->width = 0; tex->height = 0;
|
||||||
*texId = NULL;
|
*texId = NULL;
|
||||||
}
|
}
|
||||||
|
|
@ -285,13 +326,13 @@ void Gfx_SetFogEnd(float value) { }
|
||||||
void Gfx_SetFogMode(FogFunc func) { }
|
void Gfx_SetFogMode(FogFunc func) { }
|
||||||
|
|
||||||
void Gfx_SetFaceCulling(cc_bool enabled) {
|
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) { }
|
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;
|
cc_bool VERTEX_LOGGING;
|
||||||
static void DrawColouredQuads(int verticesCount, int startVertex) {
|
|
||||||
|
static void DrawColouredQuads2D(int verticesCount, int startVertex) {
|
||||||
return;
|
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)
|
for (int i = 0; i < verticesCount; i += 4)
|
||||||
{
|
{
|
||||||
struct VertexColoured* v = (struct VertexColoured*)gfx_vertices + startVertex + i;
|
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) {
|
static void DrawTexturedQuads3D(int verticesCount, int startVertex) {
|
||||||
int pageOffset = active_tex->line % TPAGE_HEIGHT;
|
int uOffset = curTex->xOffset, vOffset = curTex->yOffset;
|
||||||
|
|
||||||
for (int i = 0; i < verticesCount; i += 4)
|
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));
|
POLY_FT4* poly = new_primitive(sizeof(POLY_FT4));
|
||||||
setPolyFT4(poly);
|
setPolyFT4(poly);
|
||||||
poly->tpage = active_tex->tpage;
|
poly->tpage = curTex->tpage;
|
||||||
poly->clut = 0;
|
poly->clut = 0;
|
||||||
|
|
||||||
Vec3 coords[4];
|
Vec3 coords[4];
|
||||||
|
|
@ -586,12 +696,28 @@ static void DrawTexturedQuads(int verticesCount, int startVertex) {
|
||||||
Transform(&coords[3], &v[3], &mvp);
|
Transform(&coords[3], &v[3], &mvp);
|
||||||
|
|
||||||
// TODO & instead of %
|
// 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->x0 = coords[1].x; poly->y0 = coords[1].y;
|
||||||
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->x1 = coords[0].x; poly->y1 = coords[0].y;
|
||||||
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->x2 = coords[2].x; poly->y2 = coords[2].y;
|
||||||
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->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);
|
//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;
|
int p = (coords[0].z + coords[1].z + coords[2].z + coords[3].z) / 4;
|
||||||
if (p < 0 || p >= OT_LENGTH) continue;
|
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);
|
//if (VERTEX_LOGGING) Platform_Log3("IN: %i, %i, %i", &X, &Y, &Z);
|
||||||
X = poly->x1; Y = poly->y1, Z = coords[0].z;
|
X = poly->x1; Y = poly->y1, Z = coords[0].z;
|
||||||
|
|
||||||
poly->r0 = PackedCol_R(v->Col);
|
poly->r0 = PackedCol_R(v->Col) >> 1;
|
||||||
poly->g0 = PackedCol_G(v->Col);
|
poly->g0 = PackedCol_G(v->Col) >> 1;
|
||||||
poly->b0 = PackedCol_B(v->Col);
|
poly->b0 = PackedCol_B(v->Col) >> 1;
|
||||||
//if (VERTEX_LOGGING) Platform_Log4("OUT: %i, %i, %i (%i)", &X, &Y, &Z, &p);
|
//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
|
// 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) {
|
static void DrawQuads(int verticesCount, int startVertex) {
|
||||||
if (gfx_format == VERTEX_FORMAT_TEXTURED) {
|
if (rendering2D && gfx_format == VERTEX_FORMAT_TEXTURED) {
|
||||||
DrawTexturedQuads(verticesCount, startVertex);
|
DrawTexturedQuads2D(verticesCount, startVertex);
|
||||||
|
} else if (rendering2D) {
|
||||||
|
DrawColouredQuads2D(verticesCount, startVertex);
|
||||||
|
} else if (gfx_format == VERTEX_FORMAT_TEXTURED) {
|
||||||
|
DrawTexturedQuads3D(verticesCount, startVertex);
|
||||||
} else {
|
} 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) {
|
void Gfx_DrawVb_IndexedTris(int verticesCount) {
|
||||||
if (gfx_format == VERTEX_FORMAT_TEXTURED) {
|
DrawQuads(verticesCount, 0);
|
||||||
DrawTexturedQuads(verticesCount, 0);
|
|
||||||
} else {
|
|
||||||
DrawColouredQuads(verticesCount, 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gfx_DrawIndexedTris_T2fC4b(int verticesCount, int startVertex) {
|
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) {
|
void Gfx_BeginFrame(void) {
|
||||||
|
lastPoly = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gfx_EndFrame(void) {
|
void Gfx_EndFrame(void) {
|
||||||
|
|
@ -735,4 +867,14 @@ void Gfx_GetApiInfo(cc_string* info) {
|
||||||
}
|
}
|
||||||
|
|
||||||
cc_bool Gfx_TryRestoreContext(void) { return true; }
|
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
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -243,8 +243,6 @@ void Gfx_DisableMipmaps(void) { }
|
||||||
*------------------------------------------------------State management---------------------------------------------------*
|
*------------------------------------------------------State management---------------------------------------------------*
|
||||||
*#########################################################################################################################*/
|
*#########################################################################################################################*/
|
||||||
static int clearR, clearG, clearB;
|
static int clearR, clearG, clearB;
|
||||||
static cc_bool gfx_alphaBlend;
|
|
||||||
static cc_bool gfx_alphaTest;
|
|
||||||
static cc_bool gfx_depthTest;
|
static cc_bool gfx_depthTest;
|
||||||
static cc_bool stateDirty;
|
static cc_bool stateDirty;
|
||||||
|
|
||||||
|
|
@ -274,13 +272,11 @@ void Gfx_SetFaceCulling(cc_bool enabled) {
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gfx_SetAlphaTest(cc_bool enabled) {
|
static void SetAlphaTest(cc_bool enabled) {
|
||||||
gfx_alphaTest = enabled;
|
stateDirty = true;
|
||||||
stateDirty = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gfx_SetAlphaBlending(cc_bool enabled) {
|
static void SetAlphaBlend(cc_bool enabled) {
|
||||||
gfx_alphaBlend = enabled;
|
|
||||||
// TODO update primitive state
|
// TODO update primitive state
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -286,7 +286,7 @@ void Gfx_SetFaceCulling(cc_bool enabled) {
|
||||||
rsxSetCullFaceEnable(context, enabled);
|
rsxSetCullFaceEnable(context, enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gfx_SetAlphaBlending(cc_bool enabled) {
|
static void SetAlphaBlend(cc_bool enabled) {
|
||||||
rsxSetBlendEnable(context, enabled);
|
rsxSetBlendEnable(context, enabled);
|
||||||
}
|
}
|
||||||
void Gfx_SetAlphaArgBlend(cc_bool enabled) { }
|
void Gfx_SetAlphaArgBlend(cc_bool enabled) { }
|
||||||
|
|
@ -316,7 +316,7 @@ void Gfx_SetDepthTest(cc_bool enabled) {
|
||||||
UpdateDepthState();
|
UpdateDepthState();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gfx_SetAlphaTest(cc_bool enabled) {
|
static void SetAlphaTest(cc_bool enabled) {
|
||||||
rsxSetAlphaTestEnable(context, enabled);
|
rsxSetAlphaTestEnable(context, enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -163,7 +163,7 @@ void Gfx_BindTexture(GfxResourceID texId) {
|
||||||
*#########################################################################################################################*/
|
*#########################################################################################################################*/
|
||||||
static PackedCol gfx_clearColor;
|
static PackedCol gfx_clearColor;
|
||||||
void Gfx_SetFaceCulling(cc_bool enabled) { GU_Toggle(GU_CULL_FACE); }
|
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_SetAlphaArgBlend(cc_bool enabled) { }
|
||||||
|
|
||||||
void Gfx_ClearColor(PackedCol color) {
|
void Gfx_ClearColor(PackedCol color) {
|
||||||
|
|
@ -377,7 +377,7 @@ void Gfx_SetFogMode(FogFunc func) {
|
||||||
/* TODO: Implemen fake exp/exp2 fog */
|
/* 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) {
|
void Gfx_DepthOnlyRendering(cc_bool depthOnly) {
|
||||||
cc_bool enabled = !depthOnly;
|
cc_bool enabled = !depthOnly;
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@
|
||||||
|
|
||||||
// TODO track last frame used on
|
// TODO track last frame used on
|
||||||
static cc_bool gfx_depthOnly;
|
static cc_bool gfx_depthOnly;
|
||||||
static cc_bool gfx_alphaTesting, gfx_alphaBlending;
|
|
||||||
static int frontBufferIndex, backBufferIndex;
|
static int frontBufferIndex, backBufferIndex;
|
||||||
// Inspired from
|
// Inspired from
|
||||||
// https://github.com/xerpi/gxmfun/blob/master/source/main.c
|
// 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]
|
// [normal rendering, blend rendering, no rendering]
|
||||||
if (gfx_depthOnly) {
|
if (gfx_depthOnly) {
|
||||||
index += 2;
|
index += 2;
|
||||||
} else if (gfx_alphaBlending) {
|
} else if (gfx_alphaBlend) {
|
||||||
index += 1;
|
index += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gfx_alphaTesting) index += 2 * 3;
|
if (gfx_alphaTest) index += 2 * 3;
|
||||||
|
|
||||||
FragmentProgram* FP = &FP_list[index];
|
FragmentProgram* FP = &FP_list[index];
|
||||||
if (FP == FP_Active) return;
|
if (FP == FP_Active) return;
|
||||||
|
|
@ -964,13 +963,11 @@ void Gfx_SetFogMode(FogFunc func) {
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gfx_SetAlphaTest(cc_bool enabled) {
|
static void SetAlphaTest(cc_bool enabled) {
|
||||||
gfx_alphaTesting = enabled;
|
|
||||||
FP_SwitchActive();
|
FP_SwitchActive();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gfx_SetAlphaBlending(cc_bool enabled) {
|
static void SetAlphaBlend(cc_bool enabled) {
|
||||||
gfx_alphaBlending = enabled;
|
|
||||||
FP_SwitchActive();
|
FP_SwitchActive();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -143,10 +143,10 @@ void Gfx_SetFaceCulling(cc_bool enabled) {
|
||||||
// TODO
|
// 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) { }
|
void Gfx_SetAlphaArgBlend(cc_bool enabled) { }
|
||||||
|
|
|
||||||
|
|
@ -10,9 +10,6 @@ static struct Bitmap fb_bmp;
|
||||||
static float vp_hwidth, vp_hheight;
|
static float vp_hwidth, vp_hheight;
|
||||||
static int sc_maxX, sc_maxY;
|
static int sc_maxX, sc_maxY;
|
||||||
|
|
||||||
static cc_bool alphaBlending;
|
|
||||||
static cc_bool alphaTest;
|
|
||||||
|
|
||||||
static PackedCol* colorBuffer;
|
static PackedCol* colorBuffer;
|
||||||
static PackedCol clearColor;
|
static PackedCol clearColor;
|
||||||
static cc_bool colWrite = true;
|
static cc_bool colWrite = true;
|
||||||
|
|
@ -115,12 +112,12 @@ void Gfx_SetFaceCulling(cc_bool enabled) {
|
||||||
faceCulling = enabled;
|
faceCulling = enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gfx_SetAlphaTest(cc_bool enabled) {
|
static void SetAlphaTest(cc_bool enabled) {
|
||||||
alphaTest = enabled;
|
/* Uses value from Gfx_SetAlphaTest */
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gfx_SetAlphaBlending(cc_bool enabled) {
|
static void SetAlphaBlend(cc_bool enabled) {
|
||||||
alphaBlending = enabled;
|
/* Uses value from Gfx_SetAlphaBlending */
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gfx_SetAlphaArgBlend(cc_bool enabled) { }
|
void Gfx_SetAlphaArgBlend(cc_bool enabled) { }
|
||||||
|
|
@ -358,7 +355,7 @@ static void DrawTriangle(Vector4 frag1, Vector4 frag2, Vector4 frag3,
|
||||||
for (int x = minX; x <= maxX; x++) {
|
for (int x = minX; x <= maxX; x++) {
|
||||||
float xx = x + 0.5f;
|
float xx = x + 0.5f;
|
||||||
|
|
||||||
float ic0 = ((y2 - y3) * (xx - x3) + (x3 - x2) * (yy - y3)) * factor;
|
float ic0 = ((y2 - y3) * (xx - x3) + (x3 - x2) * (yy - y3)) * factor;
|
||||||
if (ic0 < 0 || ic0 > 1) continue;
|
if (ic0 < 0 || ic0 > 1) continue;
|
||||||
float ic1 = ((y3 - y1) * (xx - x3) + (x1 - x3) * (yy - y3)) * factor;
|
float ic1 = ((y3 - y1) * (xx - x3) + (x1 - x3) * (yy - y3)) * factor;
|
||||||
if (ic1 < 0 || ic1 > 1) continue;
|
if (ic1 < 0 || ic1 > 1) continue;
|
||||||
|
|
@ -391,7 +388,7 @@ static void DrawTriangle(Vector4 frag1, Vector4 frag2, Vector4 frag3,
|
||||||
int B = PackedCol_B(fragColor);
|
int B = PackedCol_B(fragColor);
|
||||||
int A = PackedCol_A(fragColor);
|
int A = PackedCol_A(fragColor);
|
||||||
|
|
||||||
if (alphaBlending) {
|
if (gfx_alphaBlend) {
|
||||||
PackedCol dst = colorBuffer[index];
|
PackedCol dst = colorBuffer[index];
|
||||||
int dstR = BitmapCol_R(dst);
|
int dstR = BitmapCol_R(dst);
|
||||||
int dstG = BitmapCol_G(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;
|
G = (G * A) / 255 + (dstG * (255 - A)) / 255;
|
||||||
B = (B * A) / 255 + (dstB * (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;
|
if (depthWrite) depthBuffer[index] = z;
|
||||||
colorBuffer[index] = BitmapCol_Make(R, G, B, 0xFF);
|
colorBuffer[index] = BitmapCol_Make(R, G, B, 0xFF);
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,6 @@ static GfxResourceID white_square;
|
||||||
static WHBGfxShaderGroup* group;
|
static WHBGfxShaderGroup* group;
|
||||||
|
|
||||||
static void InitGfx(void) {
|
static void InitGfx(void) {
|
||||||
WHBGfxInit();
|
|
||||||
GX2InitSampler(&sampler, GX2_TEX_CLAMP_MODE_WRAP, GX2_TEX_XY_FILTER_MODE_POINT);
|
GX2InitSampler(&sampler, GX2_TEX_CLAMP_MODE_WRAP, GX2_TEX_XY_FILTER_MODE_POINT);
|
||||||
|
|
||||||
WHBGfxLoadGFDShaderGroup(&colorShader, 0, coloured_gsh);
|
WHBGfxLoadGFDShaderGroup(&colorShader, 0, coloured_gsh);
|
||||||
|
|
@ -86,7 +85,9 @@ static void Gfx_RestoreState(void) {
|
||||||
static GX2Texture* pendingTex;
|
static GX2Texture* pendingTex;
|
||||||
|
|
||||||
static GfxResourceID Gfx_AllocTexture(struct Bitmap* bmp, int rowWidth, cc_uint8 flags, cc_bool mipmaps) {
|
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
|
// TODO handle out of memory better
|
||||||
int width = bmp->width, height = bmp->height;
|
int width = bmp->width, height = bmp->height;
|
||||||
tex->surface.width = width;
|
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);
|
tex->compMap = GX2_COMP_MAP(GX2_SQ_SEL_R, GX2_SQ_SEL_G, GX2_SQ_SEL_B, GX2_SQ_SEL_A);
|
||||||
GX2CalcSurfaceSizeAndAlignment(&tex->surface);
|
GX2CalcSurfaceSizeAndAlignment(&tex->surface);
|
||||||
GX2InitTextureRegs(tex);
|
GX2InitTextureRegs(tex);
|
||||||
|
|
||||||
tex->surface.image = MEMAllocFromDefaultHeapEx(tex->surface.imageSize, tex->surface.alignment);
|
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);
|
CopyTextureData(tex->surface.image, tex->surface.pitch << 2, bmp, rowWidth << 2);
|
||||||
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_TEXTURE, tex->surface.image, tex->surface.imageSize);
|
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_TEXTURE, tex->surface.image, tex->surface.imageSize);
|
||||||
|
|
@ -175,16 +177,16 @@ void Gfx_SetFogMode(FogFunc func) {
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gfx_SetAlphaTest(cc_bool enabled) {
|
static void SetAlphaTest(cc_bool enabled) {
|
||||||
GX2SetAlphaTest(enabled, GX2_COMPARE_FUNC_GEQUAL, 0.5f);
|
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,
|
GX2SetBlendControl(GX2_RENDER_TARGET_0,
|
||||||
GX2_BLEND_MODE_SRC_ALPHA, GX2_BLEND_MODE_INV_SRC_ALPHA, GX2_BLEND_COMBINE_MODE_ADD,
|
GX2_BLEND_MODE_SRC_ALPHA, GX2_BLEND_MODE_INV_SRC_ALPHA, GX2_BLEND_COMBINE_MODE_ADD,
|
||||||
true,
|
true,
|
||||||
GX2_BLEND_MODE_SRC_ALPHA, GX2_BLEND_MODE_INV_SRC_ALPHA, GX2_BLEND_COMBINE_MODE_ADD);
|
GX2_BLEND_MODE_SRC_ALPHA, GX2_BLEND_MODE_INV_SRC_ALPHA, GX2_BLEND_COMBINE_MODE_ADD);
|
||||||
GX2SetColorControl(GX2_LOGIC_OP_COPY, enabled, FALSE, TRUE);
|
GX2SetColorControl(GX2_LOGIC_OP_COPY, enabled, FALSE, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gfx_SetAlphaArgBlend(cc_bool enabled) {
|
void Gfx_SetAlphaArgBlend(cc_bool enabled) {
|
||||||
|
|
@ -431,12 +433,18 @@ void Gfx_ClearBuffers(GfxBuffers buffers) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int drc_ticks;
|
||||||
void Gfx_EndFrame(void) {
|
void Gfx_EndFrame(void) {
|
||||||
GX2ColorBuffer* buf;
|
GX2ColorBuffer* buf;
|
||||||
|
|
||||||
buf = WHBGfxGetTVColourBuffer();
|
buf = WHBGfxGetTVColourBuffer();
|
||||||
GX2CopyColorBufferToScanBuffer(buf, GX2_SCAN_TARGET_TV);
|
GX2CopyColorBufferToScanBuffer(buf, GX2_SCAN_TARGET_TV);
|
||||||
|
|
||||||
|
GX2ContextState* state = WHBGfxGetDRCContextState();
|
||||||
|
GX2SetContextState(state);
|
||||||
|
drc_ticks = (drc_ticks + 1) % 200;
|
||||||
buf = WHBGfxGetDRCColourBuffer();
|
buf = WHBGfxGetDRCColourBuffer();
|
||||||
|
GX2ClearColor(buf, drc_ticks / 200.0f, drc_ticks / 200.0f, drc_ticks / 200.0f, 1.0f);
|
||||||
GX2CopyColorBufferToScanBuffer(buf, GX2_SCAN_TARGET_DRC);
|
GX2CopyColorBufferToScanBuffer(buf, GX2_SCAN_TARGET_DRC);
|
||||||
|
|
||||||
GX2SwapScanBuffers();
|
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) {
|
void Gfx_3DS_SetRenderScreen1(enum Screen3DS screen) {
|
||||||
GX2ContextState* tv_state = WHBGfxGetTVContextState();
|
GX2ContextState* tv_state = WHBGfxGetTVContextState();
|
||||||
|
|
@ -467,4 +478,4 @@ void Gfx_3DS_SetRenderScreen1(enum Screen3DS screen) {
|
||||||
|
|
||||||
GX2SetContextState(screen == TOP_SCREEN ? tv_state : drc_state);
|
GX2SetContextState(screen == TOP_SCREEN ? tv_state : drc_state);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -299,13 +299,13 @@ void Gfx_SetFaceCulling(cc_bool enabled) {
|
||||||
|
|
||||||
void Gfx_SetAlphaArgBlend(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();
|
uint32_t* p = pb_begin();
|
||||||
p = pb_push1(p, NV097_SET_BLEND_ENABLE, enabled);
|
p = pb_push1(p, NV097_SET_BLEND_ENABLE, enabled);
|
||||||
pb_end(p);
|
pb_end(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gfx_SetAlphaTest(cc_bool enabled) {
|
static void SetAlphaTest(cc_bool enabled) {
|
||||||
uint32_t* p = pb_begin();
|
uint32_t* p = pb_begin();
|
||||||
p = pb_push1(p, NV097_SET_ALPHA_TEST_ENABLE, enabled);
|
p = pb_push1(p, NV097_SET_ALPHA_TEST_ENABLE, enabled);
|
||||||
pb_end(p);
|
pb_end(p);
|
||||||
|
|
@ -396,7 +396,6 @@ void Gfx_EndFrame(void) {
|
||||||
*----------------------------------------------------------Buffers--------------------------------------------------------*
|
*----------------------------------------------------------Buffers--------------------------------------------------------*
|
||||||
*#########################################################################################################################*/
|
*#########################################################################################################################*/
|
||||||
static cc_uint8* gfx_vertices;
|
static cc_uint8* gfx_vertices;
|
||||||
static cc_uint16* gfx_indices;
|
|
||||||
|
|
||||||
static void* AllocBuffer(int count, int elemSize) {
|
static void* AllocBuffer(int count, int elemSize) {
|
||||||
return MmAllocateContiguousMemoryEx(count * elemSize, 0, MAX_RAM_ADDR, 16, PAGE_WRITECOMBINE | PAGE_READWRITE);
|
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) {
|
GfxResourceID Gfx_CreateIb2(int count, Gfx_FillIBFunc fillFunc, void* obj) {
|
||||||
void* ib = AllocBuffer(count, sizeof(cc_uint16));
|
return (void*)1;
|
||||||
if (!ib) Logger_Abort("Failed to allocate memory for index buffer");
|
|
||||||
|
|
||||||
fillFunc(ib, count, obj);
|
|
||||||
return ib;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
static GfxResourceID Gfx_AllocStaticVb(VertexFormat fmt, int count) {
|
||||||
|
|
@ -476,6 +471,18 @@ void Gfx_SetFog(cc_bool enabled) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gfx_SetFogCol(PackedCol color) {
|
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) {
|
void Gfx_SetFogDensity(float value) {
|
||||||
|
|
@ -536,8 +543,8 @@ void Gfx_CalcPerspectiveMatrix(struct Matrix* matrix, float fov, float aspect, f
|
||||||
|
|
||||||
void Gfx_OnWindowResize(void) { }
|
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 struct Matrix _view, _proj, _mvp;
|
||||||
|
|
||||||
static void UpdateVSConstants(void) {
|
static void UpdateVSConstants(void) {
|
||||||
|
|
@ -655,16 +662,16 @@ static void DrawArrays(int mode, int start, int count) {
|
||||||
uint32_t *p = pb_begin();
|
uint32_t *p = pb_begin();
|
||||||
p = pb_push1(p, NV097_SET_BEGIN_END, mode);
|
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)
|
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,
|
p = pb_push1(p, 0x40000000 | NV097_DRAW_ARRAYS,
|
||||||
MASK(NV097_DRAW_ARRAYS_COUNT, (batch_count-1)) |
|
MASK(NV097_DRAW_ARRAYS_COUNT, (batch_count-1)) |
|
||||||
MASK(NV097_DRAW_ARRAYS_START_INDEX, start));
|
MASK(NV097_DRAW_ARRAYS_START_INDEX, start));
|
||||||
|
|
||||||
start += batch_count;
|
start += batch_count;
|
||||||
count -= batch_count;
|
count -= batch_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -676,9 +683,7 @@ void Gfx_DrawVb_Lines(int verticesCount) {
|
||||||
DrawArrays(NV097_SET_BEGIN_END_OP_LINES, 0, verticesCount);
|
DrawArrays(NV097_SET_BEGIN_END_OP_LINES, 0, verticesCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MAX_BATCH 120
|
|
||||||
static void DrawIndexedVertices(int verticesCount, int startVertex) {
|
static void DrawIndexedVertices(int verticesCount, int startVertex) {
|
||||||
// TODO switch to indexed rendering
|
|
||||||
DrawArrays(NV097_SET_BEGIN_END_OP_QUADS, startVertex, verticesCount);
|
DrawArrays(NV097_SET_BEGIN_END_OP_QUADS, startVertex, verticesCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,7 @@ static void Gfx_FreeState(void) {
|
||||||
static void Gfx_RestoreState(void) {
|
static void Gfx_RestoreState(void) {
|
||||||
InitDefaultResources();
|
InitDefaultResources();
|
||||||
Gfx_SetFaceCulling(false);
|
Gfx_SetFaceCulling(false);
|
||||||
Gfx_SetAlphaBlending(false);
|
SetAlphaBlend(false);
|
||||||
|
|
||||||
Xe_SetAlphaFunc(xe, XE_CMP_GREATER);
|
Xe_SetAlphaFunc(xe, XE_CMP_GREATER);
|
||||||
Xe_SetAlphaRef(xe, 0.5f);
|
Xe_SetAlphaRef(xe, 0.5f);
|
||||||
|
|
@ -155,11 +155,11 @@ void Gfx_SetFogMode(FogFunc func) {
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gfx_SetAlphaTest(cc_bool enabled) {
|
static void SetAlphaTest(cc_bool enabled) {
|
||||||
Xe_SetAlphaTestEnable(xe, enabled);
|
Xe_SetAlphaTestEnable(xe, enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gfx_SetAlphaBlending(cc_bool enabled) {
|
static void SetAlphaBlend(cc_bool enabled) {
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
Xe_SetBlendControl(xe,
|
Xe_SetBlendControl(xe,
|
||||||
XE_BLEND_SRCALPHA, XE_BLENDOP_ADD, XE_BLEND_INVSRCALPHA,
|
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) {
|
void Gui_Add(struct Screen* s, int priority) {
|
||||||
struct Screen* existing;
|
struct Screen* existing;
|
||||||
int i;
|
|
||||||
Gui_RemoveCore(s);
|
Gui_RemoveCore(s);
|
||||||
|
|
||||||
existing = Gui_GetScreen(priority);
|
existing = Gui_GetScreen(priority);
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ CC_VAR extern struct _GuiData {
|
||||||
float RawHotbarScale, RawChatScale, RawInventoryScale, RawCrosshairScale;
|
float RawHotbarScale, RawChatScale, RawInventoryScale, RawCrosshairScale;
|
||||||
GfxResourceID GuiTex, GuiClassicTex, IconsTex, TouchTex;
|
GfxResourceID GuiTex, GuiClassicTex, IconsTex, TouchTex;
|
||||||
int DefaultLines;
|
int DefaultLines;
|
||||||
int __unused;
|
int _unused;
|
||||||
float RawTouchScale;
|
float RawTouchScale;
|
||||||
/* The highest priority screen that has grabbed input. */
|
/* The highest priority screen that has grabbed input. */
|
||||||
struct Screen* InputGrab;
|
struct Screen* InputGrab;
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,6 @@ static void HeldBlockRenderer_RenderModel(void) {
|
||||||
SetHeldModel(model);
|
SetHeldModel(model);
|
||||||
Vec3_Set(held_entity.ModelScale, 1.0f,1.0f,1.0f);
|
Vec3_Set(held_entity.ModelScale, 1.0f,1.0f,1.0f);
|
||||||
|
|
||||||
Gfx_SetAlphaTest(true);
|
|
||||||
Model_RenderArm(model, &held_entity);
|
Model_RenderArm(model, &held_entity);
|
||||||
Gfx_SetAlphaTest(false);
|
Gfx_SetAlphaTest(false);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,14 @@ static void Http_ParseCookie(struct HttpRequest* req, const cc_string* value) {
|
||||||
EntryList_Set(req->cookies, &name, &data, '=');
|
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 */
|
/* Parses a HTTP header */
|
||||||
static void Http_ParseHeader(struct HttpRequest* req, const cc_string* line) {
|
static void Http_ParseHeader(struct HttpRequest* req, const cc_string* line) {
|
||||||
static const cc_string httpVersion = String_FromConst("HTTP");
|
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")) {
|
if (String_CaselessEqualsConst(&name, "ETag")) {
|
||||||
String_CopyToRawArray(req->etag, &value);
|
String_CopyToRawArray(req->etag, &value);
|
||||||
} else if (String_CaselessEqualsConst(&name, "Content-Length")) {
|
} 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")) {
|
} else if (String_CaselessEqualsConst(&name, "X-Dropbox-Content-Length")) {
|
||||||
/* dropbox stopped returning Content-Length header since switching to chunked transfer */
|
/* 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 */
|
/* 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")) {
|
} else if (String_CaselessEqualsConst(&name, "Last-Modified")) {
|
||||||
String_CopyToRawArray(req->lastModified, &value);
|
String_CopyToRawArray(req->lastModified, &value);
|
||||||
} else if (req->cookies && String_CaselessEqualsConst(&name, "Set-Cookie")) {
|
} 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) {
|
static cc_result HttpConnection_Read(struct HttpConnection* conn, cc_uint8* data, cc_uint32 count, cc_uint32* read) {
|
||||||
if (conn->sslCtx)
|
if (conn->sslCtx)
|
||||||
return SSL_Read(conn->sslCtx, data, count, read);
|
return SSL_Read(conn->sslCtx, data, count, read);
|
||||||
|
|
||||||
return Socket_Read(conn->socket, 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)
|
if (conn->sslCtx)
|
||||||
return SSL_Write(conn->sslCtx, data, count, wrote);
|
return SSL_WriteAll(conn->sslCtx, data, count);
|
||||||
return Socket_Write(conn->socket, data, count, wrote);
|
|
||||||
|
return Socket_WriteAll(conn->socket, data, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -556,6 +566,7 @@ static cc_result ConnectionPool_Open(struct HttpConnection** conn, const struct
|
||||||
*--------------------------------------------------------HttpClient-------------------------------------------------------*
|
*--------------------------------------------------------HttpClient-------------------------------------------------------*
|
||||||
*#########################################################################################################################*/
|
*#########################################################################################################################*/
|
||||||
enum HTTP_RESPONSE_STATE {
|
enum HTTP_RESPONSE_STATE {
|
||||||
|
HTTP_RESPONSE_STATE_INITIAL,
|
||||||
HTTP_RESPONSE_STATE_HEADER,
|
HTTP_RESPONSE_STATE_HEADER,
|
||||||
HTTP_RESPONSE_STATE_DATA,
|
HTTP_RESPONSE_STATE_DATA,
|
||||||
HTTP_RESPONSE_STATE_CHUNK_HEADER,
|
HTTP_RESPONSE_STATE_CHUNK_HEADER,
|
||||||
|
|
@ -581,7 +592,7 @@ struct HttpClientState {
|
||||||
};
|
};
|
||||||
|
|
||||||
static void HttpClientState_Reset(struct HttpClientState* state) {
|
static void HttpClientState_Reset(struct HttpClientState* state) {
|
||||||
state->state = HTTP_RESPONSE_STATE_HEADER;
|
state->state = HTTP_RESPONSE_STATE_INITIAL;
|
||||||
state->chunked = 0;
|
state->chunked = 0;
|
||||||
state->dataLeft = 0;
|
state->dataLeft = 0;
|
||||||
state->autoClose = false;
|
state->autoClose = false;
|
||||||
|
|
@ -621,15 +632,13 @@ static void HttpClient_Serialise(struct HttpClientState* state) {
|
||||||
static cc_result HttpClient_SendRequest(struct HttpClientState* state) {
|
static cc_result HttpClient_SendRequest(struct HttpClientState* state) {
|
||||||
char inputBuffer[16384];
|
char inputBuffer[16384];
|
||||||
cc_string inputMsg;
|
cc_string inputMsg;
|
||||||
cc_uint32 wrote;
|
|
||||||
|
|
||||||
String_InitArray(inputMsg, inputBuffer);
|
String_InitArray(inputMsg, inputBuffer);
|
||||||
state->req->meta = &inputMsg;
|
state->req->meta = &inputMsg;
|
||||||
state->req->progress = HTTP_PROGRESS_FETCHING_DATA;
|
state->req->progress = HTTP_PROGRESS_FETCHING_DATA;
|
||||||
HttpClient_Serialise(state);
|
HttpClient_Serialise(state);
|
||||||
|
|
||||||
/* TODO check that wrote is >= inputMsg.length */
|
return HttpConnection_Write(state->conn, (cc_uint8*)inputBuffer, inputMsg.length);
|
||||||
return HttpConnection_Write(state->conn, (cc_uint8*)inputBuffer, inputMsg.length, &wrote);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -705,6 +714,9 @@ static cc_result HttpClient_Process(struct HttpClientState* state, char* buffer,
|
||||||
|
|
||||||
while (offset < total) {
|
while (offset < total) {
|
||||||
switch (state->state) {
|
switch (state->state) {
|
||||||
|
case HTTP_RESPONSE_STATE_INITIAL:
|
||||||
|
state->state = HTTP_RESPONSE_STATE_HEADER;
|
||||||
|
break;
|
||||||
|
|
||||||
case HTTP_RESPONSE_STATE_HEADER:
|
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;
|
dst = state->dataLeft > INPUT_BUFFER_LEN ? (req->data + req->size) : buffer;
|
||||||
res = HttpConnection_Read(state->conn, dst, INPUT_BUFFER_LEN, &total);
|
res = HttpConnection_Read(state->conn, dst, INPUT_BUFFER_LEN, &total);
|
||||||
|
if (res) return res;
|
||||||
|
|
||||||
if (res) return res;
|
if (total == 0) {
|
||||||
if (total == 0) return ERR_END_OF_STREAM;
|
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) {
|
if (dst != buffer) {
|
||||||
/* When there is more than INPUT_BUFFER_LEN bytes of unread data/content, */
|
/* 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);
|
res = HttpBackend_PerformRequest(&state);
|
||||||
retried = true;
|
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 (res || !HttpClient_IsRedirect(req)) break;
|
||||||
if (redirects >= 20) return HTTP_ERR_REDIRECTS;
|
if (redirects >= 20) return HTTP_ERR_REDIRECTS;
|
||||||
|
|
@ -1278,7 +1298,7 @@ static void PerformRequest(struct HttpRequest* req, cc_string* url) {
|
||||||
end = Stopwatch_Measure();
|
end = Stopwatch_Measure();
|
||||||
|
|
||||||
elapsed = Stopwatch_ElapsedMS(beg, end);
|
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);
|
&req->result, &req->statusCode, &elapsed, &req->size);
|
||||||
|
|
||||||
Http_FinishRequest(req);
|
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",
|
"Keypad5", "Keypad6", "Keypad7", "Keypad8", "Keypad9",
|
||||||
"KeypadDivide", "KeypadMultiply", "KeypadSubtract",
|
"KeypadDivide", "KeypadMultiply", "KeypadSubtract",
|
||||||
"KeypadAdd", "KeypadDecimal", "KeypadEnter",
|
"KeypadAdd", "KeypadDecimal", "KeypadEnter",
|
||||||
"XButton1", "XButton2", "LeftMouse", "RightMouse", "MiddleMouse",
|
"XButton1", "XButton2", "XButton3", "XButton4", "XButton5", "XButton6",
|
||||||
|
"LeftMouse", "RightMouse", "MiddleMouse",
|
||||||
Pad_Names
|
Pad_Names
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -239,7 +240,8 @@ const char* const Input_DisplayNames[INPUT_COUNT] = {
|
||||||
"NUMPAD5", "NUMPAD6", "NUMPAD7", "NUMPAD8", "NUMPAD9",
|
"NUMPAD5", "NUMPAD6", "NUMPAD7", "NUMPAD8", "NUMPAD9",
|
||||||
"DIVIDE", "MULTIPLY", "SUBTRACT",
|
"DIVIDE", "MULTIPLY", "SUBTRACT",
|
||||||
"ADD", "DECIMAL", "NUMPADENTER",
|
"ADD", "DECIMAL", "NUMPADENTER",
|
||||||
"XBUTTON1", "XBUTTON2", "LMOUSE", "RMOUSE", "MMOUSE",
|
"XBUTTON1", "XBUTTON2", "XBUTTON3", "XBUTTON4", "XBUTTON5", "XBUTTON6",
|
||||||
|
"LMOUSE", "RMOUSE", "MMOUSE",
|
||||||
Pad_Names
|
Pad_Names
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -291,6 +293,15 @@ void Input_Clear(void) {
|
||||||
ClearTouches();
|
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----------------------------------------------------------*
|
*----------------------------------------------------------Mouse----------------------------------------------------------*
|
||||||
|
|
@ -418,38 +429,49 @@ static void KeyBind_Init(void) {
|
||||||
*---------------------------------------------------------Gamepad---------------------------------------------------------*
|
*---------------------------------------------------------Gamepad---------------------------------------------------------*
|
||||||
*#########################################################################################################################*/
|
*#########################################################################################################################*/
|
||||||
#define GAMEPAD_BEG_BTN CCPAD_A
|
#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_AxisBehaviour[2] = { AXIS_BEHAVIOUR_MOVEMENT, AXIS_BEHAVIOUR_CAMERA };
|
||||||
int Gamepad_AxisSensitivity[2] = { AXIS_SENSI_NORMAL, AXIS_SENSI_NORMAL };
|
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 };
|
static const float axis_sensiFactor[] = { 0.25f, 0.5f, 1.0f, 2.0f, 4.0f };
|
||||||
|
|
||||||
struct GamepadState {
|
struct GamepadState {
|
||||||
float axisX[2], axisY[2];
|
float axisX[2], axisY[2];
|
||||||
/*cc_bool pressed[INPUT_COUNT - GAMEPAD_BEG_BTN];*/
|
cc_bool pressed[GAMEPAD_BTN_COUNT];
|
||||||
float holdtime[INPUT_COUNT - GAMEPAD_BEG_BTN];
|
float holdtime[GAMEPAD_BTN_COUNT];
|
||||||
};
|
};
|
||||||
static struct GamepadState gamepads[INPUT_MAX_GAMEPADS];
|
static struct GamepadState gamepads[INPUT_MAX_GAMEPADS];
|
||||||
|
|
||||||
static void Gamepad_Update(struct GamepadState* pad, float delta) {
|
static void Gamepad_Update(struct GamepadState* pad, float delta) {
|
||||||
int btn;
|
int btn;
|
||||||
for (btn = GAMEPAD_BEG_BTN; btn < INPUT_COUNT; btn++)
|
for (btn = 0; btn < GAMEPAD_BTN_COUNT; btn++)
|
||||||
{
|
{
|
||||||
if (!Input.Pressed[btn]) continue;
|
if (!pad->pressed[btn]) continue;
|
||||||
pad->holdtime[btn - GAMEPAD_BEG_BTN] += delta;
|
pad->holdtime[btn] += delta;
|
||||||
if (pad->holdtime[btn - GAMEPAD_BEG_BTN] < 1.0f) continue;
|
if (pad->holdtime[btn] < 1.0f) continue;
|
||||||
|
|
||||||
/* Held for over a second, trigger a fake press */
|
/* Held for over a second, trigger a fake press */
|
||||||
pad->holdtime[btn - GAMEPAD_BEG_BTN] = 0;
|
pad->holdtime[btn] = 0;
|
||||||
Input_SetPressed(btn);
|
Input_SetPressed(btn + GAMEPAD_BEG_BTN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Gamepad_SetButton(int port, int btn, int pressed) {
|
void Gamepad_SetButton(int port, int btn, int pressed) {
|
||||||
struct GamepadState* pad = &gamepads[port];
|
struct GamepadState* pad = &gamepads[port];
|
||||||
/* Reset hold tracking time */
|
int i;
|
||||||
if (pressed && !Input.Pressed[btn]) pad->holdtime[btn - GAMEPAD_BEG_BTN] = 0;
|
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) {
|
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];
|
y = gamepads[port].axisY[axis];
|
||||||
|
|
||||||
if (x != 0 || y != 0) {
|
if (x != 0 || y != 0) {
|
||||||
angle = Math_Atan2(x, y);
|
angle = Math_Atan2f(x, y);
|
||||||
*xMoving = Math_CosF(angle);
|
*xMoving = Math_CosF(angle);
|
||||||
*zMoving = Math_SinF(angle);
|
*zMoving = Math_SinF(angle);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,8 @@ enum InputButtons {
|
||||||
CCKEY_KP_PLUS, CCKEY_KP_DECIMAL, CCKEY_KP_ENTER,
|
CCKEY_KP_PLUS, CCKEY_KP_DECIMAL, CCKEY_KP_ENTER,
|
||||||
|
|
||||||
/* NOTE: RMOUSE must be before MMOUSE for PlayerClick compatibility */
|
/* 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_A, CCPAD_B, CCPAD_X, CCPAD_Y, CCPAD_L, CCPAD_R, CCPAD_Z,
|
||||||
CCPAD_LEFT, CCPAD_RIGHT, CCPAD_UP, CCPAD_DOWN,
|
CCPAD_LEFT, CCPAD_RIGHT, CCPAD_UP, CCPAD_DOWN,
|
||||||
|
|
@ -106,6 +107,7 @@ void Input_Clear(void);
|
||||||
#else
|
#else
|
||||||
#define Input_IsActionPressed() Input_IsCtrlPressed()
|
#define Input_IsActionPressed() Input_IsCtrlPressed()
|
||||||
#endif
|
#endif
|
||||||
|
int Input_CalcDelta(int btn, int horDelta, int verDelta);
|
||||||
|
|
||||||
|
|
||||||
#ifdef CC_BUILD_TOUCH
|
#ifdef CC_BUILD_TOUCH
|
||||||
|
|
|
||||||
|
|
@ -334,6 +334,7 @@ static void OnPointerDown(void* obj, int idx) {
|
||||||
struct LScreen* s = Launcher_Active;
|
struct LScreen* s = Launcher_Active;
|
||||||
struct LWidget* over;
|
struct LWidget* over;
|
||||||
struct LWidget* prev;
|
struct LWidget* prev;
|
||||||
|
if (Window_Main.SoftKeyboardFocus) return;
|
||||||
|
|
||||||
if (!s) return;
|
if (!s) return;
|
||||||
over = GetWidgetAt(s, idx);
|
over = GetWidgetAt(s, idx);
|
||||||
|
|
@ -347,6 +348,7 @@ static void OnPointerUp(void* obj, int idx) {
|
||||||
struct LScreen* s = Launcher_Active;
|
struct LScreen* s = Launcher_Active;
|
||||||
struct LWidget* over;
|
struct LWidget* over;
|
||||||
struct LWidget* prev;
|
struct LWidget* prev;
|
||||||
|
if (Window_Main.SoftKeyboardFocus) return;
|
||||||
|
|
||||||
if (!s) return;
|
if (!s) return;
|
||||||
over = GetWidgetAt(s, idx);
|
over = GetWidgetAt(s, idx);
|
||||||
|
|
@ -367,6 +369,7 @@ static void OnPointerMove(void* obj, int idx) {
|
||||||
struct LWidget* over;
|
struct LWidget* over;
|
||||||
struct LWidget* prev;
|
struct LWidget* prev;
|
||||||
cc_bool overSame;
|
cc_bool overSame;
|
||||||
|
if (Window_Main.SoftKeyboardFocus) return;
|
||||||
|
|
||||||
if (!s) return;
|
if (!s) return;
|
||||||
over = GetWidgetAt(s, idx);
|
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) {
|
static void ColoursScreen_KeyDown(struct LScreen* s, int key, cc_bool was) {
|
||||||
if (Input_IsLeftButton(key)) {
|
int delta = Input_CalcDelta(key, 1, 10);
|
||||||
ColoursScreen_AdjustSelected(s, -1);
|
if (delta) {
|
||||||
} else if (Input_IsRightButton(key)) {
|
ColoursScreen_AdjustSelected(s, delta);
|
||||||
ColoursScreen_AdjustSelected(s, +1);
|
|
||||||
} else if (Input_IsUpButton(key)) {
|
|
||||||
ColoursScreen_AdjustSelected(s, +10);
|
|
||||||
} else if (Input_IsDownButton(key)) {
|
|
||||||
ColoursScreen_AdjustSelected(s, -10);
|
|
||||||
} else {
|
} else {
|
||||||
LScreen_KeyDown(s, key, was);
|
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_) {
|
static void MainScreen_Activated(struct LScreen* s_) {
|
||||||
struct MainScreen* s = (struct MainScreen*)s_;
|
struct MainScreen* s = (struct MainScreen*)s_;
|
||||||
|
|
||||||
|
|
@ -909,8 +910,6 @@ static void MainScreen_Activated(struct LScreen* s_) {
|
||||||
SwitchToSplitScreen, main_btnSplit);
|
SwitchToSplitScreen, main_btnSplit);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
LLabel_Add(s, &s->lblUpdate, "&eChecking..",
|
|
||||||
Updater_Supported ? main_lblUpdate_N : main_lblUpdate_H);
|
|
||||||
if (Process_OpenSupported) {
|
if (Process_OpenSupported) {
|
||||||
LButton_Add(s, &s->btnRegister, 100, 35, "Register",
|
LButton_Add(s, &s->btnRegister, 100, 35, "Register",
|
||||||
MainScreen_Register, main_btnRegister);
|
MainScreen_Register, main_btnRegister);
|
||||||
|
|
@ -918,10 +917,19 @@ static void MainScreen_Activated(struct LScreen* s_) {
|
||||||
|
|
||||||
LButton_Add(s, &s->btnOptions, 100, 35, "Options",
|
LButton_Add(s, &s->btnOptions, 100, 35, "Options",
|
||||||
SwitchToSettings, main_btnOptions);
|
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) {
|
if (Updater_Supported) {
|
||||||
LButton_Add(s, &s->btnUpdates, 100, 35, "Updates",
|
LButton_Add(s, &s->btnUpdates, 100, 35, "Updates",
|
||||||
SwitchToUpdates, main_btnUpdates);
|
SwitchToUpdates, main_btnUpdates);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
s->btnResume.OnHover = MainScreen_ResumeHover;
|
s->btnResume.OnHover = MainScreen_ResumeHover;
|
||||||
s->btnResume.OnUnhover = MainScreen_ResumeUnhover;
|
s->btnResume.OnUnhover = MainScreen_ResumeUnhover;
|
||||||
|
|
|
||||||
|
|
@ -65,8 +65,7 @@ void Launcher_DisplayHttpError(struct HttpRequest* req, const char* action, cc_s
|
||||||
if (res) {
|
if (res) {
|
||||||
/* Non HTTP error - this is not good */
|
/* Non HTTP error - this is not good */
|
||||||
Http_LogError(action, req);
|
Http_LogError(action, req);
|
||||||
String_Format2(dst, res >= 0x80000000 ? "&cError %h when %c" : "&cError %i when %c",
|
String_Format2(dst, "&cError %e when %c", &res, action);
|
||||||
&res, action);
|
|
||||||
} else if (status != 200) {
|
} else if (status != 200) {
|
||||||
String_Format2(dst, "&c%i error when %c", &status, action);
|
String_Format2(dst, "&c%i error when %c", &status, action);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -272,8 +271,9 @@ void Launcher_Run(void) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
Window_ProcessEvents(10 / 1000.0);
|
Window_ProcessEvents(10 / 1000.0f);
|
||||||
Window_ProcessGamepads(10 / 1000.0);
|
Window_ProcessGamepads(10 / 1000.0f);
|
||||||
|
Gamepad_Tick(10 / 1000.0f);
|
||||||
if (!Window_Main.Exists || Launcher_ShouldExit) break;
|
if (!Window_Main.Exists || Launcher_ShouldExit) break;
|
||||||
|
|
||||||
Launcher_Active->Tick(Launcher_Active);
|
Launcher_Active->Tick(Launcher_Active);
|
||||||
|
|
@ -580,4 +580,4 @@ void Launcher_MakeTitleFont(struct FontDesc* font) {
|
||||||
Font_Make(font, 32, FONT_FLAGS_NONE);
|
Font_Make(font, 32, FONT_FLAGS_NONE);
|
||||||
Drawer2D.BitmappedText = false;
|
Drawer2D.BitmappedText = false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
#include "Logger.h"
|
#include "Logger.h"
|
||||||
#include "Event.h"
|
#include "Event.h"
|
||||||
#include "Game.h"
|
#include "Game.h"
|
||||||
|
#include "Options.h"
|
||||||
struct _Lighting Lighting;
|
struct _Lighting Lighting;
|
||||||
#define Lighting_Pack(x, z) ((x) + World.Width * (z))
|
#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;
|
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) {
|
static PackedCol ClassicLighting_Color_XSide(int x, int y, int z) {
|
||||||
if (!World_Contains(x, y, z)) return Env.SunXSide;
|
if (!World_Contains(x, y, z)) return Env.SunXSide;
|
||||||
return y > ClassicLighting_GetLightHeight(x, z) ? Env.SunXSide : Env.ShadowXSide;
|
return y > ClassicLighting_GetLightHeight(x, z) ? Env.SunXSide : Env.ShadowXSide;
|
||||||
|
|
@ -375,10 +382,13 @@ static void ClassicLighting_AllocState(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ClassicLighting_SetActive(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.OnBlockChanged = ClassicLighting_OnBlockChanged;
|
||||||
Lighting.Refresh = ClassicLighting_Refresh;
|
Lighting.Refresh = ClassicLighting_Refresh;
|
||||||
Lighting.IsLit = ClassicLighting_IsLit;
|
Lighting.IsLit = ClassicLighting_IsLit;
|
||||||
Lighting.Color = ClassicLighting_Color;
|
Lighting.Color = smoothLighting ? SmoothLighting_Color : ClassicLighting_Color;
|
||||||
Lighting.Color_XSide = ClassicLighting_Color_XSide;
|
Lighting.Color_XSide = ClassicLighting_Color_XSide;
|
||||||
|
|
||||||
Lighting.IsLit_Fast = ClassicLighting_IsLit_Fast;
|
Lighting.IsLit_Fast = ClassicLighting_IsLit_Fast;
|
||||||
|
|
@ -398,6 +408,10 @@ static void ClassicLighting_SetActive(void) {
|
||||||
*---------------------------------------------------Lighting component----------------------------------------------------*
|
*---------------------------------------------------Lighting component----------------------------------------------------*
|
||||||
*#########################################################################################################################*/
|
*#########################################################################################################################*/
|
||||||
|
|
||||||
|
void Lighting_ApplyActive() {
|
||||||
|
ClassicLighting_SetActive();
|
||||||
|
}
|
||||||
|
|
||||||
static void OnInit(void) { ClassicLighting_SetActive(); }
|
static void OnInit(void) { ClassicLighting_SetActive(); }
|
||||||
static void OnReset(void) { Lighting.FreeState(); }
|
static void OnReset(void) { Lighting.FreeState(); }
|
||||||
static void OnNewMapLoaded(void) { Lighting.AllocState(); }
|
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_XSide_Fast)(int x, int y, int z);
|
||||||
PackedCol (*Color_ZSide_Fast)(int x, int y, int z);
|
PackedCol (*Color_ZSide_Fast)(int x, int y, int z);
|
||||||
} Lighting;
|
} Lighting;
|
||||||
|
|
||||||
|
void Lighting_ApplyActive(void);
|
||||||
#endif
|
#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) {
|
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",
|
String_Format2(msg, "Error %e when %c", &res, action);
|
||||||
&res, action);
|
|
||||||
AppendErrorDesc(msg, res, describeErr);
|
AppendErrorDesc(msg, res, describeErr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Logger_FormatWarn2(cc_string* msg, cc_result res, const char* action, const cc_string* path, Logger_DescribeError 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'",
|
String_Format3(msg, "Error %e when %c '%s'", &res, action, path);
|
||||||
&res, action, path);
|
|
||||||
AppendErrorDesc(msg, res, describeErr);
|
AppendErrorDesc(msg, res, describeErr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -508,7 +506,7 @@ static void PrintRegisters(cc_string* str, void* ctx) {
|
||||||
#define REG_GET_PC() &r->Pc
|
#define REG_GET_PC() &r->Pc
|
||||||
Dump_ARM32()
|
Dump_ARM32()
|
||||||
#elif defined _M_ARM64
|
#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_FP() &r->Fp
|
||||||
#define REG_GET_LR() &r->Lr
|
#define REG_GET_LR() &r->Lr
|
||||||
#define REG_GET_SP() &r->Sp
|
#define REG_GET_SP() &r->Sp
|
||||||
|
|
|
||||||
26
src/Menus.c
26
src/Menus.c
|
|
@ -33,6 +33,7 @@
|
||||||
#include "Utils.h"
|
#include "Utils.h"
|
||||||
#include "Errors.h"
|
#include "Errors.h"
|
||||||
#include "SystemFonts.h"
|
#include "SystemFonts.h"
|
||||||
|
#include "Lighting.h"
|
||||||
|
|
||||||
/* Describes a menu option button */
|
/* Describes a menu option button */
|
||||||
struct MenuOptionDesc {
|
struct MenuOptionDesc {
|
||||||
|
|
@ -514,7 +515,7 @@ static void PauseScreen_CheckHacksAllowed(void* screen) {
|
||||||
struct PauseScreen* s = (struct PauseScreen*)screen;
|
struct PauseScreen* s = (struct PauseScreen*)screen;
|
||||||
if (Gui.ClassicMenu) return;
|
if (Gui.ClassicMenu) return;
|
||||||
|
|
||||||
Widget_SetDisabled(&s->btns[4],
|
Widget_SetDisabled(&s->btns[1],
|
||||||
!Entities.CurPlayer->Hacks.CanAnyHacks); /* select texture pack */
|
!Entities.CurPlayer->Hacks.CanAnyHacks); /* select texture pack */
|
||||||
s->dirty = true;
|
s->dirty = true;
|
||||||
}
|
}
|
||||||
|
|
@ -541,11 +542,11 @@ static void PauseScreen_Init(void* screen) {
|
||||||
struct PauseScreen* s = (struct PauseScreen*)screen;
|
struct PauseScreen* s = (struct PauseScreen*)screen;
|
||||||
static const struct SimpleButtonDesc descs[] = {
|
static const struct SimpleButtonDesc descs[] = {
|
||||||
{ -160, -50, "Options...", Menu_SwitchOptions },
|
{ -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, -50, "Generate new level...", Menu_SwitchGenLevel },
|
||||||
{ 160, 0, "Load level...", Menu_SwitchLoadLevel },
|
{ 160, 0, "Load level...", Menu_SwitchLoadLevel },
|
||||||
{ 160, 50, "Save level...", Menu_SwitchSaveLevel },
|
{ 160, 50, "Save level...", Menu_SwitchSaveLevel }
|
||||||
{ -160, 0, "Change texture pack...", Menu_SwitchTexPacks },
|
|
||||||
{ -160, 50, "Hotkeys...", Menu_SwitchHotkeys }
|
|
||||||
};
|
};
|
||||||
s->widgets = pause_widgets;
|
s->widgets = pause_widgets;
|
||||||
s->numWidgets = 0;
|
s->numWidgets = 0;
|
||||||
|
|
@ -559,8 +560,8 @@ static void PauseScreen_Init(void* screen) {
|
||||||
s->maxVertices = Screen_CalcDefaultMaxVertices(s);
|
s->maxVertices = Screen_CalcDefaultMaxVertices(s);
|
||||||
|
|
||||||
if (Server.IsSinglePlayer) return;
|
if (Server.IsSinglePlayer) return;
|
||||||
s->btns[1].flags = WIDGET_FLAG_DISABLED;
|
s->btns[3].flags = WIDGET_FLAG_DISABLED;
|
||||||
s->btns[2].flags = WIDGET_FLAG_DISABLED;
|
s->btns[5].flags = WIDGET_FLAG_DISABLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void PauseScreen_Free(void* screen) {
|
static void PauseScreen_Free(void* screen) {
|
||||||
|
|
@ -1655,8 +1656,18 @@ static void FontListScreen_LoadEntries(struct ListScreen* s) {
|
||||||
ListScreen_Select(s, SysFonts_UNSAFE_GetDefault());
|
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) {
|
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) {
|
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_GetSmooth(cc_string* v) { Menu_GetBool(v, Builder_SmoothLighting); }
|
||||||
static void GraphicsOptionsScreen_SetSmooth(const cc_string* v) {
|
static void GraphicsOptionsScreen_SetSmooth(const cc_string* v) {
|
||||||
Builder_SmoothLighting = Menu_SetBool(v, OPT_SMOOTH_LIGHTING);
|
Builder_SmoothLighting = Menu_SetBool(v, OPT_SMOOTH_LIGHTING);
|
||||||
|
Lighting_ApplyActive();
|
||||||
Builder_ApplyActive();
|
Builder_ApplyActive();
|
||||||
MapRenderer_Refresh();
|
MapRenderer_Refresh();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -818,6 +818,7 @@ static void CustomModel_DrawArm(struct Entity* e) {
|
||||||
struct CustomModel* cm = (struct CustomModel*)Models.Active;
|
struct CustomModel* cm = (struct CustomModel*)Models.Active;
|
||||||
int i;
|
int i;
|
||||||
if (!cm->numArmParts) return;
|
if (!cm->numArmParts) return;
|
||||||
|
Gfx_SetAlphaTest(true);
|
||||||
|
|
||||||
Models.uScale = 1.0f / cm->uScale;
|
Models.uScale = 1.0f / cm->uScale;
|
||||||
Models.vScale = 1.0f / cm->vScale;
|
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) {
|
static void HumanModel_DrawArmCore(struct Entity* e, struct ModelSet* model) {
|
||||||
struct ModelLimbs* set;
|
struct ModelLimbs* set;
|
||||||
int type, num;
|
int type, num;
|
||||||
|
Gfx_SetAlphaTest(true);
|
||||||
|
|
||||||
type = Models.skinType;
|
type = Models.skinType;
|
||||||
set = &model->limbs[type & 0x3];
|
set = &model->limbs[type & 0x3];
|
||||||
|
|
@ -1854,6 +1856,7 @@ static void SkeletonModel_Draw(struct Entity* e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SkeletonModel_DrawArm(struct Entity* e) {
|
static void SkeletonModel_DrawArm(struct Entity* e) {
|
||||||
|
Gfx_SetAlphaTest(true);
|
||||||
Model_LockVB(e, MODEL_BOX_VERTICES);
|
Model_LockVB(e, MODEL_BOX_VERTICES);
|
||||||
|
|
||||||
Model_DrawArmPart(&skeleton_rightArm);
|
Model_DrawArmPart(&skeleton_rightArm);
|
||||||
|
|
|
||||||
|
|
@ -201,7 +201,7 @@ void Options_SetSecure(const char* opt, const cc_string* src) {
|
||||||
|
|
||||||
String_InitArray(enc, encData);
|
String_InitArray(enc, encData);
|
||||||
res = Platform_Encrypt(src->buffer, src->length, &enc);
|
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 */
|
/* base64 encode the data, as user might edit options.txt with a text editor */
|
||||||
if (enc.length > 1500) Logger_Abort("too large to base64");
|
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);
|
dataLen = Convert_FromBase64(raw.buffer, raw.length, data);
|
||||||
res = Platform_Decrypt(data, dataLen, dst);
|
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);
|
cc_result Socket_Write(cc_socket s, const cc_uint8* data, cc_uint32 count, cc_uint32* modified);
|
||||||
/* Attempts to close the given socket */
|
/* Attempts to close the given socket */
|
||||||
void Socket_Close(cc_socket s);
|
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
|
#ifdef CC_BUILD_MOBILE
|
||||||
void Platform_ShareScreenshot(const cc_string* filename);
|
void Platform_ShareScreenshot(const cc_string* filename);
|
||||||
|
|
|
||||||
|
|
@ -260,9 +260,6 @@ void Platform_Init(void) {
|
||||||
DisableFpuExceptions();
|
DisableFpuExceptions();
|
||||||
|
|
||||||
Platform_ReadonlyFilesystem = true;
|
Platform_ReadonlyFilesystem = true;
|
||||||
// TODO: Redesign Drawer2D to better handle this
|
|
||||||
Options_SetBool(OPT_USE_CHAT_FONT, true);
|
|
||||||
|
|
||||||
dfs_init(DFS_DEFAULT_LOCATION);
|
dfs_init(DFS_DEFAULT_LOCATION);
|
||||||
timer_init();
|
timer_init();
|
||||||
rtc_init();
|
rtc_init();
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <nds/bios.h>
|
#include <nds/bios.h>
|
||||||
|
#include <nds/cothread.h>
|
||||||
#include <nds/interrupts.h>
|
#include <nds/interrupts.h>
|
||||||
#include <nds/timers.h>
|
#include <nds/timers.h>
|
||||||
#include <nds/debug.h>
|
#include <nds/debug.h>
|
||||||
|
|
@ -66,17 +67,18 @@ cc_uint64 Stopwatch_Measure(void) {
|
||||||
static void LogNocash(const char* msg, int len) {
|
static void LogNocash(const char* msg, int len) {
|
||||||
// Can only be up to 120 bytes total
|
// Can only be up to 120 bytes total
|
||||||
char buffer[120];
|
char buffer[120];
|
||||||
len = min(len, 119);
|
len = min(len, 118);
|
||||||
|
|
||||||
Mem_Copy(buffer, msg, len);
|
Mem_Copy(buffer, msg, len);
|
||||||
buffer[len] = '\n';
|
buffer[len + 0] = '\n';
|
||||||
nocashWrite(buffer, len + 1);
|
buffer[len + 1] = '\0';
|
||||||
|
nocashWrite(buffer, len + 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern void consolePrintString(const char* ptr, int len);
|
extern void consolePrintString(const char* ptr, int len);
|
||||||
void Platform_Log(const char* msg, int len) {
|
void Platform_Log(const char* msg, int len) {
|
||||||
LogNocash(msg, len);
|
LogNocash(msg, len);
|
||||||
if (!keyboardOpen) consolePrintString(msg, len);
|
consolePrintString(msg, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
TimeMS DateTime_CurrentUTC(void) {
|
TimeMS DateTime_CurrentUTC(void) {
|
||||||
|
|
@ -108,16 +110,17 @@ static bool fat_available;
|
||||||
|
|
||||||
static void GetNativePath(char* str, const cc_string* path) {
|
static void GetNativePath(char* str, const cc_string* path) {
|
||||||
Mem_Copy(str, root_path.buffer, root_path.length);
|
Mem_Copy(str, root_path.buffer, root_path.length);
|
||||||
str += root_path.length;
|
str += root_path.length;
|
||||||
String_EncodeUtf8(str, path);
|
String_EncodeUtf8(str, path);
|
||||||
Platform_Log1("Open %c", str - root_path.length);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cc_result Directory_Create(const cc_string* path) {
|
cc_result Directory_Create(const cc_string* path) {
|
||||||
if (!fat_available) return ENOSYS;
|
if (!fat_available) return 0;
|
||||||
|
|
||||||
char str[NATIVE_STR_LEN];
|
char str[NATIVE_STR_LEN];
|
||||||
GetNativePath(str, path);
|
GetNativePath(str, path);
|
||||||
|
Platform_Log1("mkdir %c", str);
|
||||||
|
|
||||||
return mkdir(str, 0) == -1 ? errno : 0;
|
return mkdir(str, 0) == -1 ? errno : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -127,6 +130,8 @@ int File_Exists(const cc_string* path) {
|
||||||
char str[NATIVE_STR_LEN];
|
char str[NATIVE_STR_LEN];
|
||||||
struct stat sb;
|
struct stat sb;
|
||||||
GetNativePath(str, path);
|
GetNativePath(str, path);
|
||||||
|
Platform_Log1("Check %c", str);
|
||||||
|
|
||||||
return stat(str, &sb) == 0 && S_ISREG(sb.st_mode);
|
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) {
|
static cc_result File_Do(cc_file* file, const cc_string* path, int mode) {
|
||||||
char str[NATIVE_STR_LEN];
|
char str[NATIVE_STR_LEN];
|
||||||
GetNativePath(str, path);
|
GetNativePath(str, path);
|
||||||
|
Platform_Log1("Open %c", str);
|
||||||
|
|
||||||
*file = open(str, mode, 0);
|
*file = open(str, mode, 0);
|
||||||
return *file == -1 ? errno : 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;
|
*len = st.st_size; return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int LoadFatFilesystem(void* arg) {
|
||||||
|
fat_available = fatInitDefault();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void InitFilesystem(void) {
|
static void InitFilesystem(void) {
|
||||||
// I don't know why I have to call this function, but if I don't,
|
cothread_t thread = cothread_create(LoadFatFilesystem, NULL, 0, 0);
|
||||||
// then when running in DSi mode AND an SD card is readable,
|
// If running with DSi mode in melonDS and the internal SD card is enabled, then
|
||||||
// fatInitDefault gets stuck somewhere (in disk_initialize it seems)
|
// fatInitDefault gets stuck in sdmmc_ReadSectors - because the fifoWaitValue32Async will never return
|
||||||
if (isDSiMode()) {
|
// (You can tell when this happens - "MMC: unknown CMD 17 00000000" is logged to console)
|
||||||
const DISC_INTERFACE* sd_io = get_io_dsisd();
|
// However, since it does yield to cothreads, workaround this by running fatInitDefault on another thread
|
||||||
if (sd_io) sd_io->startup();
|
// 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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fat_available = fatInitDefault();
|
|
||||||
Platform_ReadonlyFilesystem = !fat_available;
|
|
||||||
if (!fat_available) return;
|
|
||||||
|
|
||||||
char* dir = fatGetDefaultCwd();
|
char* dir = fatGetDefaultCwd();
|
||||||
if (dir && dir[0]) {
|
if (dir) {
|
||||||
root_path.buffer = dir;
|
root_path.buffer = dir;
|
||||||
root_path.length = String_Length(dir);
|
root_path.length = String_Length(dir);
|
||||||
}
|
}
|
||||||
|
Platform_ReadonlyFilesystem = !fat_available;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -406,9 +425,6 @@ void Platform_Init(void) {
|
||||||
InitNetworking();
|
InitNetworking();
|
||||||
|
|
||||||
cpuStartTiming(1);
|
cpuStartTiming(1);
|
||||||
// TODO: Redesign Drawer2D to better handle this
|
|
||||||
Options_Load();
|
|
||||||
Options_SetBool(OPT_USE_CHAT_FONT, true);
|
|
||||||
}
|
}
|
||||||
void Platform_Free(void) { }
|
void Platform_Free(void) { }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -227,8 +227,6 @@ cc_result Socket_CheckWritable(cc_socket s, cc_bool* writable) {
|
||||||
void Platform_Init(void) {
|
void Platform_Init(void) {
|
||||||
ResetGraph(0);
|
ResetGraph(0);
|
||||||
Stopwatch_Init();
|
Stopwatch_Init();
|
||||||
|
|
||||||
Options_SetBool(OPT_USE_CHAT_FONT, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Platform_Free(void) { }
|
void Platform_Free(void) { }
|
||||||
|
|
|
||||||
|
|
@ -497,7 +497,7 @@ void Waitable_WaitFor(void* handle, cc_uint32 milliseconds) {
|
||||||
*--------------------------------------------------------Font/Text--------------------------------------------------------*
|
*--------------------------------------------------------Font/Text--------------------------------------------------------*
|
||||||
*#########################################################################################################################*/
|
*#########################################################################################################################*/
|
||||||
static void FontDirCallback(const cc_string* path, void* obj) {
|
static void FontDirCallback(const cc_string* path, void* obj) {
|
||||||
SysFonts_Register(path);
|
SysFonts_Register(path, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Platform_LoadSysFonts(void) {
|
void Platform_LoadSysFonts(void) {
|
||||||
|
|
|
||||||
|
|
@ -213,8 +213,6 @@ cc_result Socket_CheckWritable(cc_socket s, cc_bool* writable) {
|
||||||
*#########################################################################################################################*/
|
*#########################################################################################################################*/
|
||||||
void Platform_Init(void) {
|
void Platform_Init(void) {
|
||||||
Stopwatch_Init();
|
Stopwatch_Init();
|
||||||
|
|
||||||
Options_SetBool(OPT_USE_CHAT_FONT, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Platform_Free(void) { }
|
void Platform_Free(void) { }
|
||||||
|
|
|
||||||
|
|
@ -500,9 +500,6 @@ static void CreateRootDirectory(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Platform_Init(void) {
|
void Platform_Init(void) {
|
||||||
// TODO: Redesign Drawer2D to better handle this
|
|
||||||
//Options_SetBool(OPT_USE_CHAT_FONT, true);
|
|
||||||
|
|
||||||
CreateRootDirectory();
|
CreateRootDirectory();
|
||||||
socketInitializeDefault();
|
socketInitializeDefault();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -360,7 +360,7 @@ static void FontDirCallback(const cc_string* path, void* obj) {
|
||||||
static const cc_string fonExt = String_FromConst(".fon");
|
static const cc_string fonExt = String_FromConst(".fon");
|
||||||
/* Completely skip windows .FON files */
|
/* Completely skip windows .FON files */
|
||||||
if (String_CaselessEnds(path, &fonExt)) return;
|
if (String_CaselessEnds(path, &fonExt)) return;
|
||||||
SysFonts_Register(path);
|
SysFonts_Register(path, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Platform_LoadSysFonts(void) {
|
void Platform_LoadSysFonts(void) {
|
||||||
|
|
@ -839,7 +839,7 @@ cc_bool DynamicLib_DescribeError(cc_string* dst) {
|
||||||
dynamicErr = 0; /* Reset error (match posix behaviour) */
|
dynamicErr = 0; /* Reset error (match posix behaviour) */
|
||||||
|
|
||||||
Platform_DescribeError(res, dst);
|
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, */
|
/* Plugin may have been compiled to load symbols from ClassiCube.exe, */
|
||||||
/* but the user might have renamed it to something else */
|
/* 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) {
|
int File_Exists(const cc_string* path) {
|
||||||
if (!hdd_mounted) return ERR_NOT_SUPPORTED;
|
if (!hdd_mounted) return 0;
|
||||||
|
|
||||||
char str[NATIVE_STR_LEN];
|
char str[NATIVE_STR_LEN];
|
||||||
DWORD attribs;
|
DWORD attribs;
|
||||||
|
|
@ -164,7 +164,7 @@ cc_result Directory_Enum(const cc_string* dirPath, void* obj, Directory_EnumCall
|
||||||
} while (FindNextFileA(find, &eA));
|
} while (FindNextFileA(find, &eA));
|
||||||
|
|
||||||
res = GetLastError(); /* return code from FindNextFile */
|
res = GetLastError(); /* return code from FindNextFile */
|
||||||
FindClose(find);
|
NtClose(find);
|
||||||
return res == ERROR_NO_MORE_FILES ? 0 : res;
|
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) {
|
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) {
|
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--------------------------------------------------------*
|
*--------------------------------------------------------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); }
|
void Thread_Sleep(cc_uint32 milliseconds) { Sleep(milliseconds); }
|
||||||
static DWORD WINAPI ExecThread(void* param) {
|
static DWORD WINAPI ExecThread(void* param) {
|
||||||
Thread_StartFunc func = (Thread_StartFunc)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) {
|
void Thread_Detach(void* handle) {
|
||||||
if (!CloseHandle((HANDLE)handle)) {
|
NTSTATUS status = NtClose((HANDLE)handle);
|
||||||
Logger_Abort2(GetLastError(), "Freeing thread handle");
|
if (!NT_SUCCESS(status)) Logger_Abort2(status, "Freeing thread handle");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Thread_Join(void* handle) {
|
void Thread_Join(void* handle) {
|
||||||
WaitForSingleObject((HANDLE)handle, INFINITE);
|
WaitForSignal((HANDLE)handle, NULL);
|
||||||
Thread_Detach(handle);
|
Thread_Detach(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -263,30 +271,41 @@ void Mutex_Free(void* handle) {
|
||||||
RtlDeleteCriticalSection((CRITICAL_SECTION*)handle);
|
RtlDeleteCriticalSection((CRITICAL_SECTION*)handle);
|
||||||
Mem_Free(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* Waitable_Create(void) {
|
||||||
void* handle = CreateEventA(NULL, false, false, NULL);
|
HANDLE handle;
|
||||||
if (!handle) {
|
NTSTATUS status = NtCreateEvent(&handle, NULL, SynchronizationEvent, false);
|
||||||
Logger_Abort2(GetLastError(), "Creating waitable");
|
|
||||||
}
|
if (!NT_SUCCESS(status)) Logger_Abort2(status, "Creating waitable");
|
||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Waitable_Free(void* handle) {
|
void Waitable_Free(void* handle) {
|
||||||
if (!CloseHandle((HANDLE)handle)) {
|
NTSTATUS status = NtClose((HANDLE)handle);
|
||||||
Logger_Abort2(GetLastError(), "Freeing waitable");
|
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) {
|
void Waitable_Wait(void* handle) {
|
||||||
WaitForSingleObject((HANDLE)handle, INFINITE);
|
WaitForSignal((HANDLE)handle, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Waitable_WaitFor(void* handle, cc_uint32 milliseconds) {
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -397,18 +416,20 @@ static void InitHDD(void) {
|
||||||
} else {
|
} else {
|
||||||
hdd_mounted = nxMountDrive('E', "\\Device\\Harddisk0\\Partition1\\");
|
hdd_mounted = nxMountDrive('E', "\\Device\\Harddisk0\\Partition1\\");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!hdd_mounted) {
|
if (!hdd_mounted) {
|
||||||
Platform_LogConst("Failed to mount E:/ from Data partition");
|
Platform_LogConst("Failed to mount E:/ from Data partition");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Directory_Create(&String_Empty); // create root ClassiCube folder
|
Directory_Create(&String_Empty); // create root ClassiCube folder
|
||||||
}
|
}
|
||||||
|
|
||||||
void Platform_Init(void) {
|
void Platform_Init(void) {
|
||||||
InitHDD();
|
InitHDD();
|
||||||
Stopwatch_Init();
|
Stopwatch_Init();
|
||||||
|
#ifndef CC_BUILD_CXBX
|
||||||
nxNetInit(NULL);
|
nxNetInit(NULL);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Platform_Free(void) {
|
void Platform_Free(void) {
|
||||||
|
|
|
||||||
|
|
@ -358,7 +358,7 @@ static void DisconnectInvalidMap(cc_result res) {
|
||||||
cc_string tmp; char tmpBuffer[STRING_SIZE];
|
cc_string tmp; char tmpBuffer[STRING_SIZE];
|
||||||
String_InitArray(tmp, tmpBuffer);
|
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;
|
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);
|
&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) {
|
static cc_result SSL_RecvRaw(struct SSLContext* ctx) {
|
||||||
cc_uint32 read;
|
cc_uint32 read;
|
||||||
cc_result res;
|
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) */
|
/* Send initial handshake to the server (if there is one) */
|
||||||
if (out_buffers[0].pvBuffer) {
|
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);
|
FP_FreeContextBuffer(out_buffers[0].pvBuffer);
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
|
|
@ -221,7 +206,7 @@ static SECURITY_STATUS SSL_Negotiate(struct SSLContext* ctx) {
|
||||||
|
|
||||||
/* Need to send data to the server */
|
/* Need to send data to the server */
|
||||||
if (sec == SEC_I_CONTINUE_NEEDED) {
|
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? */
|
FP_FreeContextBuffer(out_buffers[0].pvBuffer); /* TODO always free? */
|
||||||
|
|
||||||
if (res) return res;
|
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 */
|
/* 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) */
|
/* (as TLS record header size will always be the same size) */
|
||||||
total = buffers[0].cbBuffer + buffers[1].cbBuffer + buffers[2].cbBuffer;
|
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;
|
struct SSLContext* s = ctx;
|
||||||
cc_result res;
|
cc_result res;
|
||||||
*wrote = 0;
|
|
||||||
|
|
||||||
/* TODO: Don't loop here? move to HTTPConnection instead?? */
|
/* TODO: Don't loop here? move to HTTPConnection instead?? */
|
||||||
while (count)
|
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);
|
int len = min(count, s->sizes.cbMaximumMessage);
|
||||||
if ((res = SSL_WriteChunk(s, data, len))) return res;
|
if ((res = SSL_WriteChunk(s, data, len))) return res;
|
||||||
|
|
||||||
*wrote += len;
|
|
||||||
data += len;
|
data += len;
|
||||||
count -= len;
|
count -= len;
|
||||||
}
|
}
|
||||||
|
|
@ -558,7 +541,7 @@ cc_result SSL_Read(void* ctx_, cc_uint8* data, cc_uint32 count, cc_uint32* read)
|
||||||
return 0;
|
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_;
|
SSLContext* ctx = (SSLContext*)ctx_;
|
||||||
// TODO: just br_sslio_write ??
|
// TODO: just br_sslio_write ??
|
||||||
int res = br_sslio_write_all(&ctx->ioc, data, count);
|
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);
|
br_sslio_flush(&ctx->ioc);
|
||||||
*wrote = res;
|
|
||||||
return 0;
|
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;
|
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;
|
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_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_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);
|
cc_result SSL_Free(void* ctx);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue