Merge branch 'master' of https://github.com/UnknownShadow200/ClassiCube into AndroidUI2

This commit is contained in:
UnknownShadow200 2024-05-16 18:31:12 +10:00
commit 14be9f0856
136 changed files with 2807 additions and 1846 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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'

View File

@ -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

View File

@ -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

44
.github/workflows/build_webclient.yml vendored Normal file
View File

@ -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'

View File

@ -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

View File

@ -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

79
.github/workflows/build_win-arm.yml vendored Normal file
View File

@ -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'

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

8
.gitignore vendored
View File

@ -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/

View File

@ -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",

View File

@ -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,

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
#------------------------------------------------------------------------------- #-------------------------------------------------------------------------------

View File

@ -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 */

View File

@ -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
/*########################################################################################################################* /*########################################################################################################################*

View File

@ -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;

View File

@ -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. */

View File

@ -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

View File

@ -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" />

View File

@ -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">

View File

@ -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);

View File

@ -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 */

View File

@ -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

View File

@ -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;
} }
} }

View File

@ -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

View File

@ -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;

View File

@ -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 = {

View File

@ -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 {

View File

@ -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);
} }

View File

@ -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 */

View File

@ -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;
}

View File

@ -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) */

View File

@ -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();

View File

@ -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;
} }

View File

@ -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) {

View File

@ -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);

View File

@ -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

View File

@ -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();

View File

@ -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); }
} }

View File

@ -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;

View File

@ -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); }
} }

View File

@ -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 {

View File

@ -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

View File

@ -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
} }

View File

@ -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);
} }

View File

@ -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;

View File

@ -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();
} }

View File

@ -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) { }

View File

@ -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);

View File

@ -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

View File

@ -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);
} }

View File

@ -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,

View File

@ -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);

View File

@ -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;

View File

@ -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 {

View File

@ -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);

View File

@ -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);
} }

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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(); }

View File

@ -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

View File

@ -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

View File

@ -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();
} }

View File

@ -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);

View File

@ -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);
} }

View File

@ -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);

View File

@ -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();

View File

@ -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) { }

View File

@ -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) { }

View File

@ -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) {

View File

@ -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) { }

View File

@ -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();
} }

View File

@ -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 */

View File

@ -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) {

View File

@ -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;
} }

View File

@ -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;
} }

View File

@ -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