mirror of
https://github.com/odamex/odamex
synced 2026-08-19 02:23:09 -04:00
Merge branch 'stable' into unit-tests
This commit is contained in:
commit
8a0af04eae
434 changed files with 16669 additions and 18019 deletions
15
.github/FUNDING.yml
vendored
Normal file
15
.github/FUNDING.yml
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
# These are supported funding model platforms
|
||||
|
||||
github: odamex
|
||||
patreon: # Replace with a single Patreon username
|
||||
open_collective: # Replace with a single Open Collective username
|
||||
ko_fi: # Replace with a single Ko-fi username
|
||||
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
||||
liberapay: # Replace with a single Liberapay username
|
||||
issuehunt: # Replace with a single IssueHunt username
|
||||
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
|
||||
polar: # Replace with a single Polar username
|
||||
buy_me_a_coffee: # Replace with a single Buy Me a Coffee username
|
||||
thanks_dev: # Replace with a single thanks.dev username
|
||||
custom: ['https://odamex.net'] # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
|
||||
79
.github/actions/update-prerelease/action.yml
vendored
Normal file
79
.github/actions/update-prerelease/action.yml
vendored
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
name: Update Prerelease
|
||||
|
||||
inputs:
|
||||
files:
|
||||
description: "Files to upload to release artifacts"
|
||||
required: true
|
||||
build_number:
|
||||
description: "Prerelease build number"
|
||||
required: true
|
||||
new_version:
|
||||
description: "Version number of the upcoming release"
|
||||
required: true
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- name: Check if prerelease is outdated
|
||||
id: check
|
||||
shell: bash
|
||||
run: |
|
||||
if git fetch --quiet origin refs/tags/prerelease:refs/tags/prerelease; then
|
||||
TAG_COMMIT=$(git rev-list -n 1 refs/tags/prerelease)
|
||||
|
||||
if [ "$TAG_COMMIT" != "${{ github.sha }}" ]; then
|
||||
echo "should_delete=true" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo "should_delete=false" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
else
|
||||
echo "should_delete=false" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
- name: Delete old prerelease
|
||||
if: steps.check.outputs.should_delete == 'true'
|
||||
shell: bash
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
run: |
|
||||
gh release delete prerelease --yes || true
|
||||
git push origin :prerelease || true
|
||||
- name: Find last release tag
|
||||
id: get_tag
|
||||
shell: bash
|
||||
run: |
|
||||
latest_tag=$(git tag -l --sort=version:refname "[0-9]*.[0-9]*.[0-9]*" | tail -n 1)
|
||||
echo "latest_tag=$latest_tag" >> $GITHUB_OUTPUT
|
||||
- name: Create prerelease
|
||||
uses: softprops/action-gh-release@v2.3.4
|
||||
id: create_prerelease
|
||||
with:
|
||||
tag_name: prerelease
|
||||
target_commitish: ${{ github.sha }}
|
||||
name: "Odamex ${{ inputs.new_version }} Prerelease ${{ inputs.build_number }}"
|
||||
prerelease: true
|
||||
make_latest: false
|
||||
draft: false
|
||||
overwrite_files: true
|
||||
generate_release_notes: false
|
||||
body: ""
|
||||
files: ${{ inputs.files }}
|
||||
- name: Generate release notes
|
||||
id: build_changelog
|
||||
uses: actions/github-script@v8
|
||||
env:
|
||||
latest_tag: ${{ steps.get_tag.outputs.latest_tag }}
|
||||
release_id: ${{ steps.create_prerelease.outputs.id }}
|
||||
with:
|
||||
script: |
|
||||
const notes = await github.rest.repos.generateReleaseNotes({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
tag_name: "prerelease",
|
||||
previous_tag_name: process.env.latest_tag,
|
||||
});
|
||||
await github.rest.repos.updateRelease({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
release_id: process.env.release_id,
|
||||
body: notes.data.body,
|
||||
});
|
||||
58
.github/workflows/linux-rc.yml
vendored
58
.github/workflows/linux-rc.yml
vendored
|
|
@ -5,6 +5,9 @@ on:
|
|||
branches:
|
||||
- 'release/[0-9]+.[0-9]+.[0-9]+' # Only run on major.minor.patch releases
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
pre_job:
|
||||
name: Build Preparation
|
||||
|
|
@ -21,12 +24,12 @@ jobs:
|
|||
persist-credentials: false # otherwise, the token used is the GITHUB_TOKEN, instead of your personal token
|
||||
fetch-depth: 0 # Required due to the way Git works, without it this action won't be able to find any or the correct tags
|
||||
- name: Install GitVersion
|
||||
uses: gittools/actions/gitversion/setup@v0.9.7
|
||||
uses: gittools/actions/gitversion/setup@v4.1.0
|
||||
with:
|
||||
versionSpec: '5.x'
|
||||
versionSpec: '6.x'
|
||||
- name: Determine Version
|
||||
id: gitversion
|
||||
uses: gittools/actions/gitversion/execute@v0.9.7
|
||||
uses: gittools/actions/gitversion/execute@v4.1.0
|
||||
- name: Get Commits From Source
|
||||
id: revlist
|
||||
shell: bash
|
||||
|
|
@ -44,12 +47,9 @@ jobs:
|
|||
echo "PreReleaseNumber: ${{ steps.gitversion.outputs.preReleaseNumber }}"
|
||||
echo "WeightedPreReleaseNumber: ${{ steps.gitversion.outputs.weightedPreReleaseNumber }}"
|
||||
echo "BuildMetaData: ${{ steps.gitversion.outputs.buildMetaData }}"
|
||||
echo "BuildMetaDataPadded: ${{ steps.gitversion.outputs.buildMetaDataPadded }}"
|
||||
echo "FullBuildMetaData: ${{ steps.gitversion.outputs.fullBuildMetaData }}"
|
||||
echo "MajorMinorPatch: ${{ steps.gitversion.outputs.majorMinorPatch }}"
|
||||
echo "SemVer: ${{ steps.gitversion.outputs.semVer }}"
|
||||
echo "LegacySemVer: ${{ steps.gitversion.outputs.legacySemVer }}"
|
||||
echo "LegacySemVerPadded: ${{ steps.gitversion.outputs.legacySemVerPadded }}"
|
||||
echo "AssemblySemVer: ${{ steps.gitversion.outputs.assemblySemVer }}"
|
||||
echo "AssemblySemFileVer: ${{ steps.gitversion.outputs.assemblySemFileVer }}"
|
||||
echo "FullSemVer: ${{ steps.gitversion.outputs.fullSemVer }}"
|
||||
|
|
@ -58,13 +58,8 @@ jobs:
|
|||
echo "EscapedBranchName: ${{ steps.gitversion.outputs.escapedBranchName }}"
|
||||
echo "Sha: ${{ steps.gitversion.outputs.sha }}"
|
||||
echo "ShortSha: ${{ steps.gitversion.outputs.shortSha }}"
|
||||
echo "NuGetVersionV2: ${{ steps.gitversion.outputs.nuGetVersionV2 }}"
|
||||
echo "NuGetVersion: ${{ steps.gitversion.outputs.nuGetVersion }}"
|
||||
echo "NuGetPreReleaseTagV2: ${{ steps.gitversion.outputs.nuGetPreReleaseTagV2 }}"
|
||||
echo "NuGetPreReleaseTag: ${{ steps.gitversion.outputs.nuGetPreReleaseTag }}"
|
||||
echo "VersionSourceSha: ${{ steps.gitversion.outputs.versionSourceSha }}"
|
||||
echo "CommitsSinceVersionSource: ${{ steps.gitversion.outputs.commitsSinceVersionSource }}"
|
||||
echo "CommitsSinceVersionSourcePadded: ${{ steps.gitversion.outputs.commitsSinceVersionSourcePadded }}"
|
||||
echo "UncommittedChanges: ${{ steps.gitversion.outputs.uncommittedChanges }}"
|
||||
echo "CommitDate: ${{ steps.gitversion.outputs.commitDate }}"
|
||||
echo "TotalCommits: ${{ steps.revlist.outputs.totalCommits }}"
|
||||
|
|
@ -212,13 +207,13 @@ jobs:
|
|||
--default-branch=${{ env.MODIFIED_BRANCH_NAME }} -v
|
||||
- name: Pack flatpak
|
||||
run: |
|
||||
flatpak build-bundle repo odamex.flatpak net.odamex.Odamex ${{ env.MODIFIED_BRANCH_NAME }} \
|
||||
--runtime-repo=https://flathub.org/repo/flathub.flatpakrepo
|
||||
flatpak build-bundle repo odamex-linux-x86_64-${{env.new_version}}-prerelease.${{ env.build_number }}.flatpak \
|
||||
net.odamex.Odamex ${{ env.MODIFIED_BRANCH_NAME }} --runtime-repo=https://flathub.org/repo/flathub.flatpakrepo
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: Odamex-Flatpak-x86_64
|
||||
path: odamex.flatpak
|
||||
path: odamex-linux-x86_64-${{env.new_version}}-prerelease.${{ env.build_number }}.flatpak
|
||||
build-flatpak-arm:
|
||||
name: Build Flatpak (Ubuntu 24.04 ARM)
|
||||
needs: pre_job
|
||||
|
|
@ -261,10 +256,39 @@ jobs:
|
|||
--default-branch=${{ env.MODIFIED_BRANCH_NAME }} -v
|
||||
- name: Pack flatpak
|
||||
run: |
|
||||
flatpak build-bundle repo odamex.flatpak net.odamex.Odamex ${{ env.MODIFIED_BRANCH_NAME }} \
|
||||
--runtime-repo=https://flathub.org/repo/flathub.flatpakrepo
|
||||
flatpak build-bundle repo odamex-linux-arm64-${{env.new_version}}-prerelease.${{ env.build_number }}.flatpak \
|
||||
net.odamex.Odamex ${{ env.MODIFIED_BRANCH_NAME }} --runtime-repo=https://flathub.org/repo/flathub.flatpakrepo
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: Odamex-Flatpak-ARM64
|
||||
path: odamex.flatpak
|
||||
path: odamex-linux-arm64-${{env.new_version}}-prerelease.${{ env.build_number }}.flatpak
|
||||
package-and-upload:
|
||||
name: Package and Upload Artifacts
|
||||
runs-on: windows-latest
|
||||
needs: [pre_job, build-flatpak, build-flatpak-arm]
|
||||
env:
|
||||
build_number: ${{ needs.pre_job.outputs.build_number }}
|
||||
new_version: ${{ needs.pre_job.outputs.new_version }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-tags: true
|
||||
- name: Download x86_64 Flatpak
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: Odamex-Flatpak-x86_64
|
||||
- name: Download Arm Flatpak
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: Odamex-Flatpak-ARM64
|
||||
- name: Create or update prerelease
|
||||
uses: ./.github/actions/update-prerelease
|
||||
env:
|
||||
build_number: ${{ needs.pre_job.outputs.build_number }}
|
||||
new_version: ${{ needs.pre_job.outputs.new_version }}
|
||||
with:
|
||||
build_number: ${{ env.build_number }}
|
||||
new_version: ${{ env.new_version }}
|
||||
files: |
|
||||
./*.flatpak
|
||||
10
.github/workflows/linux.yml
vendored
10
.github/workflows/linux.yml
vendored
|
|
@ -4,6 +4,16 @@ on:
|
|||
push:
|
||||
branches-ignore:
|
||||
- 'release/[0-9]+.[0-9]+.[0-9]+'
|
||||
paths-ignore:
|
||||
- "**/*.md"
|
||||
- README
|
||||
- LICENSE
|
||||
- MAINTAINERS
|
||||
- CHANGELOG
|
||||
- 3RD-PARTY-LICENSES
|
||||
- config-samples/*
|
||||
- documentation/**
|
||||
- tools/**
|
||||
pull_request:
|
||||
|
||||
|
||||
|
|
|
|||
14
.github/workflows/macos.yml
vendored
14
.github/workflows/macos.yml
vendored
|
|
@ -1,6 +1,18 @@
|
|||
name: macOS
|
||||
|
||||
on: [push, pull_request]
|
||||
on:
|
||||
push:
|
||||
paths-ignore:
|
||||
- "**/*.md"
|
||||
- README
|
||||
- LICENSE
|
||||
- MAINTAINERS
|
||||
- CHANGELOG
|
||||
- 3RD-PARTY-LICENSES
|
||||
- config-samples/*
|
||||
- documentation/**
|
||||
- tools/**
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
pre_job:
|
||||
|
|
|
|||
17
.github/workflows/release-upversion.yml
vendored
17
.github/workflows/release-upversion.yml
vendored
|
|
@ -31,15 +31,12 @@ jobs:
|
|||
persist-credentials: false # otherwise, the token used is the GITHUB_TOKEN, instead of your personal token
|
||||
fetch-depth: 0 # Required due to the way Git works, without it this action won't be able to find any or the correct tags
|
||||
- name: Install GitVersion
|
||||
uses: gittools/actions/gitversion/setup@v0.9.7
|
||||
uses: gittools/actions/gitversion/setup@v4.1.0
|
||||
with:
|
||||
versionSpec: '5.x'
|
||||
versionSpec: '6.x'
|
||||
- name: Determine Version
|
||||
id: gitversion
|
||||
uses: gittools/actions/gitversion/execute@v0.9.7
|
||||
- name: Get branch name
|
||||
id: branchname
|
||||
uses: nelonoel/branch-name@v1.0.1
|
||||
uses: gittools/actions/gitversion/execute@v4.1.0
|
||||
- name: Display GitVersion outputs
|
||||
run: |
|
||||
echo "Major: ${{ steps.gitversion.outputs.major }}"
|
||||
|
|
@ -51,12 +48,9 @@ jobs:
|
|||
echo "PreReleaseNumber: ${{ steps.gitversion.outputs.preReleaseNumber }}"
|
||||
echo "WeightedPreReleaseNumber: ${{ steps.gitversion.outputs.weightedPreReleaseNumber }}"
|
||||
echo "BuildMetaData: ${{ steps.gitversion.outputs.buildMetaData }}"
|
||||
echo "BuildMetaDataPadded: ${{ steps.gitversion.outputs.buildMetaDataPadded }}"
|
||||
echo "FullBuildMetaData: ${{ steps.gitversion.outputs.fullBuildMetaData }}"
|
||||
echo "MajorMinorPatch: ${{ steps.gitversion.outputs.majorMinorPatch }}"
|
||||
echo "SemVer: ${{ steps.gitversion.outputs.semVer }}"
|
||||
echo "LegacySemVer: ${{ steps.gitversion.outputs.legacySemVer }}"
|
||||
echo "LegacySemVerPadded: ${{ steps.gitversion.outputs.legacySemVerPadded }}"
|
||||
echo "AssemblySemVer: ${{ steps.gitversion.outputs.assemblySemVer }}"
|
||||
echo "AssemblySemFileVer: ${{ steps.gitversion.outputs.assemblySemFileVer }}"
|
||||
echo "FullSemVer: ${{ steps.gitversion.outputs.fullSemVer }}"
|
||||
|
|
@ -65,13 +59,8 @@ jobs:
|
|||
echo "EscapedBranchName: ${{ steps.gitversion.outputs.escapedBranchName }}"
|
||||
echo "Sha: ${{ steps.gitversion.outputs.sha }}"
|
||||
echo "ShortSha: ${{ steps.gitversion.outputs.shortSha }}"
|
||||
echo "NuGetVersionV2: ${{ steps.gitversion.outputs.nuGetVersionV2 }}"
|
||||
echo "NuGetVersion: ${{ steps.gitversion.outputs.nuGetVersion }}"
|
||||
echo "NuGetPreReleaseTagV2: ${{ steps.gitversion.outputs.nuGetPreReleaseTagV2 }}"
|
||||
echo "NuGetPreReleaseTag: ${{ steps.gitversion.outputs.nuGetPreReleaseTag }}"
|
||||
echo "VersionSourceSha: ${{ steps.gitversion.outputs.versionSourceSha }}"
|
||||
echo "CommitsSinceVersionSource: ${{ steps.gitversion.outputs.commitsSinceVersionSource }}"
|
||||
echo "CommitsSinceVersionSourcePadded: ${{ steps.gitversion.outputs.commitsSinceVersionSourcePadded }}"
|
||||
echo "UncommittedChanges: ${{ steps.gitversion.outputs.uncommittedChanges }}"
|
||||
echo "CommitDate: ${{ steps.gitversion.outputs.commitDate }}"
|
||||
upversion-and-pr:
|
||||
|
|
|
|||
136
.github/workflows/release.yml
vendored
136
.github/workflows/release.yml
vendored
|
|
@ -9,6 +9,9 @@ on:
|
|||
- "[0-9]+.[0-9]+.[0-9]+"
|
||||
types: [published]
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
pre_job:
|
||||
name: Build Preparation
|
||||
|
|
@ -22,16 +25,16 @@ jobs:
|
|||
fetch-depth: 0 # Required due to the way Git works, without it this action won't be able to find any or the correct tags
|
||||
- name: Get release
|
||||
id: get_release
|
||||
uses: bruceadams/get-release@v1.2.3
|
||||
uses: bruceadams/get-release@v1.3.2
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
- name: Install GitVersion
|
||||
uses: gittools/actions/gitversion/setup@v0.9.7
|
||||
uses: gittools/actions/gitversion/setup@v4.1.0
|
||||
with:
|
||||
versionSpec: '5.x'
|
||||
versionSpec: '6.x'
|
||||
- name: Determine Version
|
||||
id: gitversion
|
||||
uses: gittools/actions/gitversion/execute@v0.9.7
|
||||
uses: gittools/actions/gitversion/execute@v4.1.0
|
||||
- name: Display GitVersion outputs
|
||||
run: |
|
||||
echo "Major: ${{ steps.gitversion.outputs.major }}"
|
||||
|
|
@ -43,12 +46,9 @@ jobs:
|
|||
echo "PreReleaseNumber: ${{ steps.gitversion.outputs.preReleaseNumber }}"
|
||||
echo "WeightedPreReleaseNumber: ${{ steps.gitversion.outputs.weightedPreReleaseNumber }}"
|
||||
echo "BuildMetaData: ${{ steps.gitversion.outputs.buildMetaData }}"
|
||||
echo "BuildMetaDataPadded: ${{ steps.gitversion.outputs.buildMetaDataPadded }}"
|
||||
echo "FullBuildMetaData: ${{ steps.gitversion.outputs.fullBuildMetaData }}"
|
||||
echo "MajorMinorPatch: ${{ steps.gitversion.outputs.majorMinorPatch }}"
|
||||
echo "SemVer: ${{ steps.gitversion.outputs.semVer }}"
|
||||
echo "LegacySemVer: ${{ steps.gitversion.outputs.legacySemVer }}"
|
||||
echo "LegacySemVerPadded: ${{ steps.gitversion.outputs.legacySemVerPadded }}"
|
||||
echo "AssemblySemVer: ${{ steps.gitversion.outputs.assemblySemVer }}"
|
||||
echo "AssemblySemFileVer: ${{ steps.gitversion.outputs.assemblySemFileVer }}"
|
||||
echo "FullSemVer: ${{ steps.gitversion.outputs.fullSemVer }}"
|
||||
|
|
@ -57,13 +57,8 @@ jobs:
|
|||
echo "EscapedBranchName: ${{ steps.gitversion.outputs.escapedBranchName }}"
|
||||
echo "Sha: ${{ steps.gitversion.outputs.sha }}"
|
||||
echo "ShortSha: ${{ steps.gitversion.outputs.shortSha }}"
|
||||
echo "NuGetVersionV2: ${{ steps.gitversion.outputs.nuGetVersionV2 }}"
|
||||
echo "NuGetVersion: ${{ steps.gitversion.outputs.nuGetVersion }}"
|
||||
echo "NuGetPreReleaseTagV2: ${{ steps.gitversion.outputs.nuGetPreReleaseTagV2 }}"
|
||||
echo "NuGetPreReleaseTag: ${{ steps.gitversion.outputs.nuGetPreReleaseTag }}"
|
||||
echo "VersionSourceSha: ${{ steps.gitversion.outputs.versionSourceSha }}"
|
||||
echo "CommitsSinceVersionSource: ${{ steps.gitversion.outputs.commitsSinceVersionSource }}"
|
||||
echo "CommitsSinceVersionSourcePadded: ${{ steps.gitversion.outputs.commitsSinceVersionSourcePadded }}"
|
||||
echo "UncommittedChanges: ${{ steps.gitversion.outputs.uncommittedChanges }}"
|
||||
echo "CommitDate: ${{ steps.gitversion.outputs.commitDate }}"
|
||||
build-windows:
|
||||
|
|
@ -108,24 +103,12 @@ jobs:
|
|||
with:
|
||||
name: Odamex-Win-x64-pdb
|
||||
path: Output/pdb/*.zip
|
||||
- name: Upload release binary (x64)
|
||||
uses: actions/upload-release-asset@v1.0.2
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
- name: Upload release binary and debug pdb (x64)
|
||||
uses: softprops/action-gh-release@v2.3.4
|
||||
with:
|
||||
upload_url: ${{ env.upload_url }}
|
||||
asset_path: ./Output/zip/odamex-win64-${{env.new_version}}.zip
|
||||
asset_name: odamex-win64-${{env.new_version}}.zip
|
||||
asset_content_type: application/zip
|
||||
- name: Upload debug pdb (x64)
|
||||
uses: actions/upload-release-asset@v1.0.2
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
with:
|
||||
upload_url: ${{ env.upload_url }}
|
||||
asset_path: ./Output/pdb/odamex-debug-pdb-${{env.new_version}}-x64.zip
|
||||
asset_name: odamex-debug-pdb-${{env.new_version}}-x64.zip
|
||||
asset_content_type: application/zip
|
||||
files: |
|
||||
./Output/zip/odamex-win64-${{env.new_version}}.zip
|
||||
./Output/pdb/odamex-debug-pdb-${{env.new_version}}-x64.zip
|
||||
build-windows-x32:
|
||||
name: Windows Build (Visual Studio, 32-bit)
|
||||
needs: pre_job
|
||||
|
|
@ -168,24 +151,12 @@ jobs:
|
|||
with:
|
||||
name: Odamex-Win-x86-pdb
|
||||
path: Output/pdb/*.zip
|
||||
- name: Upload release binary (x86)
|
||||
uses: actions/upload-release-asset@v1.0.2
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
- name: Upload release binary and debug pdb (x86)
|
||||
uses: softprops/action-gh-release@v2.3.4
|
||||
with:
|
||||
upload_url: ${{ env.upload_url }}
|
||||
asset_path: ./Output/zip/odamex-win32-${{env.new_version}}.zip
|
||||
asset_name: odamex-win32-${{env.new_version}}.zip
|
||||
asset_content_type: application/zip
|
||||
- name: Upload debug pdb (x86)
|
||||
uses: actions/upload-release-asset@v1.0.2
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
with:
|
||||
upload_url: ${{ env.upload_url }}
|
||||
asset_path: ./Output/pdb/odamex-debug-pdb-${{env.new_version}}-x86.zip
|
||||
asset_name: odamex-debug-pdb-${{env.new_version}}-x86.zip
|
||||
asset_content_type: application/zip
|
||||
files: |
|
||||
./Output/zip/odamex-win32-${{env.new_version}}.zip
|
||||
./Output/pdb/odamex-debug-pdb-${{env.new_version}}-x86.zip
|
||||
build-flatpak:
|
||||
name: Build Flatpak (Ubuntu Latest)
|
||||
needs: pre_job
|
||||
|
|
@ -222,22 +193,17 @@ jobs:
|
|||
--default-branch=${{ env.MODIFIED_BRANCH_NAME }} -v
|
||||
- name: Pack flatpak
|
||||
run: |
|
||||
flatpak build-bundle repo odamex.flatpak net.odamex.Odamex ${{ env.MODIFIED_BRANCH_NAME }} \
|
||||
flatpak build-bundle repo odamex-linux-x86_64-${{ env.new_version }}.flatpak net.odamex.Odamex ${{ env.MODIFIED_BRANCH_NAME }} \
|
||||
--runtime-repo=https://flathub.org/repo/flathub.flatpakrepo
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: Odamex-Flatpak-x86_64
|
||||
path: odamex.flatpak
|
||||
path: odamex-linux-x86_64-${{ env.new_version }}.flatpak
|
||||
- name: Upload release binary (x86_64)
|
||||
uses: actions/upload-release-asset@v1.0.2
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
uses: softprops/action-gh-release@v2.3.4
|
||||
with:
|
||||
upload_url: ${{ env.upload_url }}
|
||||
asset_path: odamex.flatpak
|
||||
asset_name: odamex-linux-x86_64-${{ env.new_version }}.flatpak
|
||||
asset_content_type: application/octet-stream
|
||||
files: odamex-linux-x86_64-${{ env.new_version }}.flatpak
|
||||
build-flatpak-arm:
|
||||
name: Build Flatpak (Ubuntu 24.04 ARM)
|
||||
needs: pre_job
|
||||
|
|
@ -274,22 +240,19 @@ jobs:
|
|||
--default-branch=${{ env.MODIFIED_BRANCH_NAME }} -v
|
||||
- name: Pack flatpak
|
||||
run: |
|
||||
flatpak build-bundle repo odamex.flatpak net.odamex.Odamex ${{ env.MODIFIED_BRANCH_NAME }} \
|
||||
flatpak build-bundle repo odamex-linux-arm64-${{ env.new_version }}.flatpak net.odamex.Odamex ${{ env.MODIFIED_BRANCH_NAME }} \
|
||||
--runtime-repo=https://flathub.org/repo/flathub.flatpakrepo
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: Odamex-Flatpak-ARM64
|
||||
path: odamex.flatpak
|
||||
path: odamex-linux-arm64-${{ env.new_version }}.flatpak
|
||||
- name: Upload release binary (ARM64)
|
||||
uses: actions/upload-release-asset@v1.0.2
|
||||
uses: softprops/action-gh-release@v2.3.4
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
with:
|
||||
upload_url: ${{ env.upload_url }}
|
||||
asset_path: odamex.flatpak
|
||||
asset_name: odamex-linux-arm64-${{ env.new_version }}.flatpak
|
||||
asset_content_type: application/octet-stream
|
||||
files: odamex-linux-arm64-${{ env.new_version }}.flatpak
|
||||
package-and-upload-windows:
|
||||
name: Package and Upload Artifacts
|
||||
runs-on: windows-latest
|
||||
|
|
@ -323,7 +286,10 @@ jobs:
|
|||
run: ls
|
||||
- name: Install setup compiler
|
||||
shell: pwsh
|
||||
run: choco install innosetup -y --no-progress
|
||||
run: |
|
||||
if (-not (Get-Command iscc -ErrorAction SilentlyContinue)) {
|
||||
choco install innosetup -y --no-progress
|
||||
}
|
||||
- name: Stage and run setup compiler
|
||||
shell: pwsh
|
||||
run: |
|
||||
|
|
@ -338,24 +304,12 @@ jobs:
|
|||
with:
|
||||
name: Odamex-src-zip
|
||||
path: './odamex-src-${{ env.new_version }}.zip'
|
||||
- name: Upload zip to Github Release Artifacts
|
||||
uses: actions/upload-release-asset@v1.0.2
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
- name: Upload zip and installer to Github Release Artifacts
|
||||
uses: softprops/action-gh-release@v2.3.4
|
||||
with:
|
||||
upload_url: ${{ env.upload_url }}
|
||||
asset_path: ./odamex-src-${{env.new_version}}.zip
|
||||
asset_name: odamex-src-${{env.new_version}}.zip
|
||||
asset_content_type: application/zip
|
||||
- name: Upload installer
|
||||
uses: actions/upload-release-asset@v1.0.2
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
with:
|
||||
upload_url: ${{ env.upload_url }}
|
||||
asset_path: ./Output/odamex-win-${{env.new_version}}.exe
|
||||
asset_name: odamex-win-${{env.new_version}}.exe
|
||||
asset_content_type: application/octet-stream
|
||||
files: |
|
||||
./odamex-src-${{env.new_version}}.zip
|
||||
./Output/odamex-win-${{env.new_version}}.exe
|
||||
package-and-upload-unix:
|
||||
name: Package and Upload Artifacts
|
||||
runs-on: ubuntu-latest
|
||||
|
|
@ -391,24 +345,12 @@ jobs:
|
|||
with:
|
||||
name: Odamex-tar-gz
|
||||
path: './*.tar.gz'
|
||||
- name: Upload tar.gz to Github Release Artifacts
|
||||
uses: actions/upload-release-asset@v1.0.2
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
- name: Upload tar.gz and tar.xz to Github Release Artifacts
|
||||
uses: softprops/action-gh-release@v2.3.4
|
||||
with:
|
||||
upload_url: ${{ env.upload_url }}
|
||||
asset_path: ./odamex-src-${{env.new_version}}.tar.gz
|
||||
asset_name: odamex-src-${{env.new_version}}.tar.gz
|
||||
asset_content_type: application/x-gzip
|
||||
- name: Upload tar.xz to Github Release Artifacts
|
||||
uses: actions/upload-release-asset@v1.0.2
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
with:
|
||||
upload_url: ${{ env.upload_url }}
|
||||
asset_path: ./odamex-src-${{env.new_version}}.tar.xz
|
||||
asset_name: odamex-src-${{env.new_version}}.tar.xz
|
||||
asset_content_type: application/x-xz
|
||||
files: |
|
||||
./odamex-src-${{env.new_version}}.tar.gz
|
||||
./odamex-src-${{env.new_version}}.tar.xz
|
||||
update-winget:
|
||||
name: Update WinGet package
|
||||
needs: package-and-upload-windows
|
||||
|
|
|
|||
44
.github/workflows/windows-rc.yml
vendored
44
.github/workflows/windows-rc.yml
vendored
|
|
@ -5,6 +5,9 @@ on:
|
|||
branches:
|
||||
- 'release/[0-9]+.[0-9]+.[0-9]+' # Only run on major.minor.patch releases
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
pre_job:
|
||||
name: Build Preparation
|
||||
|
|
@ -21,12 +24,12 @@ jobs:
|
|||
persist-credentials: false # otherwise, the token used is the GITHUB_TOKEN, instead of your personal token
|
||||
fetch-depth: 0 # Required due to the way Git works, without it this action won't be able to find any or the correct tags
|
||||
- name: Install GitVersion
|
||||
uses: gittools/actions/gitversion/setup@v0.9.7
|
||||
uses: gittools/actions/gitversion/setup@v4.1.0
|
||||
with:
|
||||
versionSpec: '5.x'
|
||||
versionSpec: '6.x'
|
||||
- name: Determine Version
|
||||
id: gitversion
|
||||
uses: gittools/actions/gitversion/execute@v0.9.7
|
||||
uses: gittools/actions/gitversion/execute@v4.1.0
|
||||
- name: Get Commits From Source
|
||||
id: revlist
|
||||
shell: pwsh
|
||||
|
|
@ -44,12 +47,9 @@ jobs:
|
|||
echo "PreReleaseNumber: ${{ steps.gitversion.outputs.preReleaseNumber }}"
|
||||
echo "WeightedPreReleaseNumber: ${{ steps.gitversion.outputs.weightedPreReleaseNumber }}"
|
||||
echo "BuildMetaData: ${{ steps.gitversion.outputs.buildMetaData }}"
|
||||
echo "BuildMetaDataPadded: ${{ steps.gitversion.outputs.buildMetaDataPadded }}"
|
||||
echo "FullBuildMetaData: ${{ steps.gitversion.outputs.fullBuildMetaData }}"
|
||||
echo "MajorMinorPatch: ${{ steps.gitversion.outputs.majorMinorPatch }}"
|
||||
echo "SemVer: ${{ steps.gitversion.outputs.semVer }}"
|
||||
echo "LegacySemVer: ${{ steps.gitversion.outputs.legacySemVer }}"
|
||||
echo "LegacySemVerPadded: ${{ steps.gitversion.outputs.legacySemVerPadded }}"
|
||||
echo "AssemblySemVer: ${{ steps.gitversion.outputs.assemblySemVer }}"
|
||||
echo "AssemblySemFileVer: ${{ steps.gitversion.outputs.assemblySemFileVer }}"
|
||||
echo "FullSemVer: ${{ steps.gitversion.outputs.fullSemVer }}"
|
||||
|
|
@ -58,13 +58,8 @@ jobs:
|
|||
echo "EscapedBranchName: ${{ steps.gitversion.outputs.escapedBranchName }}"
|
||||
echo "Sha: ${{ steps.gitversion.outputs.sha }}"
|
||||
echo "ShortSha: ${{ steps.gitversion.outputs.shortSha }}"
|
||||
echo "NuGetVersionV2: ${{ steps.gitversion.outputs.nuGetVersionV2 }}"
|
||||
echo "NuGetVersion: ${{ steps.gitversion.outputs.nuGetVersion }}"
|
||||
echo "NuGetPreReleaseTagV2: ${{ steps.gitversion.outputs.nuGetPreReleaseTagV2 }}"
|
||||
echo "NuGetPreReleaseTag: ${{ steps.gitversion.outputs.nuGetPreReleaseTag }}"
|
||||
echo "VersionSourceSha: ${{ steps.gitversion.outputs.versionSourceSha }}"
|
||||
echo "CommitsSinceVersionSource: ${{ steps.gitversion.outputs.commitsSinceVersionSource }}"
|
||||
echo "CommitsSinceVersionSourcePadded: ${{ steps.gitversion.outputs.commitsSinceVersionSourcePadded }}"
|
||||
echo "UncommittedChanges: ${{ steps.gitversion.outputs.uncommittedChanges }}"
|
||||
echo "CommitDate: ${{ steps.gitversion.outputs.commitDate }}"
|
||||
echo "TotalCommits: ${{ steps.revlist.outputs.totalCommits }}"
|
||||
|
|
@ -175,6 +170,8 @@ jobs:
|
|||
new_version: ${{ needs.pre_job.outputs.new_version }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-tags: true
|
||||
- name: Run Upversion
|
||||
id: upversion
|
||||
shell: pwsh
|
||||
|
|
@ -196,7 +193,10 @@ jobs:
|
|||
name: Odamex-Win-x64
|
||||
- name: Install setup compiler
|
||||
shell: pwsh
|
||||
run: choco install innosetup -y --no-progress
|
||||
run: |
|
||||
if (-not (Get-Command iscc -ErrorAction SilentlyContinue)) {
|
||||
choco install innosetup -y --no-progress
|
||||
}
|
||||
- name: Stage and run setup compiler
|
||||
shell: pwsh
|
||||
run: |
|
||||
|
|
@ -206,3 +206,23 @@ jobs:
|
|||
with:
|
||||
name: Odamex-Installer
|
||||
path: 'Output/*.exe'
|
||||
- name: Download x86 pdb
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: Odamex-Win-x86-pdb
|
||||
- name: Download x64 pdb
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: Odamex-Win-x64-pdb
|
||||
- name: Create or update prerelease
|
||||
uses: ./.github/actions/update-prerelease
|
||||
env:
|
||||
build_number: ${{ needs.pre_job.outputs.build_number }}
|
||||
new_version: ${{ needs.pre_job.outputs.new_version }}
|
||||
with:
|
||||
build_number: ${{ env.build_number }}
|
||||
new_version: ${{ env.new_version }}
|
||||
files: |
|
||||
./odamex-win*.zip
|
||||
./odamex-debug-*.zip
|
||||
./Output/*.exe
|
||||
|
|
|
|||
10
.github/workflows/windows.yml
vendored
10
.github/workflows/windows.yml
vendored
|
|
@ -4,6 +4,16 @@ on:
|
|||
push:
|
||||
branches-ignore:
|
||||
- 'release/[0-9]+.[0-9]+.[0-9]+'
|
||||
paths-ignore:
|
||||
- "**/*.md"
|
||||
- README
|
||||
- LICENSE
|
||||
- MAINTAINERS
|
||||
- CHANGELOG
|
||||
- 3RD-PARTY-LICENSES
|
||||
- config-samples/*
|
||||
- documentation/**
|
||||
- tools/**
|
||||
pull_request:
|
||||
|
||||
|
||||
|
|
|
|||
4
.gitignore
vendored
4
.gitignore
vendored
|
|
@ -1,6 +1,8 @@
|
|||
.DS_Store
|
||||
/build*
|
||||
/.cache
|
||||
*.vscode
|
||||
*.zed
|
||||
|
||||
# Used by Visual Studio when loading this project as a folder, which uses CMake.
|
||||
/.vs
|
||||
|
|
@ -16,4 +18,4 @@ CMakeSettings.json
|
|||
/packaging/flatpak/.flatpak-builder
|
||||
|
||||
# Generated by fmtlib when building with VS
|
||||
/libraries/fmt/run-msbuild.bat
|
||||
/libraries/fmt/run-msbuild.bat
|
||||
|
|
|
|||
1
.gitmodules
vendored
1
.gitmodules
vendored
|
|
@ -21,7 +21,6 @@
|
|||
[submodule "libraries/jsoncpp"]
|
||||
path = libraries/jsoncpp
|
||||
url = https://github.com/open-source-parsers/jsoncpp.git
|
||||
branch = 0.y.z
|
||||
ignore = dirty
|
||||
[submodule "libraries/portmidi"]
|
||||
path = libraries/portmidi
|
||||
|
|
|
|||
1
.mailmap
Normal file
1
.mailmap
Normal file
|
|
@ -0,0 +1 @@
|
|||
Lexi Mayfield <me@leximayfield.com> <alexmax2742@gmail.com>
|
||||
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
|
||||
project(Odamex VERSION 11.1.1)
|
||||
project(Odamex VERSION 12.0.0)
|
||||
|
||||
include(CMakeDependentOption)
|
||||
|
||||
|
|
@ -78,14 +78,12 @@ if(NOT APPLE AND NOT WIN32)
|
|||
endif()
|
||||
|
||||
set(PROJECT_COPYRIGHT "2006-2025")
|
||||
set(PROJECT_RC_VERSION "11,1,1,0")
|
||||
set(PROJECT_RC_VERSION "12,0,0,0")
|
||||
set(PROJECT_COMPANY "The Odamex Team")
|
||||
|
||||
# Include early required commands for specific systems
|
||||
if (NSWITCH)
|
||||
include("switch.cmake" REQUIRED) # Nintendo Switch
|
||||
elseif(VWII)
|
||||
include("wii.cmake" REQUIRED) # Wii/vWii
|
||||
endif()
|
||||
|
||||
# Ensure that we can use folders in projects.
|
||||
|
|
|
|||
5
GitVersion.yml
Normal file
5
GitVersion.yml
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
branches:
|
||||
release:
|
||||
regex: ^release[/-]
|
||||
prevent-increment:
|
||||
when-current-commit-tagged: true
|
||||
30
MAINTAINERS
30
MAINTAINERS
|
|
@ -1,17 +1,19 @@
|
|||
This code is maintained on https://github.com/odamex/odamex
|
||||
Post bugs to https://github.com/odamex/odamex/issues
|
||||
IRC: irc.oftc.net #odamex
|
||||
DISCORD: https://discord.gg/bvvMJMS
|
||||
Find the Odamex code at: https://github.com/odamex/odamex
|
||||
Post bugs to: https://github.com/odamex/odamex/issues
|
||||
Read our documentation at: https://github.com/odamex/odamex/wiki
|
||||
Visit our Discord server: https://discord.gg/bvvMJMS
|
||||
|
||||
Sean: sean@odamex.net (lead coder) <- patches
|
||||
Manc: mike@odamex.net (services and odamex.net website admin, project manager) <- patches
|
||||
Ralphis: ralphis@odamex.net (project manager)
|
||||
Russell: russell@odamex.net (launcher coder, coder) <- patches
|
||||
Hyper_Eye: mwoodj@huntsvegas.org (coder, osx and xbox package manager)
|
||||
deathz0r: deathz0r@odamex.net (documentation, testing and code cleanups)
|
||||
Ch0wW: ch0ww@baseq.fr (documentation, testing and code cleanups)
|
||||
electricbrass: electricbrass@proton.me (Programmer, Linux Flatpak Maintainer)
|
||||
Hekksy: (Project Manager)
|
||||
Hyper_Eye: mwoodj@huntsvegas.org (Programmer, macOS Package Manager)
|
||||
KBlair: (Programmer)
|
||||
LexiMax: (Programmer)
|
||||
Manc: mike@odamex.net (odamex.net Services & Website Administrator, Project Manager)
|
||||
Ralphis: ralphis@gmail.com (Project Manager)
|
||||
Sean: sean@odamex.net (Programmer)
|
||||
|
||||
Portions of the save/load game system code not already present provided by Marisa from
|
||||
zdoom 1.22 relicensed under the GNU/GPL v2.
|
||||
Portions of the save/load game system code not
|
||||
already present provided by Marisa from zdoom 1.22
|
||||
relicensed under the GNU/GPL v2.
|
||||
|
||||
An archive of our old bug tracker system is available at http://odamex.net/bugs
|
||||
Updated October 14, 2025
|
||||
|
|
|
|||
2
README
2
README
|
|
@ -1,5 +1,5 @@
|
|||
===============================================================================
|
||||
Odamex v11.1.1 README
|
||||
Odamex v12.0.0 README
|
||||
https://odamex.net
|
||||
===============================================================================
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
| Windows Build Status | Mac Build Status | Linux Build Status | Join our Discord! |
|
||||
| -------------------- | ---------------- | ------------------ | ----------------- |
|
||||
| [](https://github.com/odamex/odamex/actions?query=workflow%3AWindows) | [](https://github.com/odamex/odamex/actions?query=workflow%3AmacOS) | [](https://github.com/odamex/odamex/actions?query=workflow%3ALinux) | [](https://discord.gg/aMUzcZE) |
|
||||
| [](https://github.com/odamex/odamex/actions/workflows/windows.yml) | [](https://github.com/odamex/odamex/actions/workflows/macos.yml) | [](https://github.com/odamex/odamex/actions/workflows/linux.yml) | [](https://discord.gg/aMUzcZE) |
|
||||
|
||||
Odamex is a modification of DOOM to allow players to compete with each other over the Internet using a client/server architecture. Thanks to the source code release of DOOM by id Software in December 1997, there have been many modifications that enhanced DOOM in various ways. These modifications are known as "source ports", as early modifications mainly ported DOOM to other platforms and operating systems such as Windows and Macintosh.
|
||||
|
||||
|
|
@ -16,7 +16,7 @@ Odamex supports the following features:
|
|||
* Full Client/Server multiplayer architecture with network compensation features (unlagged, client interpolation and prediction)
|
||||
* Support for up to 255 players
|
||||
* Various compatibility settings, to emulate vanilla Doom, Boom, or ZDoom physics and fixes
|
||||
* Playback and recording of vanilla demos
|
||||
* Playback of vanilla demos
|
||||
* A fully-featured client netdemo record system with playback control
|
||||
* Removal of most vanilla Doom Static limits
|
||||
* Support for most Boom and MBF mapping features
|
||||
|
|
|
|||
313
Xbox/README.Xbox
313
Xbox/README.Xbox
|
|
@ -1,313 +0,0 @@
|
|||
===============================================================================
|
||||
Odamex v11.1.1 for Xbox
|
||||
http://odamex.net/
|
||||
Authored by:
|
||||
Michael "Hyper_Eye" Wood
|
||||
Revision date: November 8, 2020
|
||||
===============================================================================
|
||||
|
||||
Table of contents:
|
||||
1. Introduction
|
||||
1.1 What is Odamex?
|
||||
1.2 Xbox Features at a Glance
|
||||
|
||||
2. Installation
|
||||
2.1 Requirements
|
||||
2.2 Installation - binary download
|
||||
2.3 Installation - source download
|
||||
|
||||
3. Xbox Controls
|
||||
3.1 Launcher
|
||||
3.2 Game Client
|
||||
|
||||
4. Issues
|
||||
4.1 TODO
|
||||
4.2 Known Issues
|
||||
4.3 Bug Reporting
|
||||
|
||||
5. Frequently Asked Questions
|
||||
|
||||
6. Acknowledgements
|
||||
|
||||
===============================================================================
|
||||
|
||||
Section 1: Introduction
|
||||
|
||||
1.1 What is Odamex?
|
||||
|
||||
Odamex is a modification of DOOM to allow players to compete with each other
|
||||
over the Internet using the client/server architecture. Odamex also provides
|
||||
a feature-rich single-player engine.
|
||||
|
||||
Please see the general README provided with Odamex for a thorough description
|
||||
of Odamex and its features.
|
||||
|
||||
1.2 Xbox Features at a Glance
|
||||
|
||||
* Supports all online game modes and features that are available on other
|
||||
platforms
|
||||
* Game launcher with server browser and solo launcher with wad selector
|
||||
* Multiple wad search paths can be configured
|
||||
* Complete analog Xbox controller support with configurable axis assignments,
|
||||
turn sensitivity, optional freelook, and configurable button bindings
|
||||
* Support for USB mouse and keyboard
|
||||
* Saved games and configuration files are stored in UDATA and TDATA paths so
|
||||
they integrate properly with the official memory manager as well as
|
||||
homebrew dashboards complete with icons
|
||||
* Saved games can be deleted using the memory manager
|
||||
* Saved games can be copied to and from a memory card
|
||||
* Vanilla 320x200 resolution, multiple SDTV resolutions including 480i, and
|
||||
HDTV resolutions up to 720p are supported
|
||||
|
||||
===============================================================================
|
||||
|
||||
Section 2. Installation
|
||||
|
||||
2.1 - Requirements
|
||||
|
||||
Odamex requires a modded Xbox in order to operate.
|
||||
|
||||
2.2 - Installation - binary download
|
||||
|
||||
Binary downloads of Odamex are not available from odamex.net or any site
|
||||
associated with The Odamex Team. Because Odamex is built with the official
|
||||
XDK binary builds cannot be provided.
|
||||
|
||||
2.3 - Installation - source download
|
||||
|
||||
If you are interested in the bleeding edge development of Odamex, you can
|
||||
access the SVN at http://odamex.net/svn/root with anonymous read access. Be
|
||||
warned however that it might be incompatible with current release versions,
|
||||
and stability is not guaranteed.
|
||||
|
||||
The following libraries are required:
|
||||
|
||||
* SDLx (http://svn.huntsvegas.org/wsvn/SDLx)
|
||||
|
||||
Additionally the launcher also requires SDLx and the following libraries:
|
||||
|
||||
* pthreads-Xbox (http://svn.huntsvegas.org/wsvn/pthreads-xbox)
|
||||
* Agar (http://www.libagar.org)
|
||||
|
||||
Building the Odamex and AG-Odalaunch source for Xbox requries the use of the
|
||||
Microsoft Xbox Software Development kit (a.k.a XDK). You must be a Microsoft
|
||||
approved Xbox developer to gain access to the required software.
|
||||
|
||||
===============================================================================
|
||||
|
||||
Section 3: Xbox Controls
|
||||
|
||||
3.1 - Launcher
|
||||
|
||||
Left Analog Stick - Move Cursor
|
||||
Left/Right Trigger - Increment/Decrement list selection by 10
|
||||
D-Pad Up/Down - Increment/Decrement list selection by 1
|
||||
Left/Right Trigger (Held) - Scroll list selection
|
||||
D-Pad up/Down (Held) - Scroll list selection
|
||||
D-Pad Left/Right - Cycle focused widget/button
|
||||
A Button - Activate cursor selection
|
||||
B Button - Activate focused widget/button
|
||||
|
||||
3.2 - Game Client
|
||||
|
||||
The D-Pad is used to navigate the game menus while A activates
|
||||
items within the menu and B returns to the previous menu.
|
||||
|
||||
When the console is down the left and right triggers scroll.
|
||||
|
||||
Default Controller Binding:
|
||||
|
||||
Left Analog Stick X Axis - Step left/right
|
||||
Left Analog Stick Y Axis - Move forward/backward
|
||||
Right Analog Stick X Axis - Turn Left/Right
|
||||
Right Analog Stick Y Axis - Look Up/Down (Freelook disabled by default)
|
||||
Right Analog Stick Push Down - Center View
|
||||
D-Pad Up - Say
|
||||
D-Pad Right - Team Say
|
||||
D-Pad Down - Quick Swap to Shotgun & Toggle SG/SSG
|
||||
D-Pad Left - Spectate/Spy Next
|
||||
Left Trigger - Walk/Run
|
||||
Right Trigger - Attack/Fire Weapon
|
||||
A Button - Activate
|
||||
X Button - Strafe
|
||||
B Button - Next Weapon
|
||||
Y Button - Previous Weapon
|
||||
White Button - Scoreboard
|
||||
Black Button - Toggle Automap
|
||||
Start Button - Menu (Not Configurable)
|
||||
Back Button - Toggle Console
|
||||
|
||||
===============================================================================
|
||||
|
||||
Section 4: Issues
|
||||
|
||||
4.1 - TODO
|
||||
|
||||
* Virtual (On-Screen) Keyboard
|
||||
* Configurable overscan in launcher
|
||||
* Rumble
|
||||
* Use a DVD as a wad source
|
||||
* Further optimization (Improve 720p performance)
|
||||
|
||||
4.2 - Known Issues
|
||||
|
||||
* The game currently cannot be launched from a DVD. This is hampered by a bug
|
||||
that is very difficult to debug.
|
||||
* Controller events are not received in the launcher while the master list is
|
||||
being queried or a complete server list refresh is taking place. Joystick
|
||||
events are disabled during these tasks because of a mutex issue or race
|
||||
condition that results in a freeze before processing the final queried
|
||||
server. The cursor can be moved with a mouse during these tasks.
|
||||
* The "Query Master On Start" launcher option does not work. It might be that
|
||||
the Xbox network controller takes a little longer to initialize but I
|
||||
don't really know at this point.
|
||||
* You must hit A inside the main launcher window before you can use B to
|
||||
activate a focused widget. This is due to a window focus issue.
|
||||
* The version of SDLx used with Odamex supports 1080i but 1080i has been
|
||||
disabled in the library as it is not currently usable in Odamex. Selecting
|
||||
1080i results in unplayable framerate and likely a crash when the system
|
||||
runs out of memory.
|
||||
* SDLx reports all 4 joystick ports as active regardless of whether or not a
|
||||
joystick is plugged in. If the active joystick selection is changed to a
|
||||
port that does not have a joystick plugged in control may be lost and a
|
||||
reboot is required or the selection must be changed with a keyboard.
|
||||
|
||||
4.3 - Bug Reporting
|
||||
|
||||
Please report any bugs you find at http://www.odamex.net/bugs
|
||||
Your bug submissions help us make Odamex better. Thank you!
|
||||
|
||||
===============================================================================
|
||||
|
||||
Section 5: Frequently Asked Questions
|
||||
|
||||
Q. How do I communicate with other players?
|
||||
A. Currently there is no way to insert text using the Xbox controller. Xbox
|
||||
players can communicate by either plugging in a USB keyboard or by using
|
||||
chat macros. A virtual keyboard is a planned feature.
|
||||
|
||||
Q. How do the chat macros work?
|
||||
A. While in a multiplayer game push either "Say" (default: D-Pad Up) or
|
||||
"Team Say" (default: D-Pad Right). You can then insert a macro by
|
||||
pushing D-Pad Up + the macro button that corresponds to the message
|
||||
you wish to insert. For example, to say "Hi" to everyone in the game
|
||||
you would press D-Pad Up and then D-Pad Up + A.
|
||||
|
||||
The default macros on Xbox are as follows:
|
||||
|
||||
A - "Hi."
|
||||
B - "I'm ready to kick butt!"
|
||||
X - "Help!"
|
||||
Y - "GG"
|
||||
White - "Yes"
|
||||
Black - "No"
|
||||
Left Trigger - "I'll take care of it."
|
||||
Right Trigger - "Come here!"
|
||||
Start - "Thanks for the game. Bye."
|
||||
Back - "I am on Xbox and can only use chat macros."
|
||||
|
||||
Q. How can I customize the chat macros?
|
||||
A. You will need to manually change them in your odamex.cfg file.
|
||||
To do this perform the following steps:
|
||||
|
||||
1) Launch the Odamex game client from the launcher (a solo game is fine)
|
||||
2) Quit Odamex using the game menus (turning off the power without
|
||||
quitting will discard configuration changes.)
|
||||
3) Quit the launcher and return to your dashboard.
|
||||
4) FTP into the machine or use another method of accessing the file system.
|
||||
5) Copy E:\TDATA\4f444d58\odamex.cfg to your computer.
|
||||
6) Open odamex.cfg in an editor.
|
||||
7) Find the "chatmacro" options and change them as desired (note the order
|
||||
as they correspond to controller buttons above.)
|
||||
8) Save the file.
|
||||
9) Copy odamex.cfg back to E:\TDATA\4f444d58\odamex.cfg
|
||||
|
||||
Q. How do I change my player name without a keyboard?
|
||||
A. You will need to manually change the setting for your player name in
|
||||
your odamex.cfg file. To do this perform the following steps:
|
||||
|
||||
1) Launch the Odamex game client from the launcher (a solo game is fine)
|
||||
2) Quit Odamex using the game menus (turning off the power without
|
||||
quitting will discard configuration changes.)
|
||||
3) Quit the launcher and return to your dashboard.
|
||||
4) FTP into the machine or use another method of accessing the file system.
|
||||
5) Copy E:\TDATA\4f444d58\odamex.cfg to your computer.
|
||||
6) Open odamex.cfg in an editor.
|
||||
7) Find the "cl_name" option and change the name to your desired handle.
|
||||
8) Save the file.
|
||||
9) Copy odamex.cfg back to E:\TDATA\4f444d58\odamex.cfg
|
||||
|
||||
Q. What is required to use a keyboard and/or mouse?
|
||||
A. A simple USB-to-Xbox adapter will work. These can be easily obtained
|
||||
from online stores and auction sites for little cost. A device with a
|
||||
cable modified to use an Xbox safety release cable will also work.
|
||||
|
||||
Q. Is it safe to try all the resolutions listed in the resolution list?
|
||||
A. SDLx scales all resolutions to 640x480 except for 720x480 and 1280x720.
|
||||
Only resolutions that are supported by the AV pack and system settings
|
||||
are shown.
|
||||
|
||||
Q. I have a widescreen television but the 720x480 options isn't available?
|
||||
A. In your Xbox system video settings select "Wide Screen" or "Letterbox".
|
||||
|
||||
Q. I have an HDTV and the HDTV AV Pack but the 1280x720 (720p) option isn't
|
||||
available?
|
||||
A. In your Xbox system video settings enable the 720p HDTV resolution.
|
||||
|
||||
===============================================================================
|
||||
|
||||
Section 6: Acknowledgements
|
||||
|
||||
This port would not be possible without the contributions and assistance of
|
||||
many people. The following especially deserve to be mentioned.
|
||||
|
||||
* Undead of Team Assembly - Undead donated 2 Xbox debug kits that proved
|
||||
to be instrumental in the development of the libraries that Odamex
|
||||
depends on as well as Odamex itself. HUGE thanks to him for his
|
||||
kind donation!
|
||||
|
||||
* Vedge of Hypertriton, Inc. (Developer of Agar) - Agar is a critical
|
||||
piece that serves as the cross-platform GUI toolkit behind AG-Odalaunch.
|
||||
Vedge provided assistance and knowledge as well as bug fixes and feature
|
||||
enhancements that directly benefited the Xbox and the development of
|
||||
AG-Odalaunch. He also trusted me with commit access so that I could
|
||||
more efficiently get code changes into Agar. Thanks for not getting
|
||||
annoyed while I flooded the channel with my thoughts, inquiries, and
|
||||
general ramblings.
|
||||
|
||||
* Sirlemonhead - Sirlemonhead helped get me set up for development and I
|
||||
e-mailed him with questions and ideas on many occasions. Also, he made
|
||||
the AvP port and nobody can thank him enough for that.
|
||||
|
||||
* weinerschnitzel - Provided testing and feedback throughout development.
|
||||
|
||||
* ldotsfan - Bouncing Xbox development tricks back and forth with him has
|
||||
been both an enjoyable and educational experience and I look forward
|
||||
to more of the same.
|
||||
|
||||
* Likklebaer - Thanks for your role in Doom-X and for sharing your experience.
|
||||
|
||||
* To all those at Xbox-Scene that have provided interest, suggestions, and
|
||||
great encouragement. I hope you guys love playing this port as much as I
|
||||
enjoy working on it - Clockface, Cheema201, guybird, ultimate509, neil222,
|
||||
moonmaster1, lawdawg0931, Mega Man (?), flux2k, Pulsemasta, rubarb, Koooi,
|
||||
Finker282, Rygrass, trrobin, |11|1VeNoM1|11|, XTecuterX73
|
||||
|
||||
* Special thanks to the faithful Odamex bug testers and patch contributers who
|
||||
put up with our crap on a daily basis because they believe in Odamex and
|
||||
the philosophies behind it - Spleen, Ladna, HeX9101, tm512, GhostlyDeath,
|
||||
and a hat tip to blzut3
|
||||
|
||||
* To anyone I missed and all the developers in the Xbox development scene that
|
||||
released source and made it possible to work on the system without being
|
||||
completely lost. The Xbox Linux guys, XBMC devs, Arnova and the rest of the
|
||||
XBMC4Xbox devs, XPort, madmab, Team Assembly, RessurectionXtras, Team Evox,
|
||||
MXM devs, everyone who has contributed to openxdk, and all the rest.
|
||||
|
||||
* Finally, all the members of the Odamex development team. Working with you
|
||||
guys is great. I appreciate the maturity, intelligence, and dedication each
|
||||
of you has brought to the team. It is the level-headedness and respect that
|
||||
everyone working on this project maintains that will see Odamex succeed as
|
||||
a great open-source project and Doom source port - Manc, Russell, Ralphis,
|
||||
Denis, and NES
|
||||
===============================================================================
|
||||
624
Xbox/i_xbox.cpp
624
Xbox/i_xbox.cpp
|
|
@ -1,624 +0,0 @@
|
|||
// Emacs style mode select -*- C++ -*-
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Copyright (C) 2006-2025 by The Odamex Team.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
//
|
||||
// DESCRIPTION:
|
||||
// Xbox Support
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifdef _XBOX
|
||||
|
||||
#include <xtl.h>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
#include <list>
|
||||
#include <errno.h>
|
||||
|
||||
#include "i_xbox.h"
|
||||
#include "i_system.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
// Xbox drive letters
|
||||
#define DriveC "\\??\\C:"
|
||||
#define DriveD "\\??\\D:"
|
||||
#define DriveE "\\??\\E:"
|
||||
#define DriveF "\\??\\F:"
|
||||
#define DriveG "\\??\\G:"
|
||||
#define DriveT "\\??\\T:"
|
||||
#define DriveU "\\??\\U:"
|
||||
#define DriveZ "\\??\\Z:"
|
||||
|
||||
// Partition device mapping
|
||||
#define DeviceC "\\Device\\Harddisk0\\Partition2"
|
||||
#define CdRom "\\Device\\CdRom0"
|
||||
#define DeviceE "\\Device\\Harddisk0\\Partition1"
|
||||
#define DeviceF "\\Device\\Harddisk0\\Partition6"
|
||||
#define DeviceG "\\Device\\Harddisk0\\Partition7"
|
||||
#define DeviceT "\\Device\\Harddisk0\\Partition1\\TDATA\\4F444D58"
|
||||
#define DeviceU "\\Device\\Harddisk0\\Partition1\\UDATA\\4F444D58"
|
||||
#define DeviceZ "\\Device\\Harddisk0\\Partition5"
|
||||
|
||||
// Custom LAUNCH_DATA struct for external XBE execution from AG_Execute()
|
||||
#define AG_LAUNCH_MAGIC 0x41474152
|
||||
|
||||
typedef struct {
|
||||
DWORD magic; // Test this against AG_LAUNCH_MAGIC to know this special struct was used
|
||||
DWORD dwID; // The Title ID of the launcher XBE
|
||||
CHAR szLauncherXBE[256]; // The full path to the launcher XBE
|
||||
CHAR szLaunchedXBE[256]; // The full path to the launched XBE
|
||||
CHAR szCmdLine[MAX_LAUNCH_DATA_SIZE - 520]; // The command-line parameters
|
||||
} AG_LAUNCH_DATA, *PAG_LAUNCH_DATA;
|
||||
|
||||
// Standard homebrew custom LAUNCH_DATA designed to launch emu's directly into a game.
|
||||
// This is used to pass custom parameters from many popular dashboards such as XBMC.
|
||||
#define CUSTOM_LAUNCH_MAGIC 0xEE456777
|
||||
|
||||
typedef struct {
|
||||
DWORD magic;
|
||||
CHAR szFilename[300];
|
||||
CHAR szLaunchXBEOnExit[100];
|
||||
CHAR szRemap_D_As[350];
|
||||
BYTE country;
|
||||
BYTE launchInsertedMedia;
|
||||
BYTE executionType;
|
||||
CHAR reserved[MAX_LAUNCH_DATA_SIZE-757];
|
||||
} CUSTOM_LAUNCH_DATA, *PCUSTOM_LAUNCH_DATA;
|
||||
|
||||
#define INVALID_FILE_ATTRIBUTES -1
|
||||
|
||||
typedef struct _STRING
|
||||
{
|
||||
USHORT Length;
|
||||
USHORT MaximumLength;
|
||||
PSTR Buffer;
|
||||
} UNICODE_STRING, *PUNICODE_STRING, ANSI_STRING, *PANSI_STRING;
|
||||
|
||||
// These are undocumented Xbox functions that are not in the XDK includes.
|
||||
// They can be found by looking through the symbols found in the Xbox libs (xapilib.lib mostly).
|
||||
extern "C" XBOXAPI LONG WINAPI IoCreateSymbolicLink(IN PUNICODE_STRING SymbolicLinkName,IN PUNICODE_STRING DeviceName);
|
||||
extern "C" XBOXAPI LONG WINAPI IoDeleteSymbolicLink(IN PUNICODE_STRING SymbolicLinkName);
|
||||
extern "C" XBOXAPI INT WINAPI XWriteTitleInfoAndRebootA(LPVOID,LPVOID,DWORD,DWORD,LPVOID);
|
||||
extern "C" XBOXAPI LONG WINAPI HalWriteSMBusValue(UCHAR devddress, UCHAR offset, UCHAR writedw, DWORD data);
|
||||
|
||||
// External function declarations
|
||||
extern int I_Main(int argc, char *argv[]); // i_main.cpp
|
||||
extern size_t I_BytesToMegabytes (size_t Bytes); // i_system.cpp
|
||||
|
||||
//Globals
|
||||
static std::list<void (*)(void)> ExitFuncList;
|
||||
static DWORD LauncherID;
|
||||
static char *LauncherXBE = NULL;
|
||||
static bool Xbox_RROD = false; // Novelty - Red Ring of DOOM!
|
||||
|
||||
//
|
||||
// xbox_Getenv
|
||||
// Environment variables don't exist on Xbox. Return NULL.
|
||||
//
|
||||
char *xbox_Getenv(const char *)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//
|
||||
// xbox_Putenv
|
||||
//
|
||||
// Environment variables don't exist on Xbox. Just return success.
|
||||
//
|
||||
int xbox_Putenv(const char *)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
// xbox_GetCWD
|
||||
//
|
||||
// Return working directory which is always D:\
|
||||
//
|
||||
char *xbox_GetCWD(char *buf, size_t size)
|
||||
{
|
||||
if(size > 0 && buf)
|
||||
{
|
||||
if(size >= 3)
|
||||
{
|
||||
strcpy(buf, "D:\\");
|
||||
return buf;
|
||||
}
|
||||
else
|
||||
errno = ERANGE;
|
||||
}
|
||||
else
|
||||
errno = EINVAL;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//
|
||||
// xbox_InetNtoa
|
||||
//
|
||||
char *xbox_InetNtoa(struct in_addr in)
|
||||
{
|
||||
static char addr[32];
|
||||
|
||||
sprintf(addr, "%d.%d.%d.%d",
|
||||
in.S_un.S_un_b.s_b1,
|
||||
in.S_un.S_un_b.s_b2,
|
||||
in.S_un.S_un_b.s_b3,
|
||||
in.S_un.S_un_b.s_b4);
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
//
|
||||
// xbox_GetHostByName
|
||||
//
|
||||
// Custom implementation for Xbox
|
||||
//
|
||||
struct hostent *xbox_GetHostByName(const char *name)
|
||||
{
|
||||
static struct hostent *he = NULL;
|
||||
unsigned long addr = INADDR_NONE;
|
||||
WSAEVENT hEvent;
|
||||
XNDNS *pDns = NULL;
|
||||
INT err;
|
||||
|
||||
if(!name)
|
||||
return NULL;
|
||||
|
||||
// This data is static and it should not be freed.
|
||||
if(!he)
|
||||
{
|
||||
he = (struct hostent *)malloc(sizeof(struct hostent));
|
||||
if(!he)
|
||||
{
|
||||
// Failed to allocate!
|
||||
return NULL;
|
||||
}
|
||||
|
||||
he->h_addr_list = (char **)malloc(sizeof(char*));
|
||||
he->h_addr_list[0] = (char *)malloc(sizeof(struct in_addr));
|
||||
}
|
||||
|
||||
if(isdigit(name[0]))
|
||||
addr = inet_addr(name);
|
||||
|
||||
if(addr != INADDR_NONE)
|
||||
*(int *)he->h_addr_list[0] = addr;
|
||||
else
|
||||
{
|
||||
hEvent = WSACreateEvent();
|
||||
err = XNetDnsLookup(name, hEvent, &pDns);
|
||||
|
||||
WaitForSingleObject( (HANDLE)hEvent, INFINITE);
|
||||
|
||||
if(!pDns || pDns->iStatus != 0)
|
||||
return NULL;
|
||||
|
||||
memcpy(he->h_addr_list[0], pDns->aina, sizeof(struct in_addr));
|
||||
|
||||
XNetDnsRelease(pDns);
|
||||
WSACloseEvent(hEvent);
|
||||
}
|
||||
|
||||
return he;
|
||||
}
|
||||
|
||||
//
|
||||
// xbox_GetHostname
|
||||
//
|
||||
// Custom implementation for Xbox
|
||||
//
|
||||
int xbox_GetHostname(char *name, int namelen)
|
||||
{
|
||||
XNADDR xna;
|
||||
DWORD dwState;
|
||||
|
||||
if(name)
|
||||
{
|
||||
if(namelen > 0)
|
||||
{
|
||||
dwState = XNetGetTitleXnAddr(&xna);
|
||||
XNetInAddrToString(xna.ina, name, namelen);
|
||||
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
errno = EINVAL;
|
||||
}
|
||||
else
|
||||
errno = EFAULT;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
//
|
||||
// xbox_PrintMemoryDebug
|
||||
//
|
||||
void xbox_PrintMemoryDebug()
|
||||
{
|
||||
MEMORYSTATUS stat;
|
||||
static DWORD lastmem = 0;
|
||||
char buf[100];
|
||||
|
||||
// Get the memory status.
|
||||
GlobalMemoryStatus(&stat);
|
||||
|
||||
if (stat.dwAvailPhys != lastmem)
|
||||
{
|
||||
sprintf(buf, "\nMemory Debug:\n");
|
||||
OutputDebugString( buf );
|
||||
|
||||
sprintf(buf, "Total Physical Memory: \t%4d bytes / %4d MB\n", stat.dwTotalPhys, I_BytesToMegabytes(stat.dwTotalPhys));
|
||||
OutputDebugString( buf );
|
||||
|
||||
sprintf(buf, "Used Physical Memory : \t%4d bytes / %4d MB\n", stat.dwTotalPhys - stat.dwAvailPhys,
|
||||
I_BytesToMegabytes(stat.dwTotalPhys - stat.dwAvailPhys));
|
||||
OutputDebugString( buf );
|
||||
|
||||
sprintf(buf, "Free Physical Memory : \t%4d bytes / %4d MB\n", stat.dwAvailPhys, I_BytesToMegabytes(stat.dwAvailPhys));
|
||||
OutputDebugString( buf );
|
||||
|
||||
OutputDebugString("\n");
|
||||
|
||||
lastmem = stat.dwAvailPhys;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// xbox_MountDevice
|
||||
//
|
||||
// XBox device mounting
|
||||
//
|
||||
LONG xbox_MountDevice(LPSTR sSymbolicLinkName, LPSTR sDeviceName)
|
||||
{
|
||||
UNICODE_STRING deviceName;
|
||||
deviceName.Buffer = sDeviceName;
|
||||
deviceName.Length = (USHORT)strlen(sDeviceName);
|
||||
deviceName.MaximumLength = (USHORT)strlen(sDeviceName) + 1;
|
||||
|
||||
UNICODE_STRING symbolicLinkName;
|
||||
symbolicLinkName.Buffer = sSymbolicLinkName;
|
||||
symbolicLinkName.Length = (USHORT)strlen(sSymbolicLinkName);
|
||||
symbolicLinkName.MaximumLength = (USHORT)strlen(sSymbolicLinkName) + 1;
|
||||
|
||||
return IoCreateSymbolicLink(&symbolicLinkName, &deviceName);
|
||||
}
|
||||
|
||||
//
|
||||
// xbox_UnMountDevice
|
||||
//
|
||||
LONG xbox_UnMountDevice(LPSTR sSymbolicLinkName)
|
||||
{
|
||||
UNICODE_STRING symbolicLinkName;
|
||||
symbolicLinkName.Buffer = sSymbolicLinkName;
|
||||
symbolicLinkName.Length = (USHORT)strlen(sSymbolicLinkName);
|
||||
symbolicLinkName.MaximumLength = (USHORT)strlen(sSymbolicLinkName) + 1;
|
||||
|
||||
return IoDeleteSymbolicLink(&symbolicLinkName);
|
||||
}
|
||||
|
||||
//
|
||||
// xbox_MountPartitions
|
||||
//
|
||||
// Some of these partitions are automatically mounted but just
|
||||
// to be on the safe side the mount will be attempted anyway
|
||||
//
|
||||
// Some of these partitions are only found on some modded consoles.
|
||||
// These partitions will only successfully mount on consoles where
|
||||
// the modder has created these partitions.
|
||||
//
|
||||
// F is likely to be found on systems that shipped with stock hdd's
|
||||
// that were 10GB in size. Since the Xbox hdd was advertised as 8GB,
|
||||
// 2GB were left unpartitioned on these and that extra space will
|
||||
// typically be partitioned into F: during modding and games or apps
|
||||
// will be installed there (like this one.) F: will also be found
|
||||
// on non-stock hdd's of any size where any space above 8GB and below
|
||||
// 137GB will be partitioned into F:
|
||||
//
|
||||
// G is likely to be found on non-stock hdd's that are larger than 137GB
|
||||
// due to the partition size limitation. Anything above 137GB is partitioned
|
||||
// into G: and it is used, typically, for the same purposes as F.
|
||||
//
|
||||
void xbox_MountPartitions()
|
||||
{
|
||||
xbox_MountDevice(DriveD, CdRom); // DVD-ROM or start path - automounted
|
||||
xbox_MountDevice(DriveE, DeviceE); // Standard save partition
|
||||
xbox_MountDevice(DriveF, DeviceF); // Non-stock partition - modded consoles only
|
||||
xbox_MountDevice(DriveG, DeviceG); // Non-stock partition - modded consoles only
|
||||
xbox_MountDevice(DriveT, DeviceT); // Odamex's unique TDATA - peristent save data (configs, etc.) - automounted
|
||||
xbox_MountDevice(DriveU, DeviceU); // Odamex's unique UDATA - user save data (save games) - automounted
|
||||
xbox_MountDevice(DriveZ, DeviceZ); // Cache partition - appropriate place for temporary files - automounted
|
||||
}
|
||||
|
||||
//
|
||||
// xbox_UnMountPartitions
|
||||
//
|
||||
void xbox_UnMountPartitions()
|
||||
{
|
||||
xbox_UnMountDevice(DriveD);
|
||||
xbox_UnMountDevice(DriveE);
|
||||
xbox_UnMountDevice(DriveF);
|
||||
xbox_UnMountDevice(DriveG);
|
||||
xbox_UnMountDevice(DriveT);
|
||||
xbox_UnMountDevice(DriveU);
|
||||
xbox_UnMountDevice(DriveZ);
|
||||
}
|
||||
|
||||
//
|
||||
// xbox_InitNet
|
||||
//
|
||||
void xbox_InitNet()
|
||||
{
|
||||
XNetStartupParams xnsp;
|
||||
|
||||
ZeroMemory( &xnsp, sizeof(xnsp) );
|
||||
xnsp.cfgSizeOfStruct = sizeof(xnsp);
|
||||
|
||||
xnsp.cfgPrivatePoolSizeInPages = 64; // == 256kb, default = 12 (48kb)
|
||||
xnsp.cfgEnetReceiveQueueLength = 16; // == 32kb, default = 8 (16kb)
|
||||
xnsp.cfgIpFragMaxSimultaneous = 16; // default = 4
|
||||
xnsp.cfgIpFragMaxPacketDiv256 = 32; // == 8kb, default = 8 (2kb)
|
||||
xnsp.cfgSockMaxSockets = 64; // default = 64
|
||||
xnsp.cfgSockDefaultRecvBufsizeInK = 128; // default = 16
|
||||
xnsp.cfgSockDefaultSendBufsizeInK = 128; // default = 16
|
||||
|
||||
// Bypass security so we can talk to the outside world as we please
|
||||
xnsp.cfgFlags = XNET_STARTUP_BYPASS_SECURITY;
|
||||
|
||||
XNetStartup( &xnsp );
|
||||
}
|
||||
|
||||
//
|
||||
// xbox_CloseNetwork
|
||||
//
|
||||
void xbox_CloseNetwork()
|
||||
{
|
||||
XNetCleanup();
|
||||
}
|
||||
|
||||
//
|
||||
// xbox_WriteSaveMeta
|
||||
//
|
||||
void xbox_WriteSaveMeta(string path, string text)
|
||||
{
|
||||
if(!path.size() || !text.size())
|
||||
return;
|
||||
|
||||
string filename = path + PATHSEP + "SaveMeta.xbx";
|
||||
ofstream metafile(filename.c_str());
|
||||
|
||||
if(metafile.fail())
|
||||
{
|
||||
I_Error ("Failed to create %s save meta:\n%s",
|
||||
filename.c_str(), strerror (errno));
|
||||
return;
|
||||
}
|
||||
|
||||
metafile << "Name=" << text;
|
||||
|
||||
metafile.close();
|
||||
}
|
||||
|
||||
//
|
||||
// xbox_GetSavePath
|
||||
//
|
||||
string xbox_GetSavePath(string file, int slot)
|
||||
{
|
||||
ostringstream path;
|
||||
DWORD attrs;
|
||||
|
||||
path << setiosflags(ios::right);
|
||||
path << setfill('0');
|
||||
|
||||
path << "U:" << PATHSEP << setw(12) << slot;
|
||||
|
||||
if((attrs = GetFileAttributes(path.str().c_str())) == INVALID_FILE_ATTRIBUTES)
|
||||
{
|
||||
if(!SUCCEEDED(CreateDirectory(path.str().c_str(), NULL)))
|
||||
{
|
||||
I_FatalError ("Failed to create %s directory:\n%s",
|
||||
path.str().c_str(), strerror (errno));
|
||||
}
|
||||
|
||||
xbox_WriteSaveMeta(path.str(), "Empty Slot");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(attrs & FILE_ATTRIBUTE_DIRECTORY))
|
||||
I_FatalError ("%s must be a directory", path.str().c_str());
|
||||
}
|
||||
|
||||
path << PATHSEP << file;
|
||||
|
||||
return path.str();
|
||||
}
|
||||
|
||||
//
|
||||
// xbox_EnableCustomLED
|
||||
//
|
||||
void xbox_EnableCustomLED()
|
||||
{
|
||||
// 0xF0 = Solid Red
|
||||
HalWriteSMBusValue(0x20, 0x08, 0, 0xF0);
|
||||
Sleep(10);
|
||||
HalWriteSMBusValue(0x20, 0x07, 0, 1);
|
||||
}
|
||||
|
||||
//
|
||||
// xbox_DisableCustomLED
|
||||
//
|
||||
void xbox_DisableCustomLED()
|
||||
{
|
||||
HalWriteSMBusValue(0x20, 0x07, 0, 0);
|
||||
}
|
||||
|
||||
//
|
||||
// xbox_RecordLauncherXBE
|
||||
//
|
||||
void xbox_RecordLauncherXBE(char *szLauncherXBE, DWORD dwID)
|
||||
{
|
||||
if(szLauncherXBE && !LauncherXBE)
|
||||
{
|
||||
LauncherXBE = strdup(szLauncherXBE);
|
||||
LauncherID = dwID;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// xbox_reboot
|
||||
//
|
||||
// Exit Odamex and perform a warm reboot (no startup logo) to a launcher or dashboard
|
||||
//
|
||||
void xbox_Reboot()
|
||||
{
|
||||
LD_LAUNCH_DASHBOARD launchData = { XLD_LAUNCH_DASHBOARD_MAIN_MENU };
|
||||
|
||||
// If Odamex was started from a launcher we want to return to it.
|
||||
if(LauncherXBE)
|
||||
{
|
||||
size_t pathLen;
|
||||
char *mntDev;
|
||||
char *p;
|
||||
|
||||
// Determine the necessary D: mapping for the launcher XBE
|
||||
p = strrchr(LauncherXBE, PATHSEPCHAR);
|
||||
pathLen = p - LauncherXBE;
|
||||
|
||||
mntDev = (char *)malloc(pathLen + 1);
|
||||
memcpy(mntDev, LauncherXBE, pathLen);
|
||||
mntDev[pathLen] = '\0'; // This is necessary
|
||||
|
||||
p++; // Now conveniently Points to the start of our XBE name with path stripped off.
|
||||
|
||||
// Return to the launcher XBE
|
||||
XWriteTitleInfoAndRebootA(p, mntDev, LDT_TITLE, LauncherID, &launchData);
|
||||
}
|
||||
|
||||
// Return to the dashboard
|
||||
XLaunchNewImage( NULL, (LAUNCH_DATA*)&launchData );
|
||||
}
|
||||
|
||||
//
|
||||
// xbox_AtExit
|
||||
//
|
||||
// Custom atexit function for Xbox
|
||||
//
|
||||
void xbox_AtExit(void (*function)(void))
|
||||
{
|
||||
if(function)
|
||||
ExitFuncList.push_back(function);
|
||||
}
|
||||
|
||||
//
|
||||
// xbox_Exit
|
||||
//
|
||||
// Custom exit function for Xbox
|
||||
//
|
||||
void xbox_Exit(int status)
|
||||
{
|
||||
std::list<void (*)(void)>::iterator funcIter;
|
||||
|
||||
for(funcIter = ExitFuncList.begin(); funcIter != ExitFuncList.end(); ++funcIter)
|
||||
(*funcIter)();
|
||||
|
||||
xbox_CloseNetwork();
|
||||
|
||||
xbox_UnMountPartitions();
|
||||
|
||||
if(Xbox_RROD)
|
||||
xbox_DisableCustomLED();
|
||||
|
||||
xbox_Reboot();
|
||||
}
|
||||
|
||||
//
|
||||
// xbox_PrepareArgs
|
||||
//
|
||||
// Convert to standard C arguments
|
||||
void xbox_PrepareArgs(string cmdline, char *argv[], int &argc)
|
||||
{
|
||||
if(cmdline.size())
|
||||
{
|
||||
size_t pos, oldpos = 0;
|
||||
|
||||
do
|
||||
{
|
||||
if(cmdline[oldpos] == '"')
|
||||
pos = cmdline.find('"', ++oldpos);
|
||||
else
|
||||
pos = cmdline.find(' ', oldpos);
|
||||
|
||||
if(pos != oldpos)
|
||||
{
|
||||
argv[argc] = strdup(cmdline.substr(oldpos, pos - oldpos).c_str());
|
||||
|
||||
if(!stricmp(argv[argc], "-rrod"))
|
||||
Xbox_RROD = true;
|
||||
|
||||
argc++;
|
||||
}
|
||||
|
||||
oldpos = pos + 1;
|
||||
} while(pos != string::npos);
|
||||
}
|
||||
|
||||
argv[argc] = NULL;
|
||||
}
|
||||
|
||||
//
|
||||
// main
|
||||
//
|
||||
// Entry point on Xbox
|
||||
//
|
||||
void __cdecl main()
|
||||
{
|
||||
DWORD launchDataType;
|
||||
LAUNCH_DATA launchData;
|
||||
char *xargv[100];
|
||||
int xargc = 1;
|
||||
|
||||
xargv[0] = strdup("D:\\default.xbe"); // mimic argv[0]
|
||||
|
||||
if(XGetLaunchInfo (&launchDataType, &launchData) == ERROR_SUCCESS)
|
||||
{
|
||||
// Command line from debugger
|
||||
if(launchDataType == LDT_FROM_DEBUGGER_CMDLINE)
|
||||
xbox_PrepareArgs((char*)((PLD_FROM_DEBUGGER_CMDLINE)&launchData)->szCmdLine, xargv, xargc);
|
||||
// Command line from homebrew dashboards (XBMC, etc.)
|
||||
else if(launchDataType == LDT_TITLE && ((PCUSTOM_LAUNCH_DATA)&launchData)->magic == CUSTOM_LAUNCH_MAGIC)
|
||||
xbox_PrepareArgs((char*)((PCUSTOM_LAUNCH_DATA)&launchData)->szFilename, xargv, xargc);
|
||||
// Command line from Agar application (AG_Odalaunch)
|
||||
else if(launchDataType == LDT_TITLE && ((PAG_LAUNCH_DATA)&launchData)->magic == AG_LAUNCH_MAGIC)
|
||||
{
|
||||
xbox_RecordLauncherXBE(((PAG_LAUNCH_DATA)&launchData)->szLauncherXBE, ((PAG_LAUNCH_DATA)&launchData)->dwID);
|
||||
xbox_PrepareArgs((char*)((PAG_LAUNCH_DATA)&launchData)->szCmdLine, xargv, xargc);
|
||||
}
|
||||
}
|
||||
|
||||
xbox_MountPartitions();
|
||||
|
||||
xbox_InitNet();
|
||||
|
||||
if(Xbox_RROD)
|
||||
xbox_EnableCustomLED();
|
||||
|
||||
I_Main(xargc, xargv); // Does not return
|
||||
}
|
||||
|
||||
#endif // _XBOX
|
||||
|
|
@ -1,77 +0,0 @@
|
|||
// Emacs style mode select -*- C++ -*-
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Copyright (C) 2006-2025 by The Odamex Team.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
//
|
||||
// DESCRIPTION:
|
||||
// Xbox Support
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _I_XBOX_H
|
||||
#define _I_XBOX_H
|
||||
|
||||
#ifdef _XBOX
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
struct hostent
|
||||
{
|
||||
char *h_name; /* canonical name of host */
|
||||
char **h_aliases; /* alias list */
|
||||
int h_addrtype; /* host address type */
|
||||
int h_length; /* length of address */
|
||||
char **h_addr_list; /* list of addresses */
|
||||
#define h_addr h_addr_list[0]
|
||||
};
|
||||
|
||||
// Xbox function overrides
|
||||
#undef getenv
|
||||
#define getenv xbox_Getenv
|
||||
#undef putenv
|
||||
#define putenv xbox_Putenv
|
||||
#undef getcwd
|
||||
#define getcwd xbox_GetCWD
|
||||
#undef exit
|
||||
#define exit xbox_Exit
|
||||
#undef atexit
|
||||
#define atexit xbox_AtExit
|
||||
#define inet_ntoa xbox_InetNtoa
|
||||
#define gethostbyname xbox_GetHostByName
|
||||
#define gethostname xbox_GetHostname
|
||||
|
||||
// Xbox function override declarations
|
||||
char *xbox_Getenv(const char *);
|
||||
int xbox_Putenv(const char *);
|
||||
char *xbox_GetCWD(char *buf, size_t size);
|
||||
char *xbox_InetNtoa(struct in_addr in);
|
||||
struct hostent *xbox_GetHostByName(const char *name);
|
||||
int xbox_GetHostname(char *name, int namelen);
|
||||
void xbox_Exit(int status);
|
||||
void xbox_AtExit(void (*function)(void));
|
||||
|
||||
// Print useful memory information for debugging
|
||||
void xbox_PrintMemoryDebug();
|
||||
|
||||
// Write a SaveMeta.xbx file
|
||||
void xbox_WriteSaveMeta(std::string path, std::string text);
|
||||
|
||||
// Get a unique save path for a save slot
|
||||
std::string xbox_GetSavePath(std::string file, int slot);
|
||||
|
||||
#endif // _XBOX
|
||||
|
||||
#endif // _I_XBOX_H
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
Microsoft Visual Studio Solution File, Format Version 8.00
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "odamex", "odamex.vcproj", "{70469239-A02A-4D90-8C58-A1613FCE3F21}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfiguration) = preSolution
|
||||
Debug = Debug
|
||||
Profile = Profile
|
||||
Profile_FastCap = Profile_FastCap
|
||||
Release = Release
|
||||
Release_LTCG = Release_LTCG
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfiguration) = postSolution
|
||||
{70469239-A02A-4D90-8C58-A1613FCE3F21}.Debug.ActiveCfg = Debug|Xbox
|
||||
{70469239-A02A-4D90-8C58-A1613FCE3F21}.Debug.Build.0 = Debug|Xbox
|
||||
{70469239-A02A-4D90-8C58-A1613FCE3F21}.Profile.ActiveCfg = Profile|Xbox
|
||||
{70469239-A02A-4D90-8C58-A1613FCE3F21}.Profile.Build.0 = Profile|Xbox
|
||||
{70469239-A02A-4D90-8C58-A1613FCE3F21}.Profile_FastCap.ActiveCfg = Profile_FastCap|Xbox
|
||||
{70469239-A02A-4D90-8C58-A1613FCE3F21}.Profile_FastCap.Build.0 = Profile_FastCap|Xbox
|
||||
{70469239-A02A-4D90-8C58-A1613FCE3F21}.Release.ActiveCfg = Release|Xbox
|
||||
{70469239-A02A-4D90-8C58-A1613FCE3F21}.Release.Build.0 = Release|Xbox
|
||||
{70469239-A02A-4D90-8C58-A1613FCE3F21}.Release_LTCG.ActiveCfg = Release_LTCG|Xbox
|
||||
{70469239-A02A-4D90-8C58-A1613FCE3F21}.Release_LTCG.Build.0 = Release_LTCG|Xbox
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityAddIns) = postSolution
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
1210
Xbox/odamex.vcproj
1210
Xbox/odamex.vcproj
File diff suppressed because it is too large
Load diff
|
|
@ -42,6 +42,7 @@ if(LibAgar_FOUND)
|
|||
set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${PROJECT_VERSION}")
|
||||
set(MACOSX_BUNDLE_BUNDLE_VERSION "${PROJECT_VERSION}")
|
||||
set(MACOSX_BUNDLE_ICON_FILE odalaunch.icns)
|
||||
set(MACOSX_BUNDLE_GUI_IDENTIFIER net.odamex.ag-odalaunch)
|
||||
|
||||
if(APPLE)
|
||||
add_custom_command(
|
||||
|
|
|
|||
|
|
@ -19,13 +19,13 @@
|
|||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>11.1.1</string>
|
||||
<string>12.0.0</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>11.1.1</string>
|
||||
<string>12.0.0</string>
|
||||
<key>CFBundleGetInfoString</key>
|
||||
<string>Copyright © 2006-2025 The Odamex Team</string>
|
||||
<key>CFBundleLongVersionString</key>
|
||||
<string>11.1.1</string>
|
||||
<string>12.0.0</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright © 2006-2025 The Odamex Team</string>
|
||||
<key>LSRequiresCarbon</key>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Emacs style mode select -*- C++ -*-
|
||||
// Emacs style mode select -*- C++ -*-
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// $Id$
|
||||
|
|
@ -42,10 +42,6 @@
|
|||
#include "typedefs.h"
|
||||
#include "icons.h"
|
||||
|
||||
#ifdef _XBOX
|
||||
#include "xbox_main.h"
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace agOdalaunch {
|
||||
|
|
@ -64,7 +60,7 @@ AGOL_MainWindow::AGOL_MainWindow(int width, int height) :
|
|||
ManualDialog(NULL), CloseManualHandler(NULL),
|
||||
QServer(NULL), WindowExited(false)
|
||||
{
|
||||
// Create the Agar window. If we are using a single-window display driver (sdlfb, sdlgl)
|
||||
// Create the Agar window. If we are using a single-window display driver (sdlfb, sdlgl)
|
||||
// make the window plain (no window decorations). No flags for multi-window drivers (glx, wgl)
|
||||
MainWindow = AG_WindowNewNamedS(agDriverSw ? AG_WINDOW_PLAIN : 0, "MainWindow");
|
||||
AG_WindowSetGeometryAligned(MainWindow, AG_WINDOW_MC, width, height);
|
||||
|
|
@ -89,12 +85,12 @@ AGOL_MainWindow::AGOL_MainWindow(int width, int height) :
|
|||
AG_WindowMaximize(MainWindow);
|
||||
|
||||
// Add the show event
|
||||
AG_AddEvent(MainWindow, "window-shown", EventReceiver, "%p",
|
||||
AG_AddEvent(MainWindow, "window-shown", EventReceiver, "%p",
|
||||
RegisterEventHandler((EVENT_FUNC_PTR)&AGOL_MainWindow::OnShow));
|
||||
|
||||
// Set the window close action
|
||||
AG_WindowSetCloseAction(MainWindow, AG_WINDOW_DETACH);
|
||||
AG_AddEvent(MainWindow, "window-close", EventReceiver, "%p",
|
||||
AG_AddEvent(MainWindow, "window-close", EventReceiver, "%p",
|
||||
RegisterEventHandler((EVENT_FUNC_PTR)&AGOL_MainWindow::ExitWindow));
|
||||
|
||||
// Add the save widget states event
|
||||
|
|
@ -121,7 +117,7 @@ AGOL_MainWindow::~AGOL_MainWindow()
|
|||
{
|
||||
// If the window exit action has not been performed by this time
|
||||
// then the driver being used is a single-window driver that does
|
||||
// not trigger the exit action when the window is closed (due to
|
||||
// not trigger the exit action when the window is closed (due to
|
||||
// the fact that the close button is actually for the driver window
|
||||
// itself.) In that case it should be safe to save the widget states
|
||||
// because the window is actually still valid. In all other cases
|
||||
|
|
@ -195,51 +191,51 @@ AG_Menu *AGOL_MainWindow::CreateMainMenu(void *parent)
|
|||
|
||||
// File menu
|
||||
m = AG_MenuNode(menu->root, "File", NULL);
|
||||
AG_MenuAction(m, "Settings", agIconGear.s, EventReceiver, "%p",
|
||||
AG_MenuAction(m, "Settings", agIconGear.s, EventReceiver, "%p",
|
||||
RegisterEventHandler((EVENT_FUNC_PTR)&AGOL_MainWindow::OnOpenSettingsDialog));
|
||||
AG_MenuSeparator(m);
|
||||
AG_MenuActionKb(m, "Exit", agIconClose.s, AG_KEY_Q, AG_KEYMOD_CTRL,
|
||||
AG_MenuActionKb(m, "Exit", agIconClose.s, AG_KEY_Q, AG_KEYMOD_CTRL,
|
||||
EventReceiver, "%p", RegisterEventHandler((EVENT_FUNC_PTR)&AGOL_MainWindow::OnExit));
|
||||
|
||||
// Action menu
|
||||
m = AG_MenuNode(menu->root, "Action", NULL);
|
||||
AG_MenuAction(m, "Launch", NULL, EventReceiver, "%p",
|
||||
AG_MenuAction(m, "Launch", NULL, EventReceiver, "%p",
|
||||
RegisterEventHandler((EVENT_FUNC_PTR)&AGOL_MainWindow::OnLaunch));
|
||||
AG_MenuAction(m, "Run Offline", NULL, EventReceiver, "%p",
|
||||
AG_MenuAction(m, "Run Offline", NULL, EventReceiver, "%p",
|
||||
RegisterEventHandler((EVENT_FUNC_PTR)&AGOL_MainWindow::OnOfflineLaunch));
|
||||
AG_MenuSeparator(m);
|
||||
AG_MenuAction(m, "Refresh Selected", NULL, EventReceiver, "%p",
|
||||
AG_MenuAction(m, "Refresh Selected", NULL, EventReceiver, "%p",
|
||||
RegisterEventHandler((EVENT_FUNC_PTR)&AGOL_MainWindow::OnRefreshSelected));
|
||||
AG_MenuAction(m, "Refresh All", NULL, EventReceiver, "%p",
|
||||
AG_MenuAction(m, "Refresh All", NULL, EventReceiver, "%p",
|
||||
RegisterEventHandler((EVENT_FUNC_PTR)&AGOL_MainWindow::OnRefreshAll));
|
||||
AG_MenuAction(m, "Get Master List", NULL, EventReceiver, "%p",
|
||||
AG_MenuAction(m, "Get Master List", NULL, EventReceiver, "%p",
|
||||
RegisterEventHandler((EVENT_FUNC_PTR)&AGOL_MainWindow::OnGetMasterList));
|
||||
|
||||
// Tools Menu
|
||||
m = AG_MenuNode(menu->root, "Tools", NULL);
|
||||
m = AG_MenuNode(m, "OdaGet", NULL);
|
||||
AG_MenuDisable(m);
|
||||
AG_MenuAction(m, "Get WAD", NULL, EventReceiver, "%p",
|
||||
AG_MenuAction(m, "Get WAD", NULL, EventReceiver, "%p",
|
||||
RegisterEventHandler((EVENT_FUNC_PTR)&AGOL_MainWindow::OnGetWAD));
|
||||
AG_MenuAction(m, "Configure", NULL, EventReceiver, "%p",
|
||||
AG_MenuAction(m, "Configure", NULL, EventReceiver, "%p",
|
||||
RegisterEventHandler((EVENT_FUNC_PTR)&AGOL_MainWindow::OnOdaGetConfig));
|
||||
AG_MenuEnable(m);
|
||||
|
||||
// Advanced menu
|
||||
m = AG_MenuNode(menu->root, "Advanced", NULL);
|
||||
AG_MenuAction(m, "Manual Connect", NULL, EventReceiver, "%p",
|
||||
AG_MenuAction(m, "Manual Connect", NULL, EventReceiver, "%p",
|
||||
RegisterEventHandler((EVENT_FUNC_PTR)&AGOL_MainWindow::OnManualConnect));
|
||||
AG_MenuDisable(m);
|
||||
AG_MenuAction(m, "Custom Servers", NULL, EventReceiver, "%p",
|
||||
AG_MenuAction(m, "Custom Servers", NULL, EventReceiver, "%p",
|
||||
RegisterEventHandler((EVENT_FUNC_PTR)&AGOL_MainWindow::OnCustomServer));
|
||||
AG_MenuEnable(m);
|
||||
|
||||
|
||||
// Help menu
|
||||
m = AG_MenuNode(menu->root, "Help", NULL);
|
||||
AG_MenuAction(m, "Report Bug", NULL, EventReceiver, "%p",
|
||||
AG_MenuAction(m, "Report Bug", NULL, EventReceiver, "%p",
|
||||
RegisterEventHandler((EVENT_FUNC_PTR)&AGOL_MainWindow::OnReportBug));
|
||||
AG_MenuSeparator(m);
|
||||
AG_MenuAction(m, "About", NULL, EventReceiver, "%p",
|
||||
AG_MenuAction(m, "About", NULL, EventReceiver, "%p",
|
||||
RegisterEventHandler((EVENT_FUNC_PTR)&AGOL_MainWindow::OnAbout));
|
||||
|
||||
return menu;
|
||||
|
|
@ -253,30 +249,30 @@ ODA_ButtonBox *AGOL_MainWindow::CreateMainButtonBox(void *parent)
|
|||
|
||||
bbox->buttonbox = AG_BoxNewHoriz(parent, AG_BOX_HFILL);
|
||||
|
||||
bbox->launch = CreateButton(bbox->buttonbox, "Launch", odalaunchico,
|
||||
bbox->launch = CreateButton(bbox->buttonbox, "Launch", odalaunchico,
|
||||
sizeof(odalaunchico), (EVENT_FUNC_PTR)&AGOL_MainWindow::OnLaunch);
|
||||
bbox->qlaunch = CreateButton(bbox->buttonbox, "Quick Launch", odaqlaunchico,
|
||||
bbox->qlaunch = CreateButton(bbox->buttonbox, "Quick Launch", odaqlaunchico,
|
||||
sizeof(odaqlaunchico), (EVENT_FUNC_PTR)&AGOL_MainWindow::OnOfflineLaunch);
|
||||
|
||||
AG_SeparatorNewVert(bbox->buttonbox);
|
||||
|
||||
bbox->refresh = CreateButton(bbox->buttonbox, "Refresh Selected", btnrefreshico,
|
||||
bbox->refresh = CreateButton(bbox->buttonbox, "Refresh Selected", btnrefreshico,
|
||||
sizeof(btnrefreshico), (EVENT_FUNC_PTR)&AGOL_MainWindow::OnRefreshSelected);
|
||||
bbox->refreshall = CreateButton(bbox->buttonbox, "Refresh All", btnrefreshallico,
|
||||
bbox->refreshall = CreateButton(bbox->buttonbox, "Refresh All", btnrefreshallico,
|
||||
sizeof(btnrefreshico), (EVENT_FUNC_PTR)&AGOL_MainWindow::OnRefreshAll);
|
||||
bbox->mlist = CreateButton(bbox->buttonbox, "Query Master", btnlistico,
|
||||
bbox->mlist = CreateButton(bbox->buttonbox, "Query Master", btnlistico,
|
||||
sizeof(btnlistico), (EVENT_FUNC_PTR)&AGOL_MainWindow::OnGetMasterList);
|
||||
|
||||
AG_SeparatorNewVert(bbox->buttonbox);
|
||||
|
||||
bbox->settings = CreateButton(bbox->buttonbox, "Settings", btnsettingsico,
|
||||
bbox->settings = CreateButton(bbox->buttonbox, "Settings", btnsettingsico,
|
||||
sizeof(btnsettingsico), (EVENT_FUNC_PTR)&AGOL_MainWindow::OnOpenSettingsDialog);
|
||||
bbox->about = CreateButton(bbox->buttonbox, "About", btnhelpico,
|
||||
bbox->about = CreateButton(bbox->buttonbox, "About", btnhelpico,
|
||||
sizeof(btnhelpico), (EVENT_FUNC_PTR)&AGOL_MainWindow::OnAbout);
|
||||
|
||||
AG_SeparatorNewVert(bbox->buttonbox);
|
||||
|
||||
bbox->exit = CreateButton(bbox->buttonbox, "Exit", btnexitico,
|
||||
bbox->exit = CreateButton(bbox->buttonbox, "Exit", btnexitico,
|
||||
sizeof(btnexitico), (EVENT_FUNC_PTR)&AGOL_MainWindow::OnExit);
|
||||
|
||||
return bbox;
|
||||
|
|
@ -315,13 +311,13 @@ AG_Table *AGOL_MainWindow::CreateServerList(void *parent)
|
|||
ostringstream colSzSpec[8];
|
||||
int colW[8] = { 200, 33, 48, 100, 47, 105, 72, 125 };
|
||||
|
||||
list = AG_TableNewPolled(parent, AG_TABLE_EXPAND, EventReceiver, "%p",
|
||||
list = AG_TableNewPolled(parent, AG_TABLE_EXPAND, EventReceiver, "%p",
|
||||
RegisterEventHandler((EVENT_FUNC_PTR)&AGOL_MainWindow::UpdateServerList));
|
||||
|
||||
AG_TableSetRowDblClickFn(list, EventReceiver, "%p",
|
||||
AG_TableSetRowDblClickFn(list, EventReceiver, "%p",
|
||||
RegisterEventHandler((EVENT_FUNC_PTR)&AGOL_MainWindow::OnLaunch));
|
||||
|
||||
AG_SetEvent(list, "row-selected", EventReceiver, "%p",
|
||||
AG_SetEvent(list, "row-selected", EventReceiver, "%p",
|
||||
RegisterEventHandler((EVENT_FUNC_PTR)&AGOL_MainWindow::OnServerListRowSelected));
|
||||
|
||||
// Configure each columns size spec
|
||||
|
|
@ -350,7 +346,7 @@ AG_Table *AGOL_MainWindow::CreateServerList(void *parent)
|
|||
AG_TableAddCol(list, "Address : Port", colSzSpec[7].str().c_str(), NULL);
|
||||
|
||||
// Add an update event that we can schedule without enabling polling
|
||||
AG_SetEvent(list, "update-items", EventReceiver, "%p",
|
||||
AG_SetEvent(list, "update-items", EventReceiver, "%p",
|
||||
RegisterEventHandler((EVENT_FUNC_PTR)&AGOL_MainWindow::UpdateServerList));
|
||||
|
||||
return list;
|
||||
|
|
@ -437,8 +433,8 @@ void AGOL_MainWindow::UpdateStatusbarMasterPing(uint64_t ping)
|
|||
AG_LabelText(MainStatusbar->mping, "Master Ping: %lu", ping);
|
||||
}
|
||||
|
||||
AG_Button *AGOL_MainWindow::CreateButton(void *parent, const char *label,
|
||||
const unsigned char *icon, int iconsize,
|
||||
AG_Button *AGOL_MainWindow::CreateButton(void *parent, const char *label,
|
||||
const unsigned char *icon, int iconsize,
|
||||
EVENT_FUNC_PTR handler)
|
||||
{
|
||||
AG_Button *button;
|
||||
|
|
@ -446,7 +442,7 @@ AG_Button *AGOL_MainWindow::CreateButton(void *parent, const char *label,
|
|||
|
||||
button = AG_ButtonNewFn(parent, 0, label, EventReceiver, "%p", RegisterEventHandler(handler));
|
||||
|
||||
AG_SetEvent(button, "button-mouseoverlap", EventReceiver, "%p",
|
||||
AG_SetEvent(button, "button-mouseoverlap", EventReceiver, "%p",
|
||||
RegisterEventHandler((EVENT_FUNC_PTR)&AGOL_MainWindow::OnMouseOverWidget));
|
||||
|
||||
|
||||
|
|
@ -539,7 +535,7 @@ int AGOL_MainWindow::GetServerListRowFromAddr(const string &address)
|
|||
string cellAddr;
|
||||
|
||||
cellAddr = GetAddrFromServerListRow(row);
|
||||
|
||||
|
||||
if(!cellAddr.size())
|
||||
continue;
|
||||
|
||||
|
|
@ -616,12 +612,12 @@ void AGOL_MainWindow::UpdatePlayerList(int serverNdx)
|
|||
AG_Surface *(*teamFn)(void*,int,int) = NullSurfFn;
|
||||
AG_Surface *(*specFn)(void*,int,int) = NullSurfFn;
|
||||
string name = " ";
|
||||
|
||||
|
||||
if(QServer[serverNdx].Info.Players[i].Name.size())
|
||||
name = QServer[serverNdx].Info.Players[i].Name;
|
||||
|
||||
// Team pixmap
|
||||
if(QServer[serverNdx].Info.GameType == GT_TeamDeathmatch ||
|
||||
if(QServer[serverNdx].Info.GameType == GT_TeamDeathmatch ||
|
||||
QServer[serverNdx].Info.GameType == GT_CaptureTheFlag)
|
||||
{
|
||||
switch(QServer[serverNdx].Info.Players[i].Team)
|
||||
|
|
@ -644,7 +640,7 @@ void AGOL_MainWindow::UpdatePlayerList(int serverNdx)
|
|||
}
|
||||
|
||||
AG_TableAddRow(PlayerList, "%[FS]:%s:%u:%u:%i:%u:%u:%[FS]",
|
||||
specFn, name.c_str(),
|
||||
specFn, name.c_str(),
|
||||
QServer[serverNdx].Info.Players[i].Ping,
|
||||
QServer[serverNdx].Info.Players[i].Time,
|
||||
QServer[serverNdx].Info.Players[i].Frags,
|
||||
|
|
@ -895,7 +891,7 @@ void AGOL_MainWindow::AutoSizeTableColumn(AG_Table *table, int col)
|
|||
if(cell && cell->data.s)
|
||||
{
|
||||
int txtsize;
|
||||
|
||||
|
||||
AG_TextSize(cell->data.s, &txtsize, NULL);
|
||||
|
||||
if(txtsize > maxpx)
|
||||
|
|
@ -1181,7 +1177,7 @@ void AGOL_MainWindow::UpdateServerList(AG_Event *event)
|
|||
}
|
||||
|
||||
GuiConfig::Read("ShowBlockedServers", showBlocked);
|
||||
|
||||
|
||||
for(size_t i = 0; i < serverCount; ++i)
|
||||
{
|
||||
AG_Surface *(*padlockFn)(void*,int,int) = NullSurfFn;
|
||||
|
|
@ -1194,7 +1190,7 @@ void AGOL_MainWindow::UpdateServerList(AG_Event *event)
|
|||
string gametype;
|
||||
size_t wadCnt = 0;
|
||||
int row;
|
||||
|
||||
|
||||
// If we can't immediately get a lock on this server
|
||||
// move on to the next one.
|
||||
if(QServer[i].TryLock())
|
||||
|
|
@ -1341,13 +1337,6 @@ void *AGOL_MainWindow::GetMasterList(void *arg)
|
|||
uint16_t port = 0;
|
||||
unsigned int masterTimeout;
|
||||
|
||||
#ifdef _XBOX
|
||||
// A slight delay is required to complete initialization on Xbox
|
||||
// if this is the "Master On Start" query - 3/4 sec
|
||||
if(StartupQuery)
|
||||
AG_Delay(750);
|
||||
#endif
|
||||
|
||||
if(GuiConfig::Read("MasterTimeout", masterTimeout) || masterTimeout == 0)
|
||||
masterTimeout = 500;
|
||||
|
||||
|
|
@ -1357,15 +1346,11 @@ void *AGOL_MainWindow::GetMasterList(void *arg)
|
|||
MServer.SetSocket(&socket);
|
||||
|
||||
// Get a list of servers
|
||||
#ifdef _XBOX
|
||||
MServer.QueryMasters(masterTimeout, 0, 2); // TODO: Make broadcast and retry configurable
|
||||
#else
|
||||
MServer.QueryMasters(masterTimeout, 1, 2); // TODO: Make broadcast and retry configurable
|
||||
#endif
|
||||
|
||||
serverCount = MServer.GetServerCount();
|
||||
|
||||
// If there are no servers something went wrong
|
||||
// If there are no servers something went wrong
|
||||
// (either with the query or with the Odamex project ;P)
|
||||
if(serverCount == 0)
|
||||
{
|
||||
|
|
@ -1438,10 +1423,6 @@ void *AGOL_MainWindow::QueryAllServers(void *arg)
|
|||
if(serverCount == 0)
|
||||
return NULL;
|
||||
|
||||
#ifdef _XBOX
|
||||
Xbox::EnableJoystickUpdates(false);
|
||||
#endif
|
||||
|
||||
StartServerListPoll();
|
||||
|
||||
ClearList(PlayerList);
|
||||
|
|
@ -1478,12 +1459,6 @@ void *AGOL_MainWindow::QueryAllServers(void *arg)
|
|||
serversQueried++;
|
||||
}
|
||||
}
|
||||
#ifdef _XBOX
|
||||
// This yield is required on Xbox. Without it the Xbox sometimes fails to give the other
|
||||
// threads CPU time and that results in an unacceptably long query and an interface pause
|
||||
// while this thread continuously queries the other threads for completion. -- Hyper_Eye
|
||||
AG_Delay(1); // 1ms yield
|
||||
#endif
|
||||
UpdateQueriedLabelCompleted(static_cast<int>(count));
|
||||
}
|
||||
|
||||
|
|
@ -1498,10 +1473,6 @@ void *AGOL_MainWindow::QueryAllServers(void *arg)
|
|||
UpdatePlayerList(selectedNdx);
|
||||
UpdateServInfoList(selectedNdx);
|
||||
|
||||
#ifdef _XBOX
|
||||
Xbox::EnableJoystickUpdates(true);
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -1524,10 +1495,10 @@ int AGOL_MainWindow::CellCompare(const void *p1, const void *p2)
|
|||
AG_TableCell *c2 = (AG_TableCell*)p2;
|
||||
|
||||
// Make sure the cells are the same type
|
||||
if (c1->type != c2->type || strcmp(c1->fmt, c2->fmt) != 0)
|
||||
if (c1->type != c2->type || strcmp(c1->fmt, c2->fmt) != 0)
|
||||
{
|
||||
// See if one of the cells is null
|
||||
if (c1->type == AG_CELL_NULL || c2->type == AG_CELL_NULL)
|
||||
if (c1->type == AG_CELL_NULL || c2->type == AG_CELL_NULL)
|
||||
{
|
||||
// Sort out the null (unset) cells
|
||||
return (c1->type == AG_CELL_NULL ? 1 : -1);
|
||||
|
|
@ -1576,7 +1547,7 @@ int AGOL_MainWindow::CellCompare(const void *p1, const void *p2)
|
|||
{
|
||||
compval[0] = 1;
|
||||
}
|
||||
|
||||
|
||||
if(c2->fnSu == BulletBlueSurfFn ||
|
||||
c2->fnSu == SpectatorIconSurfFn ||
|
||||
c2->fnSu == PadlockIconSurfFn)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Emacs style mode select -*- C++ -*-
|
||||
// Emacs style mode select -*- C++ -*-
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// $Id$
|
||||
|
|
@ -27,10 +27,6 @@
|
|||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
#ifdef _XBOX
|
||||
#include <xtl.h>
|
||||
#endif
|
||||
|
||||
#include <agar/core.h>
|
||||
#include <agar/gui.h>
|
||||
|
||||
|
|
@ -86,9 +82,7 @@ int GameCommand::Launch()
|
|||
cmd += AG_PATHSEP;
|
||||
|
||||
// Add the bin to the path
|
||||
#ifdef _XBOX
|
||||
cmd += "odamex.xbe";
|
||||
#elif _WIN32
|
||||
#ifdef _WIN32
|
||||
cmd += "odamex.exe";
|
||||
#else
|
||||
cmd += "odamex";
|
||||
|
|
@ -96,7 +90,7 @@ int GameCommand::Launch()
|
|||
|
||||
// The path with bin tacked on is the first arg
|
||||
argv[0] = strdup(cmd.c_str());
|
||||
|
||||
|
||||
// Add each param as an arg
|
||||
for(i = Parameters.begin(); i != Parameters.end(); ++i, ++argc)
|
||||
argv[argc] = strdup((*i).c_str());
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Emacs style mode select -*- C++ -*-
|
||||
// Emacs style mode select -*- C++ -*-
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// $Id$
|
||||
|
|
@ -41,10 +41,6 @@
|
|||
#include "agar_mutex_factory.h"
|
||||
#include "threads/mutex_factory.h"
|
||||
|
||||
#ifdef _XBOX
|
||||
#include "xbox_main.h"
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
using namespace odalpapi;
|
||||
|
||||
|
|
@ -80,20 +76,12 @@ int AGOL_InitVideo(const string& drivers, const int width, const int height, con
|
|||
|
||||
spec << "(width=" << width << ":height=" << height << ":depth=" << depth << ")";
|
||||
|
||||
if (AG_InitGraphics(spec.str().c_str()) == -1)
|
||||
if (AG_InitGraphics(spec.str().c_str()) == -1)
|
||||
{
|
||||
cerr << AG_GetError() << endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef _XBOX
|
||||
// Software cursor only updates at the refresh rate so make it respectable
|
||||
if(agDriverSw)
|
||||
{
|
||||
AG_SetRefreshRate(60);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Pick up GUI subsystem options
|
||||
GuiConfig::Load();
|
||||
|
||||
|
|
@ -117,7 +105,7 @@ int main(int argc, char *argv[])
|
|||
int width, height;
|
||||
|
||||
/* Initialize Agar-Core. */
|
||||
if (AG_InitCore("ag-odalaunch", AG_VERBOSE | AG_CREATE_DATADIR) == -1)
|
||||
if (AG_InitCore("ag-odalaunch", AG_VERBOSE | AG_CREATE_DATADIR) == -1)
|
||||
{
|
||||
cerr << AG_GetError() << endl;
|
||||
return (-1);
|
||||
|
|
@ -126,9 +114,9 @@ int main(int argc, char *argv[])
|
|||
// Initial config load
|
||||
GuiConfig::Load();
|
||||
|
||||
while ((c = AG_Getopt(argc, argv, "?d:f", &optArg, NULL)) != -1)
|
||||
while ((c = AG_Getopt(argc, argv, "?d:f", &optArg, NULL)) != -1)
|
||||
{
|
||||
switch (c)
|
||||
switch (c)
|
||||
{
|
||||
case 'd':
|
||||
drivers = optArg;
|
||||
|
|
@ -170,13 +158,6 @@ int main(int argc, char *argv[])
|
|||
if(!drivers.size())
|
||||
{
|
||||
GuiConfig::Read("VideoDriver", drivers);
|
||||
|
||||
#ifdef _XBOX
|
||||
if(!drivers.size())
|
||||
{
|
||||
drivers = "sdlfb";
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if(AGOL_InitVideo(drivers, width, height, 32))
|
||||
|
|
@ -198,11 +179,6 @@ int main(int argc, char *argv[])
|
|||
AG_BindGlobalKey(AG_KEY_F12, AG_KEYMOD_ANY, AGOL_StartDebugger);
|
||||
#endif
|
||||
|
||||
#ifdef _XBOX
|
||||
// Initialize the Xbox controller
|
||||
Xbox::InitializeJoystick();
|
||||
#endif
|
||||
|
||||
// Event (main) Loop
|
||||
AG_EventLoop();
|
||||
|
||||
|
|
|
|||
|
|
@ -9,24 +9,12 @@ set -x
|
|||
|
||||
# Install packages
|
||||
sudo apt update
|
||||
if [[ -z ${USE_SDL12:-} ]]; then
|
||||
sudo apt install ninja-build libsdl2-dev libsdl2-mixer-dev \
|
||||
libcurl4-openssl-dev libpng-dev libwxgtk3.2-dev deutex
|
||||
else
|
||||
sudo apt install ninja-build libsdl1.2-dev libsdl-mixer1.2-dev \
|
||||
libcurl4-openssl-dev libpng-dev libwxgtk3.2-dev deutex
|
||||
fi
|
||||
sudo apt install ninja-build libsdl2-dev libsdl2-mixer-dev \
|
||||
libcurl4-openssl-dev libpng-dev libwxgtk3.2-dev deutex
|
||||
|
||||
# Generate build
|
||||
mkdir -p build && cd build
|
||||
if [[ -z ${USE_SDL12:-} ]]; then
|
||||
cmake .. -GNinja \
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
|
||||
-DBUILD_OR_FAIL=1 -DBUILD_CLIENT=1 -DBUILD_SERVER=1 \
|
||||
-DBUILD_MASTER=1 -DBUILD_LAUNCHER=1
|
||||
else
|
||||
cmake .. -GNinja \
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo -DUSE_SDL12=1 \
|
||||
-DBUILD_OR_FAIL=1 -DBUILD_CLIENT=1 -DBUILD_SERVER=1 \
|
||||
-DBUILD_MASTER=1 -DBUILD_LAUNCHER=1
|
||||
fi
|
||||
cmake .. -GNinja \
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
|
||||
-DBUILD_OR_FAIL=1 -DBUILD_CLIENT=1 -DBUILD_SERVER=1 \
|
||||
-DBUILD_MASTER=1 -DBUILD_LAUNCHER=1
|
||||
|
|
|
|||
|
|
@ -170,16 +170,16 @@ function ZipDebugX64 {
|
|||
# Copy pdb files into zip. DO NOT THROW THESE AWAY!
|
||||
Copy-Item -Force -Path `
|
||||
"${CurrentDir}\BuildX64\client\RelWithDebInfo\odamex.pdb" `
|
||||
-Destination "${OutputDir}\odamex-x64-${OdamexVersion}.pdb"
|
||||
-Destination "${OutputDir}\odamex-x64-${OdamexVersion}${OdamexTestSuffix}.pdb"
|
||||
Copy-Item -Force -Path `
|
||||
"${CurrentDir}\BuildX64\server\RelWithDebInfo\odasrv.pdb" `
|
||||
-Destination "${OutputDir}\odasrv-x64-${OdamexVersion}.pdb"
|
||||
-Destination "${OutputDir}\odasrv-x64-${OdamexVersion}${OdamexTestSuffix}.pdb"
|
||||
Copy-Item -Force -Path `
|
||||
"${CurrentDir}\BuildX64\odalaunch\RelWithDebInfo\odalaunch.pdb" `
|
||||
-Destination "${OutputDir}\odalaunch-x64-${OdamexVersion}.pdb"
|
||||
-Destination "${OutputDir}\odalaunch-x64-${OdamexVersion}${OdamexTestSuffix}.pdb"
|
||||
|
||||
7z.exe a `
|
||||
"${PdbDir}\odamex-debug-pdb-${OdamexVersion}-x64.zip" `
|
||||
"${PdbDir}\odamex-debug-pdb-${OdamexVersion}${OdamexTestSuffix}-x64.zip" `
|
||||
"${OutputDir}\*.pdb"
|
||||
|
||||
Remove-Item -Force -Path "${OutputDir}\*.pdb"
|
||||
|
|
|
|||
|
|
@ -168,16 +168,16 @@ function ZipDebugX86 {
|
|||
# Copy pdb files into zip. DO NOT THROW THESE AWAY!
|
||||
Copy-Item -Force -Path `
|
||||
"${CurrentDir}\BuildX86\client\RelWithDebInfo\odamex.pdb" `
|
||||
-Destination "${OutputDir}\odamex-x86-${OdamexVersion}.pdb"
|
||||
-Destination "${OutputDir}\odamex-x86-${OdamexVersion}${OdamexTestSuffix}.pdb"
|
||||
Copy-Item -Force -Path `
|
||||
"${CurrentDir}\BuildX86\server\RelWithDebInfo\odasrv.pdb" `
|
||||
-Destination "${OutputDir}\odasrv-x86-${OdamexVersion}.pdb"
|
||||
-Destination "${OutputDir}\odasrv-x86-${OdamexVersion}${OdamexTestSuffix}.pdb"
|
||||
Copy-Item -Force -Path `
|
||||
"${CurrentDir}\BuildX86\odalaunch\RelWithDebInfo\odalaunch.pdb" `
|
||||
-Destination "${OutputDir}\odalaunch-x86-${OdamexVersion}.pdb"
|
||||
-Destination "${OutputDir}\odalaunch-x86-${OdamexVersion}${OdamexTestSuffix}.pdb"
|
||||
|
||||
7z.exe a `
|
||||
"${PdbDir}\odamex-debug-pdb-${OdamexVersion}-x86.zip" `
|
||||
"${PdbDir}\odamex-debug-pdb-${OdamexVersion}${OdamexTestSuffix}-x86.zip" `
|
||||
"${OutputDir}\*.pdb"
|
||||
|
||||
Remove-Item -Force -Path "${OutputDir}\*.pdb"
|
||||
|
|
|
|||
|
|
@ -3,7 +3,10 @@ Set-PSDebug -Trace 1
|
|||
mkdir "build-x32" | Out-Null
|
||||
Set-Location "build-x32"
|
||||
|
||||
& cmake .. `
|
||||
-G "Visual Studio 17 2022" -A Win32 -DBUILD_ODALAUNCH=0 `
|
||||
& cmake .. -G "Visual Studio 17 2022" `
|
||||
-A Win32 `
|
||||
-DBUILD_OR_FAIL=1 `
|
||||
-DBUILD_CLIENT=1 -DBUILD_SERVER=1 `
|
||||
-DBUILD_MASTER=1 -DBUILD_LAUNCHER=1
|
||||
|
||||
Set-Location ..
|
||||
|
|
|
|||
|
|
@ -29,10 +29,6 @@ if (GCONSOLE)
|
|||
file(GLOB CLIENT_HEADERS ${CLIENT_HEADERS} switch/*.h)
|
||||
file(GLOB CLIENT_SOURCES ${CLIENT_SOURCES} switch/*.cpp)
|
||||
odamex_target_settings_nx(CLIENT_DIR GLOB)
|
||||
elseif (VWII)
|
||||
set(CLIENT_DIR ${CLIENT_DIR} vwii) # Nintendo Wii/vWII
|
||||
file(GLOB CLIENT_HEADERS ${CLIENT_HEADERS} vwii/*.h)
|
||||
file(GLOB CLIENT_SOURCES ${CLIENT_SOURCES} vwii/*.cpp)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
|
@ -205,7 +201,7 @@ if(TARGET SDL2::SDL2 OR TARGET SDL::SDL)
|
|||
endif()
|
||||
target_link_libraries(odamex SDL2::mixer)
|
||||
endif()
|
||||
target_link_libraries(odamex ${PNG_LIBRARY} ${ZLIB_LIBRARY} CURL::libcurl)
|
||||
|
||||
if(NOT GCONSOLE)
|
||||
target_include_directories(odamex PRIVATE gui)
|
||||
if(USE_INTERNAL_FLTK)
|
||||
|
|
@ -224,13 +220,11 @@ if(TARGET SDL2::SDL2 OR TARGET SDL::SDL)
|
|||
target_link_libraries(odamex PkgConfig::JSONCPP)
|
||||
endif()
|
||||
|
||||
target_link_libraries(odamex libADLMIDI::ADLMIDI_static)
|
||||
|
||||
if(ENABLE_PORTMIDI)
|
||||
target_link_libraries(odamex ${PORTMIDI_LIBRARY})
|
||||
endif()
|
||||
|
||||
target_link_libraries(odamex ZLIB::ZLIB PNG::PNG fmt::fmt minilzo cpptrace::cpptrace)
|
||||
target_link_libraries(odamex ZLIB::ZLIB PNG::PNG fmt::fmt minilzo cpptrace::cpptrace libADLMIDI::ADLMIDI_static curl_interface)
|
||||
|
||||
if(WIN32)
|
||||
target_link_libraries(odamex winmm wsock32 shlwapi)
|
||||
|
|
@ -238,10 +232,6 @@ if(TARGET SDL2::SDL2 OR TARGET SDL::SDL)
|
|||
target_link_libraries(odamex ${APPLE_FRAMEWORKS})
|
||||
elseif(NSWITCH)
|
||||
target_link_libraries(odamex SDL2 mpg123 modplug vorbisfile vorbis opusfile opus ogg EGL glapi drm_nouveau nx m)
|
||||
elseif(VWII)
|
||||
# Ch0wW : this is UGLY, please fix it ASAP !!
|
||||
target_link_libraries(odamex -L$ENV{DEVKITPRO}/libogc/lib/wii -L$ENV{DEVKITPRO}/portlibs/ppc/lib -L$ENV{DEVKITPRO}/portlibs/wii/lib)
|
||||
target_link_libraries(odamex SDL_mixer SDL smpeg png png16 vorbisidec z fat wiiuse bte ogc ogg m wiikeyboard)
|
||||
elseif(SOLARIS)
|
||||
target_link_libraries(odamex socket nsl)
|
||||
endif()
|
||||
|
|
@ -262,6 +252,7 @@ if(TARGET SDL2::SDL2 OR TARGET SDL::SDL)
|
|||
set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${PROJECT_VERSION}")
|
||||
set(MACOSX_BUNDLE_BUNDLE_VERSION "${PROJECT_VERSION}")
|
||||
set(MACOSX_BUNDLE_ICON_FILE odamex.icns)
|
||||
set(MACOSX_BUNDLE_GUI_IDENTIFIER net.odamex.odamex)
|
||||
|
||||
if(APPLE)
|
||||
add_custom_command(
|
||||
|
|
@ -324,10 +315,6 @@ if(TARGET SDL2::SDL2 OR TARGET SDL::SDL)
|
|||
endif()
|
||||
elseif(NSWITCH)
|
||||
odamex_target_postcompile_nx(odamex)
|
||||
elseif(VWII)
|
||||
message(${CMAKE_BINARY_DIR})
|
||||
add_custom_command( TARGET odamex POST_BUILD
|
||||
COMMAND elf2dol ${CMAKE_BINARY_DIR}/client/odamex ${CMAKE_BINARY_DIR}/boot.dol )
|
||||
elseif(WIN32)
|
||||
install(TARGETS odamex
|
||||
RUNTIME DESTINATION .
|
||||
|
|
|
|||
|
|
@ -569,12 +569,6 @@ class BootWindow : public Fl_Window
|
|||
scannedIWAD_t iwad = m_IWADs[value - 1];
|
||||
g_SelectedWADs.iwad = iwad.path;
|
||||
|
||||
if (iwad.id != NULL && iwad.id->mIdName == "CHEX QUEST")
|
||||
{
|
||||
g_SelectedWADs.options.push_back("-deh");
|
||||
g_SelectedWADs.options.push_back("chex.deh");
|
||||
}
|
||||
|
||||
// PWADs
|
||||
for (const auto& pwad : m_selectedPWADs)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
#include "gui_resource.h"
|
||||
|
||||
#if defined(_WIN32) && !defined(_XBOX)
|
||||
#if defined(_WIN32)
|
||||
|
||||
#include "FL/x.H"
|
||||
#include "win32inc.h"
|
||||
|
|
|
|||
|
|
@ -42,15 +42,11 @@
|
|||
#include "i_system.h"
|
||||
#include "hu_stuff.h"
|
||||
|
||||
#ifdef _XBOX
|
||||
#include "i_xbox.h"
|
||||
#elif __SWITCH__
|
||||
#ifdef __SWITCH__
|
||||
#include "nx_io.h"
|
||||
#endif
|
||||
|
||||
#if defined(SDL12)
|
||||
#include "i_input_sdl12.h"
|
||||
#elif defined(SDL20)
|
||||
#if defined(SDL20)
|
||||
#include "i_input_sdl20.h"
|
||||
#endif
|
||||
|
||||
|
|
@ -594,9 +590,7 @@ bool I_InitInput()
|
|||
|
||||
atterm(I_ShutdownInput);
|
||||
|
||||
#if defined(SDL12)
|
||||
input_subsystem = new ISDL12InputSubsystem();
|
||||
#elif defined(SDL20)
|
||||
#ifdef SDL20
|
||||
input_subsystem = new ISDL20InputSubsystem();
|
||||
#endif
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,188 +0,0 @@
|
|||
// Emacs style mode select -*- C++ -*-
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Copyright (C) 2006-2025 by The Odamex Team.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// DESCRIPTION:
|
||||
//
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "i_sdl.h"
|
||||
#include "i_input.h"
|
||||
|
||||
#include "d_event.h"
|
||||
#include <queue>
|
||||
#include <list>
|
||||
#include "hashtable.h"
|
||||
|
||||
typedef OHashTable<int, int> KeyTranslationTable;
|
||||
|
||||
#ifdef SDL12
|
||||
|
||||
// ============================================================================
|
||||
//
|
||||
// ISDL12KeyboardInputDevice class interface
|
||||
//
|
||||
// ============================================================================
|
||||
|
||||
class ISDL12KeyboardInputDevice : public IKeyboardInputDevice
|
||||
{
|
||||
public:
|
||||
ISDL12KeyboardInputDevice(int id);
|
||||
virtual ~ISDL12KeyboardInputDevice();
|
||||
|
||||
virtual bool active() const;
|
||||
|
||||
virtual void pause();
|
||||
virtual void resume();
|
||||
virtual void reset();
|
||||
|
||||
virtual void gatherEvents();
|
||||
|
||||
virtual bool hasEvent() const
|
||||
{ return !mEvents.empty(); }
|
||||
|
||||
virtual void getEvent(event_t* ev);
|
||||
|
||||
virtual void flushEvents();
|
||||
|
||||
private:
|
||||
int translateKey(SDL_keysym keysym);
|
||||
|
||||
bool mActive;
|
||||
|
||||
typedef std::queue<event_t> EventQueue;
|
||||
EventQueue mEvents;
|
||||
};
|
||||
|
||||
|
||||
// ============================================================================
|
||||
//
|
||||
// ISDL12MouseInputDevice class interface
|
||||
//
|
||||
// ============================================================================
|
||||
|
||||
class ISDL12MouseInputDevice : public IInputDevice
|
||||
{
|
||||
public:
|
||||
ISDL12MouseInputDevice(int id);
|
||||
virtual ~ISDL12MouseInputDevice();
|
||||
|
||||
virtual bool active() const;
|
||||
|
||||
virtual void pause();
|
||||
virtual void resume();
|
||||
virtual void reset();
|
||||
|
||||
virtual void gatherEvents();
|
||||
|
||||
virtual bool hasEvent() const
|
||||
{ return !mEvents.empty(); }
|
||||
|
||||
virtual void getEvent(event_t* ev);
|
||||
|
||||
virtual void flushEvents();
|
||||
|
||||
private:
|
||||
void center();
|
||||
|
||||
bool mActive;
|
||||
|
||||
typedef std::queue<event_t> EventQueue;
|
||||
EventQueue mEvents;
|
||||
};
|
||||
|
||||
|
||||
// ============================================================================
|
||||
//
|
||||
// ISDL12JoystickInputDevice class interface
|
||||
//
|
||||
// ============================================================================
|
||||
|
||||
class ISDL12JoystickInputDevice : public IInputDevice
|
||||
{
|
||||
public:
|
||||
ISDL12JoystickInputDevice(int id);
|
||||
virtual ~ISDL12JoystickInputDevice();
|
||||
|
||||
virtual bool active() const;
|
||||
|
||||
virtual void pause();
|
||||
virtual void resume();
|
||||
virtual void reset();
|
||||
|
||||
virtual void gatherEvents();
|
||||
|
||||
virtual bool hasEvent() const
|
||||
{ return !mEvents.empty(); }
|
||||
|
||||
virtual void getEvent(event_t* ev);
|
||||
|
||||
virtual void flushEvents();
|
||||
|
||||
private:
|
||||
static const int JOY_DEADZONE = 6000;
|
||||
|
||||
bool mActive;
|
||||
|
||||
typedef std::queue<event_t> EventQueue;
|
||||
EventQueue mEvents;
|
||||
|
||||
int mJoystickId;
|
||||
SDL_Joystick* mJoystick;
|
||||
|
||||
int mNumHats;
|
||||
int* mHatStates;
|
||||
};
|
||||
|
||||
|
||||
// ============================================================================
|
||||
//
|
||||
// ISDL12InputSubsystem class interface
|
||||
//
|
||||
// ============================================================================
|
||||
|
||||
class ISDL12InputSubsystem : public IInputSubsystem
|
||||
{
|
||||
public:
|
||||
ISDL12InputSubsystem();
|
||||
virtual ~ISDL12InputSubsystem();
|
||||
|
||||
virtual void grabInput();
|
||||
virtual void releaseInput();
|
||||
|
||||
virtual bool isInputGrabbed() const
|
||||
{ return mInputGrabbed; }
|
||||
|
||||
virtual std::vector<IInputDeviceInfo> getKeyboardDevices() const;
|
||||
virtual void initKeyboard(int id);
|
||||
virtual void shutdownKeyboard(int id);
|
||||
|
||||
virtual std::vector<IInputDeviceInfo> getMouseDevices() const;
|
||||
virtual void initMouse(int id);
|
||||
virtual void shutdownMouse(int id);
|
||||
|
||||
virtual std::vector<IInputDeviceInfo> getJoystickDevices() const;
|
||||
virtual void initJoystick(int id);
|
||||
virtual void shutdownJoystick(int id);
|
||||
|
||||
private:
|
||||
bool mInputGrabbed;
|
||||
};
|
||||
|
||||
#endif // SDL12
|
||||
|
|
@ -433,13 +433,24 @@ void ISDL20MouseInputDevice::resume()
|
|||
{
|
||||
mActive = true;
|
||||
reset();
|
||||
|
||||
// [RV] Always use relative mouse mode and
|
||||
// force unscaled relative motion across supported SDL versions
|
||||
SDL_SetRelativeMouseMode(SDL_TRUE);
|
||||
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 14)
|
||||
SDL_SetHintWithPriority(SDL_HINT_MOUSE_RELATIVE_SCALING, "0", SDL_HINT_OVERRIDE);
|
||||
#endif
|
||||
|
||||
#if SDL_VERSION_ATLEAST(2, 26, 0)
|
||||
SDL_SetHintWithPriority(SDL_HINT_MOUSE_RELATIVE_SYSTEM_SCALE, "0", SDL_HINT_OVERRIDE);
|
||||
#endif
|
||||
|
||||
SDL_EventState(SDL_MOUSEMOTION, SDL_ENABLE);
|
||||
SDL_EventState(SDL_MOUSEBUTTONDOWN, SDL_ENABLE);
|
||||
SDL_EventState(SDL_MOUSEBUTTONUP, SDL_ENABLE);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// ISDL20MouseInputDevice::gatherEvents
|
||||
//
|
||||
|
|
|
|||
|
|
@ -25,17 +25,6 @@
|
|||
|
||||
#include "odamex.h"
|
||||
|
||||
// denis - todo - remove
|
||||
#include "win32inc.h"
|
||||
#ifdef _WIN32
|
||||
#ifndef _XBOX
|
||||
#undef GetMessage
|
||||
typedef bool (WINAPI *SetAffinityFunc)(HANDLE hProcess, DWORD mask);
|
||||
#endif // !_XBOX
|
||||
#else
|
||||
#include <sched.h>
|
||||
#endif // WIN32
|
||||
|
||||
#ifdef UNIX
|
||||
// for getuid and geteuid
|
||||
#include <unistd.h>
|
||||
|
|
@ -64,10 +53,6 @@
|
|||
#include "c_console.h"
|
||||
#include "z_zone.h"
|
||||
|
||||
#ifdef _XBOX
|
||||
#include "i_xbox.h"
|
||||
#endif
|
||||
|
||||
// Use main() on windows for msvc
|
||||
#if defined(_MSC_VER) && !defined(GCONSOLE)
|
||||
# pragma comment(linker, "/subsystem:windows /ENTRY:mainCRTStartup")
|
||||
|
|
@ -171,81 +156,21 @@ int main(int argc, char *argv[])
|
|||
if(argc == 2 && argv && argv[1])
|
||||
{
|
||||
static constexpr std::string_view protocol = "odamex://";
|
||||
const char *uri = argv[1];
|
||||
std::string_view uri = argv[1];
|
||||
|
||||
if(protocol == uri)
|
||||
if(uri.substr(0, protocol.length()) == protocol)
|
||||
{
|
||||
std::string location = uri + protocol.length();
|
||||
std::string_view location = uri.substr(protocol.length());
|
||||
size_t term = location.find_first_of('/');
|
||||
|
||||
if(term == std::string::npos)
|
||||
term = location.length();
|
||||
|
||||
Args.AppendArg("-connect");
|
||||
Args.AppendArg(location.substr(0, term).c_str());
|
||||
Args.AppendArg(std::string(location.substr(0, term)).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(SDL12)
|
||||
// [Russell] - No more double-tapping of capslock to enable autorun
|
||||
SDL_putenv((char*)"SDL_DISABLE_LOCK_KEYS=1");
|
||||
|
||||
// Set SDL video centering
|
||||
SDL_putenv((char*)"SDL_VIDEO_WINDOW_POS=center");
|
||||
SDL_putenv((char*)"SDL_VIDEO_CENTERED=1");
|
||||
#endif
|
||||
|
||||
#if defined _WIN32 && !defined _XBOX
|
||||
|
||||
#if defined(SDL12)
|
||||
// From the SDL 1.2.10 release notes:
|
||||
//
|
||||
// > The "windib" video driver is the default now, to prevent
|
||||
// > problems with certain laptops, 64-bit Windows, and Windows
|
||||
// > Vista.
|
||||
//
|
||||
// The hell with that.
|
||||
|
||||
// SoM: the gdi interface is much faster for windowed modes which are more
|
||||
// commonly used. Thus, GDI is default.
|
||||
//
|
||||
// GDI mouse issues fill many users with great sadness. We are going back
|
||||
// to directx as defulat for now and the people will rejoice. --Hyper_Eye
|
||||
if (Args.CheckParm ("-gdi"))
|
||||
putenv((char*)"SDL_VIDEODRIVER=windib");
|
||||
else
|
||||
putenv((char*)"SDL_VIDEODRIVER=directx");
|
||||
#endif // SDL12
|
||||
|
||||
|
||||
// Set the process affinity mask to 1 on Windows, so that all threads
|
||||
// run on the same processor. This is a workaround for a bug in
|
||||
// SDL_mixer that causes occasional crashes. Thanks to entryway and fraggle for this.
|
||||
//
|
||||
// [ML] 8/6/10: Updated to match prboom+'s I_SetAffinityMask. We don't do everything
|
||||
// you might find in there but we do enough for now.
|
||||
HMODULE kernel32_dll = LoadLibrary("kernel32.dll");
|
||||
|
||||
if (kernel32_dll)
|
||||
{
|
||||
SetAffinityFunc SetAffinity = (SetAffinityFunc)GetProcAddress(kernel32_dll, "SetProcessAffinityMask");
|
||||
|
||||
if (SetAffinity)
|
||||
{
|
||||
if (!SetAffinity(GetCurrentProcess(), 1))
|
||||
LOG << "Failed to set process affinity mask: " << GetLastError() << std::endl;
|
||||
}
|
||||
}
|
||||
#endif // _WIN32 && !_XBOX
|
||||
|
||||
#ifdef X11
|
||||
#if defined(SDL12)
|
||||
// [SL] 2011-12-21 - Ensure we're getting raw DGA mouse input from X11,
|
||||
// bypassing X11's mouse acceleration
|
||||
putenv((char*)"SDL_VIDEO_X11_DGAMOUSE=1");
|
||||
#endif // SDL12
|
||||
#endif // X11
|
||||
|
||||
unsigned int sdl_flags = SDL_INIT_TIMER;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
|
|
|||
|
|
@ -387,7 +387,7 @@ static std::list<MidiEvent*> *I_ReadMidiTrack(MEMFILE *mf)
|
|||
|
||||
if (chunkheader.chunk_id != cTrackChunkId)
|
||||
{
|
||||
Printf(PRINT_WARNING, "I_ReadMidiTrack: Unexpected chunk header ID\n");
|
||||
PrintFmt(PRINT_WARNING, "I_ReadMidiTrack: Unexpected chunk header ID\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -400,7 +400,7 @@ static std::list<MidiEvent*> *I_ReadMidiTrack(MEMFILE *mf)
|
|||
|
||||
if (!newevent)
|
||||
{
|
||||
Printf(PRINT_WARNING, "I_ReadMidiTrack: Unable to read MIDI event\n");
|
||||
PrintFmt(PRINT_WARNING, "I_ReadMidiTrack: Unable to read MIDI event\n");
|
||||
|
||||
I_ClearMidiEventList(eventlist);
|
||||
delete eventlist;
|
||||
|
|
@ -484,7 +484,7 @@ void MidiSong::_ParseSong(MEMFILE *mf)
|
|||
|
||||
if (chunkheader.chunk_id != cHeaderChunkId)
|
||||
{
|
||||
Printf(PRINT_WARNING, "MidiSong::_ParseSong: Unexpected file header ID\n");
|
||||
PrintFmt(PRINT_WARNING, "MidiSong::_ParseSong: Unexpected file header ID\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -499,7 +499,7 @@ void MidiSong::_ParseSong(MEMFILE *mf)
|
|||
|
||||
if (fileheader.format_type != 0 && fileheader.format_type != 1)
|
||||
{
|
||||
Printf(PRINT_WARNING, "MidiSong::_ParseSong: Only type 0 or type 1 MIDI files are supported.\n");
|
||||
PrintFmt(PRINT_WARNING, "MidiSong::_ParseSong: Only type 0 or type 1 MIDI files are supported.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -509,7 +509,7 @@ void MidiSong::_ParseSong(MEMFILE *mf)
|
|||
std::list<MidiEvent*> *eventlist = I_ReadMidiTrack(mf);
|
||||
if (!eventlist)
|
||||
{
|
||||
Printf(PRINT_WARNING, "MidiSong::_ParseSong: Error reading track %lu.\n", i + 1);
|
||||
PrintFmt(PRINT_WARNING, "MidiSong::_ParseSong: Error reading track {}.\n", i + 1);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Emacs style mode select -*- C++ -*-
|
||||
// Emacs style mode select -*- C++ -*-
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// $Id$
|
||||
|
|
@ -26,18 +26,6 @@
|
|||
#include <list>
|
||||
#include "m_memio.h"
|
||||
|
||||
static byte gm_system_on[] = {
|
||||
0xF0, 0x7E, 0x7F, 0x09, 0x01, 0xF7
|
||||
};
|
||||
|
||||
static byte gs_reset[] = {
|
||||
0xF0, 0x41, 0x10, 0x42, 0x12, 0x40, 0x00, 0x7F, 0x00, 0x41, 0xF7
|
||||
};
|
||||
|
||||
static byte xg_system_on[] = {
|
||||
0xF0, 0x43, 0x10, 0x4C, 0x00, 0x00, 0x7E, 0x00, 0xF7
|
||||
};
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MIDI_RESET_NONE,
|
||||
|
|
@ -130,16 +118,16 @@ public:
|
|||
MidiEvent(unsigned int time, midi_event_type_t type) :
|
||||
mTime(time), mType(type)
|
||||
{ }
|
||||
|
||||
|
||||
MidiEvent(const MidiEvent &other) :
|
||||
mTime(other.mTime), mType(other.mType)
|
||||
{ }
|
||||
|
||||
|
||||
virtual ~MidiEvent() { }
|
||||
|
||||
unsigned int getMidiClockTime() const { return mTime; }
|
||||
virtual midi_event_type_t getEventType() const { return mType; }
|
||||
|
||||
|
||||
private:
|
||||
unsigned int mTime;
|
||||
midi_event_type_t mType;
|
||||
|
|
@ -158,13 +146,13 @@ public:
|
|||
memcpy(mData, data, mLength);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
virtual ~MidiMetaEvent()
|
||||
{
|
||||
if (mData)
|
||||
delete mData;
|
||||
}
|
||||
|
||||
|
||||
virtual size_t getDataLength() const { return mLength; }
|
||||
virtual const byte* getData() const { return mData; }
|
||||
virtual midi_meta_event_type_t getMetaType() const { return mMetaType; }
|
||||
|
|
@ -188,13 +176,13 @@ public:
|
|||
memcpy(mData, data, mLength);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
virtual ~MidiSysexEvent()
|
||||
{
|
||||
if (mData)
|
||||
delete mData;
|
||||
}
|
||||
|
||||
|
||||
virtual size_t getDataLength() const { return mLength; }
|
||||
virtual const byte* getData() const { return mData; }
|
||||
|
||||
|
|
@ -211,13 +199,13 @@ public:
|
|||
byte param1, byte param2 = 0) :
|
||||
MidiEvent(time, type), mChannel(channel), mParam1(param1), mParam2(param2)
|
||||
{ }
|
||||
|
||||
|
||||
virtual ~MidiChannelEvent() {}
|
||||
|
||||
|
||||
byte getChannel() const { return mChannel; }
|
||||
byte getParam1() const { return mParam1; }
|
||||
byte getParam2() const { return mParam2; }
|
||||
|
||||
|
||||
private:
|
||||
byte mChannel;
|
||||
byte mParam1;
|
||||
|
|
@ -233,11 +221,11 @@ public:
|
|||
MidiChannelEvent(time, MIDI_EVENT_CONTROLLER, channel, param1, 0),
|
||||
mControllerType(controllertype)
|
||||
{ }
|
||||
|
||||
|
||||
virtual ~MidiControllerEvent() {}
|
||||
|
||||
|
||||
midi_controller_t getControllerType() const { return mControllerType; }
|
||||
|
||||
|
||||
private:
|
||||
midi_controller_t mControllerType;
|
||||
};
|
||||
|
|
@ -248,12 +236,12 @@ class MidiSong
|
|||
public:
|
||||
MidiSong(byte* data, size_t length);
|
||||
~MidiSong();
|
||||
|
||||
|
||||
unsigned short getTimeDivision() { return mTimeDivision; }
|
||||
|
||||
|
||||
typedef std::list<MidiEvent*>::iterator iterator;
|
||||
typedef std::list<MidiEvent*>::const_iterator const_iterator;
|
||||
|
||||
|
||||
// Allow iteration through a song's events
|
||||
iterator begin() { return mEvents.begin(); }
|
||||
const_iterator begin() const { return mEvents.begin(); }
|
||||
|
|
@ -263,7 +251,7 @@ public:
|
|||
private:
|
||||
std::list<MidiEvent*> mEvents;
|
||||
unsigned short mTimeDivision;
|
||||
|
||||
|
||||
void _ParseSong(MEMFILE *mf);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
#include "odamex.h"
|
||||
|
||||
#include "win32inc.h"
|
||||
#if defined(_WIN32) && !defined(_XBOX)
|
||||
#if defined(_WIN32)
|
||||
#include <mmsystem.h>
|
||||
#endif
|
||||
|
||||
|
|
@ -46,7 +46,7 @@ MusicSystem* musicsystem = NULL;
|
|||
MusicSystemType current_musicsystem_type = MS_NONE;
|
||||
|
||||
void S_StopMusic();
|
||||
void S_ChangeMusic (std::string musicname, bool looping);
|
||||
void S_ChangeMusic (std::string musicname, bool looping, int order = 0);
|
||||
|
||||
EXTERN_CVAR (snd_musicvolume)
|
||||
EXTERN_CVAR (snd_musicsystem)
|
||||
|
|
@ -142,7 +142,7 @@ bool S_MusicIsWave(byte* data, size_t length)
|
|||
//
|
||||
void I_ResetMidiVolume()
|
||||
{
|
||||
#if defined(_WIN32) && !defined(_XBOX)
|
||||
#if defined(_WIN32)
|
||||
SDL_LockAudio();
|
||||
|
||||
for (UINT device = MIDI_MAPPER; device != midiOutGetNumDevs(); device++)
|
||||
|
|
@ -288,7 +288,7 @@ static MusicSystemType I_SelectMusicSystem(byte *data, size_t length)
|
|||
return MS_SDLMIXER;
|
||||
}
|
||||
|
||||
void I_PlaySong(const OByteSpan data, const bool loop)
|
||||
void I_PlaySong(const OByteSpan data, const bool loop, const int order)
|
||||
{
|
||||
if (!musicsystem)
|
||||
return;
|
||||
|
|
@ -304,7 +304,7 @@ void I_PlaySong(const OByteSpan data, const bool loop)
|
|||
I_InitMusic(newtype);
|
||||
}
|
||||
|
||||
musicsystem->startSong(data.data(), data.size(), loop);
|
||||
musicsystem->startSong(data.data(), data.size(), loop, order);
|
||||
|
||||
// Hack for problems with Windows Vista/7 & SDL_Mixer
|
||||
// See comment for I_ResetMidiVolume().
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Emacs style mode select -*- C++ -*-
|
||||
// Emacs style mode select -*- C++ -*-
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// $Id$
|
||||
|
|
@ -68,7 +68,7 @@ void I_ResumeSong();
|
|||
// plays a song, and when the song is done,
|
||||
// starts playing it again in an endless loop.
|
||||
// Horrible thing to do, considering.
|
||||
void I_PlaySong(const OByteSpan data, const bool loop);
|
||||
void I_PlaySong(const OByteSpan data, const bool loop, const int order);
|
||||
// Stops a song over 3 seconds.
|
||||
void I_StopSong();
|
||||
void I_UpdateMusic();
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ static double I_CalculateMsPerMidiClock(int timeDivision, double tempo = 120.0)
|
|||
//
|
||||
// ============================================================================
|
||||
|
||||
void MusicSystem::startSong(byte* data, size_t length, bool loop)
|
||||
void MusicSystem::startSong(byte* data, size_t length, bool loop, int order)
|
||||
{
|
||||
m_isPlaying = true;
|
||||
m_isPaused = false;
|
||||
|
|
@ -139,15 +139,15 @@ static MidiSong* I_RegisterMidiSong(byte* data, size_t length)
|
|||
}
|
||||
else
|
||||
{
|
||||
Printf(PRINT_WARNING, "I_RegisterMidiSong: MUS is not valid\n");
|
||||
PrintFmt(PRINT_WARNING, "I_RegisterMidiSong: MUS is not valid\n");
|
||||
regdata = NULL;
|
||||
reglength = 0;
|
||||
}
|
||||
}
|
||||
else if (!S_MusicIsMidi(data, length))
|
||||
{
|
||||
Printf(PRINT_WARNING, "I_RegisterMidiSong: Only midi music formats are supported "
|
||||
"with the selected music system.\n");
|
||||
PrintFmt(PRINT_WARNING, "I_RegisterMidiSong: Only midi music formats are supported "
|
||||
"with the selected music system.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -214,7 +214,7 @@ void MidiMusicSystem::_DisableFallback()
|
|||
m_useFallback = false;
|
||||
}
|
||||
|
||||
void MidiMusicSystem::startSong(byte* data, size_t length, bool loop)
|
||||
void MidiMusicSystem::startSong(byte* data, size_t length, bool loop, int order)
|
||||
{
|
||||
if (!isInitialized())
|
||||
return;
|
||||
|
|
@ -239,7 +239,7 @@ void MidiMusicSystem::startSong(byte* data, size_t length, bool loop)
|
|||
m_prevClockTime = 0;
|
||||
m_lastEventTime = I_MSTime();
|
||||
|
||||
MusicSystem::startSong(data, length, loop);
|
||||
MusicSystem::startSong(data, length, loop, order);
|
||||
}
|
||||
|
||||
void MidiMusicSystem::stopSong()
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ class MusicSystem
|
|||
MusicSystem() { }
|
||||
virtual ~MusicSystem() { }
|
||||
|
||||
virtual void startSong(byte* data, size_t length, bool loop);
|
||||
virtual void startSong(byte* data, size_t length, bool loop, int order);
|
||||
virtual void stopSong();
|
||||
virtual void pauseSong();
|
||||
virtual void resumeSong();
|
||||
|
|
@ -74,10 +74,10 @@ class SilentMusicSystem : public MusicSystem
|
|||
public:
|
||||
SilentMusicSystem()
|
||||
{
|
||||
Printf(PRINT_WARNING, "I_InitMusic: Music playback disabled.\n");
|
||||
PrintFmt(PRINT_WARNING, "I_InitMusic: Music playback disabled.\n");
|
||||
}
|
||||
|
||||
void startSong(byte* data, size_t length, bool loop) override { }
|
||||
void startSong(byte* data, size_t length, bool loop, int order) override { }
|
||||
void stopSong() override { }
|
||||
void pauseSong() override { }
|
||||
void resumeSong() override { }
|
||||
|
|
@ -109,7 +109,7 @@ class MidiMusicSystem : public MusicSystem
|
|||
MidiMusicSystem();
|
||||
~MidiMusicSystem() override;
|
||||
|
||||
void startSong(byte* data, size_t length, bool loop) override;
|
||||
void startSong(byte* data, size_t length, bool loop, int order) override;
|
||||
void stopSong() override;
|
||||
void pauseSong() override;
|
||||
void resumeSong() override;
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ AdlMidiMusicSystem::AdlMidiMusicSystem() : m_mutex()
|
|||
return;
|
||||
}
|
||||
else
|
||||
PrintFmt("I_InitMusic: Music playback enabled using libADLMIDI.\n");
|
||||
PrintFmt(PRINT_FILTERHIGH, "I_InitMusic: Music playback enabled using libADLMIDI.\n");
|
||||
|
||||
m_isInitialized = true;
|
||||
|
||||
|
|
@ -127,7 +127,7 @@ static void adlmidi_music_hook (void *data, byte *stream, int len)
|
|||
}
|
||||
|
||||
|
||||
void AdlMidiMusicSystem::startSong(byte* data, size_t length, bool loop)
|
||||
void AdlMidiMusicSystem::startSong(byte* data, size_t length, bool loop, int order)
|
||||
{
|
||||
if (!isInitialized())
|
||||
return;
|
||||
|
|
@ -145,7 +145,7 @@ void AdlMidiMusicSystem::startSong(byte* data, size_t length, bool loop)
|
|||
adl_setLoopEnabled(m_midiPlayer, loop);
|
||||
_UpdateMidiHook();
|
||||
|
||||
MusicSystem::startSong(data, length, loop);
|
||||
MusicSystem::startSong(data, length, loop, order);
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ class AdlMidiMusicSystem : public MusicSystem
|
|||
AdlMidiMusicSystem();
|
||||
~AdlMidiMusicSystem() override;
|
||||
|
||||
void startSong(byte* data, size_t length, bool loop) override;
|
||||
void startSong(byte* data, size_t length, bool loop, int order) override;
|
||||
void stopSong() override;
|
||||
void pauseSong() override;
|
||||
void resumeSong() override;
|
||||
|
|
|
|||
|
|
@ -95,19 +95,19 @@ AuMusicSystem::AuMusicSystem() : m_isInitialized(false)
|
|||
|
||||
if (AUGraphConnectNodeInput(m_graph, m_synth, 0, m_output, 0) != noErr)
|
||||
{
|
||||
Printf(PRINT_HIGH, "I_InitMusic: AUGraphConnectNodeInput failed\n");
|
||||
PrintFmt(PRINT_HIGH, "I_InitMusic: AUGraphConnectNodeInput failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (AUGraphOpen(m_graph) != noErr)
|
||||
{
|
||||
Printf(PRINT_HIGH, "I_InitMusic: AUGraphOpen failed\n");
|
||||
PrintFmt(PRINT_HIGH, "I_InitMusic: AUGraphOpen failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (AUGraphInitialize(m_graph) != noErr)
|
||||
{
|
||||
Printf(PRINT_HIGH, "I_InitMusic: AUGraphInitialize failed\n");
|
||||
PrintFmt(PRINT_HIGH, "I_InitMusic: AUGraphInitialize failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -118,18 +118,18 @@ AuMusicSystem::AuMusicSystem() : m_isInitialized(false)
|
|||
if (AUGraphNodeInfo(m_graph, m_output, NULL, &m_unit) != noErr)
|
||||
#endif
|
||||
{
|
||||
Printf(PRINT_HIGH, "I_InitMusic: AUGraphGetNodeInfo failed\n");
|
||||
PrintFmt(PRINT_HIGH, "I_InitMusic: AUGraphGetNodeInfo failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (NewMusicPlayer(&m_player) != noErr)
|
||||
{
|
||||
Printf(PRINT_HIGH,
|
||||
PrintFmt(PRINT_HIGH,
|
||||
"I_InitMusic: Music player creation failed using AudioToolbox\n");
|
||||
return;
|
||||
}
|
||||
|
||||
Printf(PRINT_HIGH, "I_InitMusic: Music playback enabled using AudioToolbox\n");
|
||||
PrintFmt(PRINT_FILTERHIGH, "I_InitMusic: Music playback enabled using AudioToolbox\n");
|
||||
m_isInitialized = true;
|
||||
return;
|
||||
}
|
||||
|
|
@ -143,7 +143,7 @@ AuMusicSystem::~AuMusicSystem()
|
|||
AUGraphClose(m_graph);
|
||||
}
|
||||
|
||||
void AuMusicSystem::startSong(byte* data, size_t length, bool loop)
|
||||
void AuMusicSystem::startSong(byte* data, size_t length, bool loop, int order)
|
||||
{
|
||||
if (!isInitialized())
|
||||
return;
|
||||
|
|
@ -157,26 +157,26 @@ void AuMusicSystem::startSong(byte* data, size_t length, bool loop)
|
|||
|
||||
if (MusicSequenceSetAUGraph(m_sequence, m_graph) != noErr)
|
||||
{
|
||||
Printf(PRINT_HIGH, "I_PlaySong: MusicSequenceSetAUGraph failed\n");
|
||||
PrintFmt(PRINT_HIGH, "I_PlaySong: MusicSequenceSetAUGraph failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (MusicPlayerSetSequence(m_player, m_sequence) != noErr)
|
||||
{
|
||||
Printf(PRINT_HIGH, "I_PlaySong: MusicPlayerSetSequence failed\n");
|
||||
PrintFmt(PRINT_HIGH, "I_PlaySong: MusicPlayerSetSequence failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (MusicPlayerPreroll(m_player) != noErr)
|
||||
{
|
||||
Printf(PRINT_HIGH, "I_PlaySong: MusicPlayerPreroll failed\n");
|
||||
PrintFmt(PRINT_HIGH, "I_PlaySong: MusicPlayerPreroll failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
UInt32 outNumberOfTracks = 0;
|
||||
if (MusicSequenceGetTrackCount(m_sequence, &outNumberOfTracks) != noErr)
|
||||
{
|
||||
Printf(PRINT_HIGH, "I_PlaySong: MusicSequenceGetTrackCount failed\n");
|
||||
PrintFmt(PRINT_HIGH, "I_PlaySong: MusicSequenceGetTrackCount failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -189,14 +189,14 @@ void AuMusicSystem::startSong(byte* data, size_t length, bool loop)
|
|||
|
||||
if (MusicSequenceGetIndTrack(m_sequence, i, &track) != noErr)
|
||||
{
|
||||
Printf(PRINT_HIGH, "I_PlaySong: MusicSequenceGetIndTrack failed\n");
|
||||
PrintFmt(PRINT_HIGH, "I_PlaySong: MusicSequenceGetIndTrack failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (MusicTrackGetProperty(track, kSequenceTrackProperty_TrackLength, &time,
|
||||
&size) != noErr)
|
||||
{
|
||||
Printf(PRINT_HIGH, "I_PlaySong: MusicTrackGetProperty failed\n");
|
||||
PrintFmt(PRINT_HIGH, "I_PlaySong: MusicTrackGetProperty failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -220,7 +220,7 @@ void AuMusicSystem::startSong(byte* data, size_t length, bool loop)
|
|||
|
||||
if (MusicSequenceGetIndTrack(m_sequence, i, &track) != noErr)
|
||||
{
|
||||
Printf(PRINT_HIGH, "I_PlaySong: MusicSequenceGetIndTrack failed\n");
|
||||
PrintFmt(PRINT_HIGH, "I_PlaySong: MusicSequenceGetIndTrack failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -230,18 +230,18 @@ void AuMusicSystem::startSong(byte* data, size_t length, bool loop)
|
|||
if (MusicTrackSetProperty(track, kSequenceTrackProperty_LoopInfo, &LoopInfo,
|
||||
sizeof(LoopInfo)) != noErr)
|
||||
{
|
||||
Printf(PRINT_HIGH, "I_PlaySong: MusicTrackSetProperty failed\n");
|
||||
PrintFmt(PRINT_HIGH, "I_PlaySong: MusicTrackSetProperty failed\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (MusicPlayerStart(m_player) != noErr)
|
||||
{
|
||||
Printf(PRINT_HIGH, "I_PlaySong: MusicPlayerStart failed\n");
|
||||
PrintFmt(PRINT_HIGH, "I_PlaySong: MusicPlayerStart failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
MusicSystem::startSong(data, length, loop);
|
||||
MusicSystem::startSong(data, length, loop, order);
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -294,7 +294,7 @@ void AuMusicSystem::setVolume(float volume)
|
|||
if (AudioUnitSetParameter(m_unit, kAudioUnitParameterUnit_LinearGain,
|
||||
kAudioUnitScope_Output, 0, getVolume(), 0) != noErr)
|
||||
{
|
||||
Printf(PRINT_HIGH, "I_InitMusic: AudioUnitSetParameter failed\n");
|
||||
PrintFmt(PRINT_HIGH, "I_InitMusic: AudioUnitSetParameter failed\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -337,20 +337,20 @@ void AuMusicSystem::_RegisterSong(byte* data, size_t length)
|
|||
}
|
||||
else
|
||||
{
|
||||
Printf(PRINT_HIGH, "MUS is not valid\n");
|
||||
PrintFmt(PRINT_HIGH, "MUS is not valid\n");
|
||||
regdata = NULL;
|
||||
reglength = 0;
|
||||
}
|
||||
}
|
||||
else if (!S_MusicIsMidi(data, length))
|
||||
{
|
||||
Printf(PRINT_HIGH, "I_PlaySong: AudioUnit does not support this music format\n");
|
||||
PrintFmt(PRINT_HIGH, "I_PlaySong: AudioUnit does not support this music format\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (NewMusicSequence(&m_sequence) != noErr)
|
||||
{
|
||||
Printf(PRINT_HIGH, "I_PlaySong: Unable to create AudioUnit sequence\n");
|
||||
PrintFmt(PRINT_HIGH, "I_PlaySong: Unable to create AudioUnit sequence\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ class AuMusicSystem : public MusicSystem
|
|||
AuMusicSystem();
|
||||
~AuMusicSystem() override;
|
||||
|
||||
void startSong(byte* data, size_t length, bool loop) override;
|
||||
void startSong(byte* data, size_t length, bool loop, int order) override;
|
||||
void stopSong() override;
|
||||
void pauseSong() override;
|
||||
void resumeSong() override;
|
||||
|
|
|
|||
|
|
@ -42,6 +42,18 @@ EXTERN_CVAR(snd_midisysex)
|
|||
// Partially based on an implementation from prboom-plus by Nicholai Main (Natt).
|
||||
// ============================================================================
|
||||
|
||||
static byte gm_system_on[] = {
|
||||
0xF0, 0x7E, 0x7F, 0x09, 0x01, 0xF7
|
||||
};
|
||||
|
||||
static byte gs_reset[] = {
|
||||
0xF0, 0x41, 0x10, 0x42, 0x12, 0x40, 0x00, 0x7F, 0x00, 0x41, 0xF7
|
||||
};
|
||||
|
||||
static byte xg_system_on[] = {
|
||||
0xF0, 0x43, 0x10, 0x4C, 0x00, 0x00, 0x7E, 0x00, 0xF7
|
||||
};
|
||||
|
||||
//
|
||||
// I_PortMidiTime()
|
||||
//
|
||||
|
|
@ -62,7 +74,7 @@ PortMidiMusicSystem::PortMidiMusicSystem()
|
|||
|
||||
if (Pm_Initialize() != pmNoError)
|
||||
{
|
||||
Printf(PRINT_WARNING, "I_InitMusic: PortMidi initialization failed.\n");
|
||||
PrintFmt(PRINT_WARNING, "I_InitMusic: PortMidi initialization failed.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -80,12 +92,12 @@ PortMidiMusicSystem::PortMidiMusicSystem()
|
|||
if (!prefdevicename.empty() && iequals(prefdevicename, curdevicename))
|
||||
m_outputDevice = i;
|
||||
|
||||
Printf(PRINT_HIGH, "%d: %s, %s\n", i, info->interf, info->name);
|
||||
PrintFmt(PRINT_FILTERHIGH, "{}: {}, {}\n", i, info->interf, info->name);
|
||||
}
|
||||
|
||||
if (m_outputDevice == pmNoDevice)
|
||||
{
|
||||
Printf(PRINT_WARNING, "I_InitMusic: No PortMidi output devices available.\n");
|
||||
PrintFmt(PRINT_WARNING, "I_InitMusic: No PortMidi output devices available.\n");
|
||||
Pm_Terminate();
|
||||
return;
|
||||
}
|
||||
|
|
@ -93,8 +105,8 @@ PortMidiMusicSystem::PortMidiMusicSystem()
|
|||
if (Pm_OpenOutput(&m_stream, m_outputDevice, NULL, output_buffer_size, I_PortMidiTime,
|
||||
NULL, cLatency) != pmNoError)
|
||||
{
|
||||
Printf(PRINT_WARNING, "I_InitMusic: Failure opening PortMidi output device %d.\n",
|
||||
m_outputDevice);
|
||||
PrintFmt(PRINT_WARNING, "I_InitMusic: Failure opening PortMidi output device {}.\n",
|
||||
m_outputDevice);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -112,7 +124,7 @@ PortMidiMusicSystem::PortMidiMusicSystem()
|
|||
// Initialize instrument fallback support
|
||||
_InitFallback();
|
||||
|
||||
Printf(PRINT_HIGH, "I_InitMusic: Music playback enabled using PortMidi.\n");
|
||||
PrintFmt(PRINT_FILTERHIGH, "I_InitMusic: Music playback enabled using PortMidi.\n");
|
||||
m_isInitialized = true;
|
||||
}
|
||||
|
||||
|
|
@ -303,11 +315,11 @@ void PortMidiMusicSystem::_ResetDevice(bool playing)
|
|||
m_useResetDelay = (snd_mididelay > 0);
|
||||
}
|
||||
|
||||
void PortMidiMusicSystem::startSong(byte *data, size_t length, bool loop)
|
||||
void PortMidiMusicSystem::startSong(byte *data, size_t length, bool loop, int order)
|
||||
{
|
||||
m_isPlaying = false;
|
||||
_ResetDevice(true);
|
||||
MidiMusicSystem::startSong(data, length, loop);
|
||||
MidiMusicSystem::startSong(data, length, loop, order);
|
||||
m_isPlaying = true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ class PortMidiMusicSystem : public MidiMusicSystem
|
|||
PortMidiMusicSystem();
|
||||
~PortMidiMusicSystem() override;
|
||||
|
||||
void startSong(byte *data, size_t length, bool loop) override;
|
||||
void startSong(byte *data, size_t length, bool loop, int order) override;
|
||||
void stopSong() override;
|
||||
void pauseSong() override;
|
||||
void restartSong() override;
|
||||
|
|
|
|||
|
|
@ -31,21 +31,11 @@
|
|||
#include "i_music.h"
|
||||
#include "mus2midi.h"
|
||||
|
||||
// [Russell] - define a temporary midi file, for consistency
|
||||
// SDL < 1.2.7
|
||||
#ifdef _XBOX
|
||||
// Use the cache partition
|
||||
#define TEMP_MIDI "Z:\\temp_music"
|
||||
#elif MIX_MAJOR_VERSION < 1 || (MIX_MAJOR_VERSION == 1 && MIX_MINOR_VERSION < 2) || \
|
||||
(MIX_MAJOR_VERSION == 1 && MIX_MINOR_VERSION == 2 && MIX_PATCHLEVEL < 7)
|
||||
#define TEMP_MIDI "temp_music"
|
||||
#endif
|
||||
|
||||
EXTERN_CVAR(snd_musicvolume)
|
||||
|
||||
SdlMixerMusicSystem::SdlMixerMusicSystem() : m_isInitialized(false), m_registeredSong()
|
||||
{
|
||||
Printf("I_InitMusic: Music playback enabled using SDL_Mixer.\n");
|
||||
PrintFmt(PRINT_FILTERHIGH, "I_InitMusic: Music playback enabled using SDL_Mixer.\n");
|
||||
m_isInitialized = true;
|
||||
}
|
||||
|
||||
|
|
@ -60,7 +50,7 @@ SdlMixerMusicSystem::~SdlMixerMusicSystem()
|
|||
m_isInitialized = false;
|
||||
}
|
||||
|
||||
void SdlMixerMusicSystem::startSong(byte* data, size_t length, bool loop)
|
||||
void SdlMixerMusicSystem::startSong(byte* data, size_t length, bool loop, int order)
|
||||
{
|
||||
if (!isInitialized())
|
||||
return;
|
||||
|
|
@ -77,13 +67,17 @@ void SdlMixerMusicSystem::startSong(byte* data, size_t length, bool loop)
|
|||
|
||||
if (Mix_PlayMusic(m_registeredSong.Track, loop ? -1 : 1) == -1)
|
||||
{
|
||||
Printf(PRINT_WARNING, "Mix_PlayMusic: %s\n", Mix_GetError());
|
||||
PrintFmt(PRINT_WARNING, "Mix_PlayMusic: {}\n", Mix_GetError());
|
||||
return;
|
||||
}
|
||||
|
||||
#if (SDL_MIXER_MAJOR_VERSION == 2 && SDL_MIXER_MINOR_VERSION >= 6)
|
||||
Mix_ModMusicJumpToOrder(order); // for musinfo
|
||||
#endif
|
||||
|
||||
Mix_HookMusicFinished(I_ResetMidiVolume);
|
||||
|
||||
MusicSystem::startSong(data, length, loop);
|
||||
MusicSystem::startSong(data, length, loop, order);
|
||||
|
||||
// [Russell] - Hack for setting the volume on windows vista, since it gets
|
||||
// reset on every music change
|
||||
|
|
@ -98,7 +92,7 @@ void SdlMixerMusicSystem::startSong(byte* data, size_t length, bool loop)
|
|||
//
|
||||
void SdlMixerMusicSystem::_StopSong()
|
||||
{
|
||||
if (!isInitialized() || !isPlaying())
|
||||
if (!isInitialized())
|
||||
return;
|
||||
|
||||
if (isPaused())
|
||||
|
|
@ -197,7 +191,7 @@ void SdlMixerMusicSystem::_RegisterSong(byte* data, size_t length)
|
|||
}
|
||||
else
|
||||
{
|
||||
Printf(PRINT_WARNING, "MUS is not valid\n");
|
||||
PrintFmt(PRINT_WARNING, "MUS is not valid\n");
|
||||
}
|
||||
|
||||
mem_fclose(mus);
|
||||
|
|
@ -209,62 +203,15 @@ void SdlMixerMusicSystem::_RegisterSong(byte* data, size_t length)
|
|||
|
||||
if (!m_registeredSong.Data)
|
||||
{
|
||||
Printf(PRINT_WARNING, "SDL_RWFromMem: %s\n", SDL_GetError());
|
||||
PrintFmt(PRINT_WARNING, "SDL_RWFromMem: {}\n", SDL_GetError());
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef TEMP_MIDI
|
||||
// We're using an older version of SDL and must save the midi data
|
||||
// to a temporary file first
|
||||
FILE* fp = fopen(TEMP_MIDI, "wb+");
|
||||
if (!fp)
|
||||
{
|
||||
Printf(PRINT_WARNING,
|
||||
"Could not open temporary music file %s, not playing track\n", TEMP_MIDI);
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the size of the music data
|
||||
SDL_RWseek(m_registeredSong.Data, 0, SEEK_END);
|
||||
size_t reglength = SDL_RWtell(m_registeredSong.Data);
|
||||
|
||||
// Write the music data to the temporary file
|
||||
SDL_RWseek(m_registeredSong.Data, 0, SEEK_SET);
|
||||
char buf[1024];
|
||||
while (reglength)
|
||||
{
|
||||
size_t chunksize = reglength > sizeof(buf) ? sizeof(buf) : reglength;
|
||||
|
||||
SDL_RWread(m_registeredSong.Data, buf, chunksize, 1);
|
||||
fwrite(buf, chunksize, 1, fp);
|
||||
reglength -= chunksize;
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
// Read the midi data from the temporary file
|
||||
m_registeredSong.Track = Mix_LoadMUS(TEMP_MIDI);
|
||||
unlink(TEMP_MIDI); // remove the temporary file
|
||||
|
||||
if (!m_registeredSong.Track)
|
||||
{
|
||||
Printf(PRINT_WARNING, "Mix_LoadMUSW: %s\n", Mix_GetError());
|
||||
return;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
// We can read the midi data directly from memory
|
||||
#ifdef SDL20
|
||||
m_registeredSong.Track = Mix_LoadMUS_RW(m_registeredSong.Data, 0);
|
||||
#elif defined SDL12
|
||||
m_registeredSong.Track = Mix_LoadMUS_RW(m_registeredSong.Data);
|
||||
#endif // SDL12
|
||||
|
||||
if (!m_registeredSong.Track)
|
||||
{
|
||||
Printf(PRINT_WARNING, "Mix_LoadMUS_RW: %s\n", Mix_GetError());
|
||||
PrintFmt(PRINT_WARNING, "Mix_LoadMUS_RW: {}\n", Mix_GetError());
|
||||
return;
|
||||
}
|
||||
|
||||
#endif // TEMP_MIDI
|
||||
}
|
||||
|
|
@ -37,7 +37,7 @@ class SdlMixerMusicSystem : public MusicSystem
|
|||
SdlMixerMusicSystem();
|
||||
~SdlMixerMusicSystem() override;
|
||||
|
||||
void startSong(byte* data, size_t length, bool loop) override ;
|
||||
void startSong(byte* data, size_t length, bool loop, int order) override ;
|
||||
void stopSong() override ;
|
||||
void pauseSong() override ;
|
||||
void resumeSong() override ;
|
||||
|
|
|
|||
|
|
@ -25,7 +25,9 @@
|
|||
|
||||
#include <SDL.h>
|
||||
|
||||
#if (SDL_MAJOR_VERSION == 2)
|
||||
#if (SDL_MAJOR_VERSION == 3)
|
||||
#define SDL3
|
||||
#elif (SDL_MAJOR_VERSION == 2)
|
||||
#define SDL20
|
||||
#if (SDL_MINOR_VERSION > 0 || SDL_PATCHLEVEL >= 16)
|
||||
#define SDL2016
|
||||
|
|
|
|||
|
|
@ -40,10 +40,6 @@
|
|||
#include "m_misc.h"
|
||||
#include "w_wad.h"
|
||||
|
||||
#ifdef _XBOX
|
||||
#include "i_xbox.h"
|
||||
#endif
|
||||
|
||||
#define NUM_CHANNELS 32
|
||||
|
||||
static int mixer_freq;
|
||||
|
|
@ -230,8 +226,8 @@ static Uint8 *perform_sdlmix_conv(Uint8 *data, Uint32 size, Uint32 *newsize)
|
|||
|
||||
if (!mem_op)
|
||||
{
|
||||
Printf(PRINT_HIGH,
|
||||
"perform_sdlmix_conv - SDL_RWFromMem: %s\n", SDL_GetError());
|
||||
PrintFmt(PRINT_HIGH,
|
||||
"perform_sdlmix_conv - SDL_RWFromMem: {}\n", SDL_GetError());
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -240,8 +236,8 @@ static Uint8 *perform_sdlmix_conv(Uint8 *data, Uint32 size, Uint32 *newsize)
|
|||
|
||||
if (!chunk)
|
||||
{
|
||||
Printf(PRINT_HIGH,
|
||||
"perform_sdlmix_conv - Mix_LoadWAV_RW: %s\n", Mix_GetError());
|
||||
PrintFmt(PRINT_HIGH,
|
||||
"perform_sdlmix_conv - Mix_LoadWAV_RW: {}\n", Mix_GetError());
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -483,28 +479,21 @@ void I_InitSound()
|
|||
if (I_IsHeadless() || Args.CheckParm("-nosound"))
|
||||
return;
|
||||
|
||||
#if defined(SDL12)
|
||||
const char *driver = getenv("SDL_AUDIODRIVER");
|
||||
|
||||
if(!driver)
|
||||
driver = "default";
|
||||
|
||||
Printf(PRINT_HIGH, "I_InitSound: Initializing SDL's sound subsystem (%s)\n", driver);
|
||||
#elif defined(SDL20)
|
||||
Printf("I_InitSound: Initializing SDL's sound subsystem\n");
|
||||
#if defined(SDL20)
|
||||
PrintFmt("I_InitSound: Initializing SDL's sound subsystem\n");
|
||||
#endif
|
||||
|
||||
if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0)
|
||||
{
|
||||
Printf(PRINT_ERROR,
|
||||
"I_InitSound: Unable to set up sound: %s\n",
|
||||
SDL_GetError());
|
||||
PrintFmt(PRINT_ERROR,
|
||||
"I_InitSound: Unable to set up sound: {}\n",
|
||||
SDL_GetError());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(SDL20)
|
||||
Printf("I_InitSound: Using SDL's audio driver (%s)\n", SDL_GetCurrentAudioDriver());
|
||||
PrintFmt("I_InitSound: Using SDL's audio driver ({})\n", SDL_GetCurrentAudioDriver());
|
||||
#endif
|
||||
|
||||
const SDL_version *ver = Mix_Linked_Version();
|
||||
|
|
@ -512,7 +501,7 @@ void I_InitSound()
|
|||
if(ver->major != MIX_MAJOR_VERSION
|
||||
|| ver->minor != MIX_MINOR_VERSION)
|
||||
{
|
||||
Printf(PRINT_ERROR, "I_InitSound: SDL_mixer version conflict (%d.%d.%d vs %d.%d.%d dll)\n",
|
||||
PrintFmt(PRINT_ERROR, "I_InitSound: SDL_mixer version conflict ({}.{}.{} vs {}.{}.{} dll)\n",
|
||||
MIX_MAJOR_VERSION, MIX_MINOR_VERSION, MIX_PATCHLEVEL,
|
||||
ver->major, ver->minor, ver->patch);
|
||||
return;
|
||||
|
|
@ -520,12 +509,12 @@ void I_InitSound()
|
|||
|
||||
if(ver->patch != MIX_PATCHLEVEL)
|
||||
{
|
||||
Printf(PRINT_WARNING, "I_InitSound: SDL_mixer version warning (%d.%d.%d vs %d.%d.%d dll)\n",
|
||||
PrintFmt(PRINT_WARNING, "I_InitSound: SDL_mixer version warning ({}.{}.{} vs {}.{}.{} dll)\n",
|
||||
MIX_MAJOR_VERSION, MIX_MINOR_VERSION, MIX_PATCHLEVEL,
|
||||
ver->major, ver->minor, ver->patch);
|
||||
}
|
||||
|
||||
Printf(PRINT_HIGH, "I_InitSound: Initializing SDL_mixer\n");
|
||||
PrintFmt(PRINT_HIGH, "I_InitSound: Initializing SDL_mixer\n");
|
||||
|
||||
#ifdef SDL20
|
||||
// Apparently, when Mix_OpenAudio requests a certain number of channels
|
||||
|
|
@ -539,23 +528,23 @@ void I_InitSound()
|
|||
if (Mix_OpenAudio((int)snd_samplerate, AUDIO_S16SYS, 2, 1024) < 0)
|
||||
#endif
|
||||
{
|
||||
Printf(PRINT_ERROR,
|
||||
"I_InitSound: Error initializing SDL_mixer: %s\n",
|
||||
Mix_GetError());
|
||||
PrintFmt(PRINT_ERROR,
|
||||
"I_InitSound: Error initializing SDL_mixer: {}\n",
|
||||
Mix_GetError());
|
||||
return;
|
||||
}
|
||||
|
||||
if(!Mix_QuerySpec(&mixer_freq, &mixer_format, &mixer_channels))
|
||||
{
|
||||
Printf(PRINT_ERROR,
|
||||
"I_InitSound: Error initializing SDL_mixer: %s\n",
|
||||
Mix_GetError());
|
||||
PrintFmt(PRINT_ERROR,
|
||||
"I_InitSound: Error initializing SDL_mixer: {}\n",
|
||||
Mix_GetError());
|
||||
return;
|
||||
}
|
||||
|
||||
Printf("I_InitSound: Using %d channels (freq:%d, fmt:%d, chan:%d)\n",
|
||||
Mix_AllocateChannels(NUM_CHANNELS),
|
||||
mixer_freq, mixer_format, mixer_channels);
|
||||
PrintFmt("I_InitSound: Using {} channels (freq:{}, fmt:{}, chan:{})\n",
|
||||
Mix_AllocateChannels(NUM_CHANNELS),
|
||||
mixer_freq, mixer_format, mixer_channels);
|
||||
|
||||
atterm(I_ShutdownSound);
|
||||
|
||||
|
|
@ -563,7 +552,7 @@ void I_InitSound()
|
|||
|
||||
SDL_PauseAudio(0);
|
||||
|
||||
Printf("I_InitSound: sound module ready\n");
|
||||
PrintFmt("I_InitSound: sound module ready\n");
|
||||
|
||||
I_InitMusic();
|
||||
|
||||
|
|
|
|||
|
|
@ -41,27 +41,22 @@
|
|||
|
||||
#include "win32inc.h"
|
||||
#ifdef _WIN32
|
||||
#include <direct.h>
|
||||
#include <io.h>
|
||||
#include <process.h>
|
||||
|
||||
#ifdef _XBOX
|
||||
#include <xtl.h>
|
||||
#else
|
||||
#include <shlwapi.h>
|
||||
#include <winsock2.h>
|
||||
#include <mmsystem.h>
|
||||
#include <shlobj.h>
|
||||
#endif // !_XBOX
|
||||
#include <direct.h>
|
||||
#include <io.h>
|
||||
#include <process.h>
|
||||
#include <shlwapi.h>
|
||||
#include <winsock2.h>
|
||||
#include <mmsystem.h>
|
||||
#include <shlobj.h>
|
||||
#endif // WIN32
|
||||
|
||||
#ifdef UNIX
|
||||
// for getuid and geteuid
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <limits.h>
|
||||
#include <time.h>
|
||||
#include <pwd.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <limits.h>
|
||||
#include <time.h>
|
||||
#include <pwd.h>
|
||||
#endif
|
||||
|
||||
#include <sstream>
|
||||
|
|
@ -93,14 +88,6 @@
|
|||
#include "m_fileio.h"
|
||||
#include "txt_main.h"
|
||||
|
||||
#ifdef _XBOX
|
||||
#include "i_xbox.h"
|
||||
#endif
|
||||
|
||||
#ifdef GEKKO
|
||||
#include "i_wii.h"
|
||||
#endif
|
||||
|
||||
#ifndef GCONSOLE // I will add this back later -- Hyper_Eye
|
||||
// For libtextscreen to link properly
|
||||
extern "C"
|
||||
|
|
@ -109,7 +96,7 @@
|
|||
}
|
||||
#define ENDOOM_W 80
|
||||
#define ENDOOM_H 25
|
||||
#endif // _XBOX
|
||||
#endif // GCONSOLE
|
||||
|
||||
EXTERN_CVAR (r_loadicon)
|
||||
EXTERN_CVAR (r_showendoom)
|
||||
|
|
@ -173,12 +160,12 @@ dtime_t I_GetTime()
|
|||
mach_port_deallocate(mach_task_self(), cclock);
|
||||
return mts.tv_sec * 1000LL * 1000LL * 1000LL + mts.tv_nsec;
|
||||
|
||||
#elif defined UNIX && !defined GEKKO
|
||||
#elif defined UNIX
|
||||
timespec ts;
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
return ts.tv_sec * 1000LL * 1000LL * 1000LL + ts.tv_nsec;
|
||||
|
||||
#elif defined WIN32 && !defined _XBOX
|
||||
#elif defined WIN32
|
||||
static bool initialized = false;
|
||||
static LARGE_INTEGER initial_count;
|
||||
static double nanoseconds_per_count;
|
||||
|
|
@ -262,7 +249,7 @@ void I_Sleep(dtime_t sleep_time)
|
|||
#if defined UNIX
|
||||
usleep(sleep_time / 1000LL);
|
||||
|
||||
#elif defined(WIN32) && !defined(_XBOX)
|
||||
#elif defined(WIN32)
|
||||
Sleep(sleep_time / 1000000LL);
|
||||
|
||||
#else
|
||||
|
|
@ -295,7 +282,7 @@ void I_WaitVBL(int count)
|
|||
//
|
||||
// SubsetLanguageIDs
|
||||
//
|
||||
#if defined _WIN32 && !defined _XBOX
|
||||
#if defined _WIN32
|
||||
static void SubsetLanguageIDs (LCID id, LCTYPE type, int idx)
|
||||
{
|
||||
char buf[8];
|
||||
|
|
@ -324,16 +311,35 @@ void SetLanguageIDs()
|
|||
|
||||
if (strcmp(langid, "auto") == 0)
|
||||
{
|
||||
#if defined _WIN32 && !defined _XBOX
|
||||
#if defined _WIN32
|
||||
memset(LanguageIDs, 0, sizeof(LanguageIDs));
|
||||
SubsetLanguageIDs(LOCALE_USER_DEFAULT, LOCALE_ILANGUAGE, 0);
|
||||
SubsetLanguageIDs(LOCALE_USER_DEFAULT, LOCALE_IDEFAULTLANGUAGE, 1);
|
||||
SubsetLanguageIDs(LOCALE_SYSTEM_DEFAULT, LOCALE_ILANGUAGE, 2);
|
||||
SubsetLanguageIDs(LOCALE_SYSTEM_DEFAULT, LOCALE_IDEFAULTLANGUAGE, 3);
|
||||
#elif SDL_VERSION_ATLEAST(2, 0, 14)
|
||||
SDL_Locale* locales = SDL_GetPreferredLocales();
|
||||
size_t i;
|
||||
for (i = 0; i < ARRAY_LENGTH(LanguageIDs) && locales && locales->language; i++)
|
||||
{
|
||||
char slang[4] = {'\0', '\0', '\0', '\0'};
|
||||
strncpy(slang, locales->language, ARRAY_LENGTH(slang) - 1);
|
||||
const uint32_t lang = MAKE_ID(slang[0], slang[1], slang[2], slang[3]);
|
||||
LanguageIDs[i] = lang;
|
||||
}
|
||||
if (i < ARRAY_LENGTH(LanguageIDs))
|
||||
{
|
||||
// Fill the rest with the last valid entry
|
||||
for (; i < ARRAY_LENGTH(LanguageIDs); i++)
|
||||
LanguageIDs[i] = LanguageIDs[i - 1];
|
||||
}
|
||||
#else
|
||||
// Default to US English on non-windows systems
|
||||
// FIXME: Use SDL Locale support if available.
|
||||
langid = "enu";
|
||||
static constexpr uint32_t lang = MAKE_ID('e', 'n', 'u', '\0');
|
||||
LanguageIDs[0] = lang;
|
||||
LanguageIDs[1] = lang;
|
||||
LanguageIDs[2] = lang;
|
||||
LanguageIDs[3] = lang;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
|
|
@ -465,7 +471,7 @@ void STACK_ARGS call_terms (void);
|
|||
|
||||
void I_BaseWarning(const std::string& warningtext)
|
||||
{
|
||||
Printf(PRINT_WARNING, "\n%s\n", warningtext);
|
||||
PrintFmt(PRINT_WARNING, "\n{}\n", warningtext);
|
||||
}
|
||||
|
||||
void I_BaseError(const std::string& errortext)
|
||||
|
|
@ -578,7 +584,7 @@ std::string I_GetClipboardText()
|
|||
|
||||
if (!dis)
|
||||
{
|
||||
Printf(PRINT_HIGH, "I_GetClipboardText: XOpenDisplay failed");
|
||||
PrintFmt(PRINT_HIGH, "I_GetClipboardText: XOpenDisplay failed");
|
||||
return "";
|
||||
}
|
||||
|
||||
|
|
@ -594,7 +600,7 @@ std::string I_GetClipboardText()
|
|||
XDestroyWindow(dis, WindowEvents);
|
||||
XUnlockDisplay(dis);
|
||||
XCloseDisplay(dis);
|
||||
Printf(PRINT_HIGH, "I_GetClipboardText: XConvertSelection failed");
|
||||
PrintFmt(PRINT_HIGH, "I_GetClipboardText: XConvertSelection failed");
|
||||
return "";
|
||||
}
|
||||
|
||||
|
|
@ -622,7 +628,7 @@ std::string I_GetClipboardText()
|
|||
XDestroyWindow(dis, WindowEvents);
|
||||
XUnlockDisplay(dis);
|
||||
XCloseDisplay(dis);
|
||||
Printf(PRINT_HIGH, "I_GetClipboardText: XGetWindowProperty failed(1)");
|
||||
PrintFmt(PRINT_HIGH, "I_GetClipboardText: XGetWindowProperty failed(1)");
|
||||
return "";
|
||||
}
|
||||
|
||||
|
|
@ -642,7 +648,7 @@ std::string I_GetClipboardText()
|
|||
XDestroyWindow(dis, WindowEvents);
|
||||
XUnlockDisplay(dis);
|
||||
XCloseDisplay(dis);
|
||||
Printf(PRINT_HIGH, "I_GetClipboardText: XGetWindowProperty failed(2)");
|
||||
PrintFmt(PRINT_HIGH, "I_GetClipboardText: XGetWindowProperty failed(2)");
|
||||
return "";
|
||||
}
|
||||
|
||||
|
|
@ -657,7 +663,7 @@ std::string I_GetClipboardText()
|
|||
return ret;
|
||||
#endif
|
||||
|
||||
#if defined _WIN32 && !defined _XBOX
|
||||
#if defined _WIN32
|
||||
std::string ret;
|
||||
|
||||
if(!IsClipboardFormatAvailable(CF_TEXT))
|
||||
|
|
@ -706,7 +712,7 @@ std::string I_GetClipboardText()
|
|||
|
||||
if (err)
|
||||
{
|
||||
Printf(PRINT_HIGH, "GetCurrentScrap error: %d", err);
|
||||
PrintFmt(PRINT_HIGH, "GetCurrentScrap error: {}", err);
|
||||
return "";
|
||||
}
|
||||
|
||||
|
|
@ -714,7 +720,7 @@ std::string I_GetClipboardText()
|
|||
|
||||
if (err)
|
||||
{
|
||||
Printf(PRINT_HIGH, "GetScrapFlavorSize error: %d", err);
|
||||
PrintFmt(PRINT_HIGH, "GetScrapFlavorSize error: {}", err);
|
||||
return "";
|
||||
}
|
||||
|
||||
|
|
@ -725,7 +731,7 @@ std::string I_GetClipboardText()
|
|||
|
||||
if(err)
|
||||
{
|
||||
Printf(PRINT_HIGH, "GetScrapFlavorData error: %d", err);
|
||||
PrintFmt(PRINT_HIGH, "GetScrapFlavorData error: {}", err);
|
||||
delete[] data;
|
||||
|
||||
return "";
|
||||
|
|
@ -744,7 +750,7 @@ std::string I_GetClipboardText()
|
|||
|
||||
if (NULL == textp)
|
||||
{
|
||||
Printf(PRINT_HIGH, "SDL_GetClipboardText error: %s", SDL_GetError());
|
||||
PrintFmt(PRINT_HIGH, "SDL_GetClipboardText error: {}", SDL_GetError());
|
||||
return "";
|
||||
}
|
||||
|
||||
|
|
@ -921,7 +927,7 @@ void I_ErrorMessageBox(const char* message)
|
|||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, ODAMEX_ERROR_TITLE, message, NULL);
|
||||
}
|
||||
|
||||
#elif defined(WIN32) && !defined(_XBOX)
|
||||
#elif defined(WIN32)
|
||||
|
||||
void I_ErrorMessageBox(const char* message)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -89,21 +89,21 @@ void I_BaseError(const std::string& errortext);
|
|||
[[noreturn]] void I_BaseFatalError(const std::string& errortext);
|
||||
|
||||
template <typename... ARGS>
|
||||
void I_Warning(const fmt::string_view format, const ARGS&... args)
|
||||
void I_Warning(fmt::format_string<ARGS...> format, ARGS&&... args)
|
||||
{
|
||||
I_BaseWarning(fmt::format(format, args...));
|
||||
I_BaseWarning(fmt::format(format, std::forward<ARGS>(args)...));
|
||||
}
|
||||
|
||||
template <typename... ARGS>
|
||||
void I_Error(const fmt::string_view format, const ARGS&... args)
|
||||
void I_Error(fmt::format_string<ARGS...> format, ARGS&&... args)
|
||||
{
|
||||
I_BaseError(fmt::format(format, args...));
|
||||
I_BaseError(fmt::format(format, std::forward<ARGS>(args)...));
|
||||
}
|
||||
|
||||
template <typename... ARGS>
|
||||
[[noreturn]] void I_FatalError(const fmt::string_view format, const ARGS&... args)
|
||||
[[noreturn]] void I_FatalError(fmt::format_string<ARGS...> format, ARGS&&... args)
|
||||
{
|
||||
I_BaseFatalError(fmt::format(format, args...));
|
||||
I_BaseFatalError(fmt::format(format, std::forward<ARGS>(args)...));
|
||||
}
|
||||
|
||||
void addterm (void (STACK_ARGS *func)(void), const char *name);
|
||||
|
|
|
|||
|
|
@ -33,9 +33,7 @@
|
|||
#include "i_video.h"
|
||||
#include "v_video.h"
|
||||
|
||||
#if defined(SDL12)
|
||||
#include "i_video_sdl12.h"
|
||||
#elif defined(SDL20)
|
||||
#if defined(SDL20)
|
||||
#include "i_video_sdl20.h"
|
||||
#else
|
||||
#error "no video subsystem selected"
|
||||
|
|
@ -51,7 +49,7 @@
|
|||
|
||||
// [Russell] - Just for windows, display the icon in the system menu and
|
||||
// alt-tab display
|
||||
#if defined(_WIN32) && !defined(_XBOX)
|
||||
#if defined(_WIN32)
|
||||
#include "win32inc.h"
|
||||
#include "SDL_syswm.h"
|
||||
#include "resource.h"
|
||||
|
|
@ -931,9 +929,7 @@ void I_InitHardware()
|
|||
}
|
||||
else
|
||||
{
|
||||
#if defined(SDL12)
|
||||
video_subsystem = new ISDL12VideoSubsystem();
|
||||
#elif defined(SDL20)
|
||||
#if defined(SDL20)
|
||||
video_subsystem = new ISDL20VideoSubsystem();
|
||||
#endif
|
||||
assert(video_subsystem != NULL);
|
||||
|
|
|
|||
|
|
@ -1,837 +0,0 @@
|
|||
// Emacs style mode select -*- C++ -*-
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Copyright (C) 2006-2025 by The Odamex Team.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// DESCRIPTION:
|
||||
// SDL 1.2 implementation of the IVideo class.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
#include "odamex.h"
|
||||
|
||||
#include "i_video_sdl12.h"
|
||||
|
||||
#include "i_sdl.h"
|
||||
#include <stdlib.h>
|
||||
#include <cassert>
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
|
||||
#include "i_video.h"
|
||||
#include "v_video.h"
|
||||
|
||||
#include "v_palette.h"
|
||||
#include "i_system.h"
|
||||
#include "i_input.h"
|
||||
#include "i_icon.h"
|
||||
|
||||
#include "c_dispatch.h"
|
||||
|
||||
// [Russell] - Just for windows, display the icon in the system menu and alt-tab display
|
||||
#include "win32inc.h"
|
||||
#if defined(_WIN32) && !defined(_XBOX)
|
||||
#include <SDL_syswm.h>
|
||||
#include "resource.h"
|
||||
#endif // WIN32
|
||||
|
||||
#ifdef _XBOX
|
||||
#include "i_xbox.h"
|
||||
#endif
|
||||
|
||||
|
||||
EXTERN_CVAR (vid_fullscreen)
|
||||
EXTERN_CVAR (vid_widescreen)
|
||||
EXTERN_CVAR (vid_pillarbox)
|
||||
|
||||
|
||||
// ****************************************************************************
|
||||
|
||||
#ifdef SDL12
|
||||
// ============================================================================
|
||||
//
|
||||
// ISDL12VideoCapabilities class implementation
|
||||
//
|
||||
// ============================================================================
|
||||
|
||||
//
|
||||
// I_AddSDL12VideoModes
|
||||
//
|
||||
// Queries SDL to find the supported video modes at the given bit depth
|
||||
// and then adds them to modelist.
|
||||
//
|
||||
static void I_AddSDL12VideoModes(IVideoModeList* modelist, int bpp)
|
||||
{
|
||||
SDL_PixelFormat format;
|
||||
memset(&format, 0, sizeof(format));
|
||||
format.BitsPerPixel = bpp;
|
||||
|
||||
SDL_Rect** sdlmodes = SDL_ListModes(&format, SDL_ANYFORMAT | SDL_FULLSCREEN | SDL_SWSURFACE);
|
||||
|
||||
if (sdlmodes)
|
||||
{
|
||||
if (sdlmodes == (SDL_Rect**)-1)
|
||||
{
|
||||
// SDL 1.2 documentation indicates the following
|
||||
// "-1: Any dimension is okay for the given format"
|
||||
// Shouldn't happen with SDL_FULLSCREEN flag though
|
||||
I_FatalError("SDL_ListModes returned -1. Internal error.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// add the video modes reported by SDL
|
||||
while (*sdlmodes)
|
||||
{
|
||||
int width = (*sdlmodes)->w, height = (*sdlmodes)->h;
|
||||
if (width > 0 && width <= MAXWIDTH && height > 0 && height <= MAXHEIGHT)
|
||||
{
|
||||
// add this video mode to the list (both fullscreen & windowed)
|
||||
modelist->push_back(IVideoMode(width, height, bpp, WINDOW_Windowed));
|
||||
modelist->push_back(IVideoMode(width, height, bpp, WINDOW_Fullscreen));
|
||||
}
|
||||
++sdlmodes;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
static bool Is8bppFullScreen(const IVideoMode& mode)
|
||||
{ return mode.bpp == 8 && mode.isFullScreen(); }
|
||||
#endif
|
||||
|
||||
|
||||
//
|
||||
// ISDL12VideoCapabilities::ISDL12VideoCapabilities
|
||||
//
|
||||
// Discovers the native desktop resolution and queries SDL for a list of
|
||||
// supported fullscreen video modes.
|
||||
//
|
||||
// NOTE: discovering the native desktop resolution only works if this is called
|
||||
// prior to the first SDL_SetVideoMode call!
|
||||
//
|
||||
// NOTE: SDL has palette issues in 8bpp fullscreen mode on Windows platforms. As
|
||||
// a workaround, we force a 32bpp resolution in this case by removing all
|
||||
// fullscreen 8bpp video modes on Windows platforms.
|
||||
//
|
||||
ISDL12VideoCapabilities::ISDL12VideoCapabilities() :
|
||||
IVideoCapabilities(),
|
||||
mNativeMode(SDL_GetVideoInfo()->current_w, SDL_GetVideoInfo()->current_h,
|
||||
SDL_GetVideoInfo()->vfmt->BitsPerPixel, WINDOW_Fullscreen)
|
||||
{
|
||||
I_AddSDL12VideoModes(&mModeList, 8);
|
||||
I_AddSDL12VideoModes(&mModeList, 32);
|
||||
|
||||
// always add the following windowed modes (if windowed modes are supported)
|
||||
if (supportsWindowed())
|
||||
{
|
||||
if (supports8bpp())
|
||||
{
|
||||
mModeList.push_back(IVideoMode(320, 200, 8, WINDOW_Windowed));
|
||||
mModeList.push_back(IVideoMode(320, 240, 8, WINDOW_Windowed));
|
||||
mModeList.push_back(IVideoMode(640, 400, 8, WINDOW_Windowed));
|
||||
mModeList.push_back(IVideoMode(640, 480, 8, WINDOW_Windowed));
|
||||
}
|
||||
if (supports32bpp())
|
||||
{
|
||||
mModeList.push_back(IVideoMode(320, 200, 32, WINDOW_Windowed));
|
||||
mModeList.push_back(IVideoMode(320, 240, 32, WINDOW_Windowed));
|
||||
mModeList.push_back(IVideoMode(640, 400, 32, WINDOW_Windowed));
|
||||
mModeList.push_back(IVideoMode(640, 480, 32, WINDOW_Windowed));
|
||||
}
|
||||
}
|
||||
|
||||
// reverse sort the modes
|
||||
std::sort(mModeList.begin(), mModeList.end(), std::greater<IVideoMode>());
|
||||
|
||||
// get rid of any duplicates (SDL sometimes reports duplicates)
|
||||
mModeList.erase(std::unique(mModeList.begin(), mModeList.end()), mModeList.end());
|
||||
|
||||
#ifdef _WIN32
|
||||
// fullscreen directx requires a 32-bit mode to fix broken palette
|
||||
// [Russell] - Use for gdi as well, fixes d2 map02 water
|
||||
// [SL] remove all fullscreen 8bpp modes
|
||||
mModeList.erase(std::remove_if(mModeList.begin(), mModeList.end(), Is8bppFullScreen), mModeList.end());
|
||||
#endif
|
||||
|
||||
assert(supportsWindowed() || supportsFullScreen());
|
||||
assert(supports8bpp() || supports32bpp());
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ****************************************************************************
|
||||
|
||||
// ============================================================================
|
||||
//
|
||||
// ISDL12DirectWindowSurfaceManager implementation
|
||||
//
|
||||
// Helper class for IWindow to encapsulate the creation of a IWindowSurface
|
||||
// primary surface and to assist in using it to refresh the window.
|
||||
//
|
||||
// ============================================================================
|
||||
|
||||
//
|
||||
// ISDL12DirectWindowSurfaceManager::ISDL12DirectWindowSurfaceManager
|
||||
//
|
||||
ISDL12DirectWindowSurfaceManager::ISDL12DirectWindowSurfaceManager(
|
||||
uint16_t width, uint16_t height, const PixelFormat* format)
|
||||
{
|
||||
SDL_Surface* sdl_surface = SDL_GetVideoSurface();
|
||||
assert(sdl_surface != NULL);
|
||||
mSurface = new IWindowSurface(width, height, format, sdl_surface->pixels, sdl_surface->pitch);
|
||||
assert(mSurface != NULL);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// ISDL12DirectWindowSurfaceManager::~ISDL12DirectWindowSurfaceManager
|
||||
//
|
||||
ISDL12DirectWindowSurfaceManager::~ISDL12DirectWindowSurfaceManager()
|
||||
{
|
||||
delete mSurface;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// ISDL12DirectWindowSurfaceManager::lockSurface
|
||||
//
|
||||
void ISDL12DirectWindowSurfaceManager::lockSurface()
|
||||
{
|
||||
SDL_Surface* sdl_surface = SDL_GetVideoSurface();
|
||||
assert(sdl_surface != NULL);
|
||||
if (SDL_MUSTLOCK(sdl_surface))
|
||||
SDL_LockSurface(sdl_surface);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// ISDL12DirectWindowSurfaceManager::unlockSurface
|
||||
//
|
||||
void ISDL12DirectWindowSurfaceManager::unlockSurface()
|
||||
{
|
||||
SDL_Surface* sdl_surface = SDL_GetVideoSurface();
|
||||
assert(sdl_surface != NULL);
|
||||
if (SDL_MUSTLOCK(sdl_surface))
|
||||
SDL_UnlockSurface(sdl_surface);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// ISDL12DirectWindowSurfaceManager::startRefresh
|
||||
//
|
||||
void ISDL12DirectWindowSurfaceManager::startRefresh()
|
||||
{ }
|
||||
|
||||
|
||||
//
|
||||
// ISDL12DirectWindowSurfaceManager::finishRefresh
|
||||
//
|
||||
void ISDL12DirectWindowSurfaceManager::finishRefresh()
|
||||
{
|
||||
SDL_Surface* sdl_surface = SDL_GetVideoSurface();
|
||||
assert(sdl_surface != NULL);
|
||||
SDL_Flip(sdl_surface);
|
||||
}
|
||||
|
||||
|
||||
// ============================================================================
|
||||
//
|
||||
// ISDL12SoftwareWindowSurfaceManager implementation
|
||||
//
|
||||
// Helper class for IWindow to encapsulate the creation of a IWindowSurface
|
||||
// primary surface and to assist in using it to refresh the window.
|
||||
//
|
||||
//
|
||||
// ============================================================================
|
||||
|
||||
//
|
||||
// ISDL12SoftwareWindowSurfaceManager::ISDL12SoftwareWindowSurfaceManager
|
||||
//
|
||||
ISDL12SoftwareWindowSurfaceManager::ISDL12SoftwareWindowSurfaceManager(
|
||||
uint16_t width, uint16_t height, const PixelFormat* format)
|
||||
{
|
||||
mSurface = new IWindowSurface(width, height, format);
|
||||
assert(mSurface != NULL);
|
||||
|
||||
uint32_t rmask = uint32_t(format->getRMax()) << format->getRShift();
|
||||
uint32_t gmask = uint32_t(format->getGMax()) << format->getGShift();
|
||||
uint32_t bmask = uint32_t(format->getBMax()) << format->getBShift();
|
||||
|
||||
mSDLSoftwareSurface = SDL_CreateRGBSurfaceFrom(
|
||||
mSurface->getBuffer(),
|
||||
mSurface->getWidth(), mSurface->getHeight(),
|
||||
mSurface->getBitsPerPixel(),
|
||||
mSurface->getPitch(),
|
||||
rmask, gmask, bmask, 0);
|
||||
|
||||
assert(mSDLSoftwareSurface != NULL);
|
||||
|
||||
SDL_Surface* sdl_surface = SDL_GetVideoSurface();
|
||||
assert(mSDLSoftwareSurface->format->Rmask == sdl_surface->format->Rmask &&
|
||||
mSDLSoftwareSurface->format->Gmask == sdl_surface->format->Gmask &&
|
||||
mSDLSoftwareSurface->format->Bmask == sdl_surface->format->Bmask);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// ISDL12SoftwareWindowSurfaceManager::~ISDL12SoftwareWindowSurfaceManager
|
||||
//
|
||||
ISDL12SoftwareWindowSurfaceManager::~ISDL12SoftwareWindowSurfaceManager()
|
||||
{
|
||||
if (mSDLSoftwareSurface)
|
||||
SDL_FreeSurface(mSDLSoftwareSurface);
|
||||
|
||||
delete mSurface;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// ISDL12SoftwareWindowSurfaceManager::lockSurface
|
||||
//
|
||||
void ISDL12SoftwareWindowSurfaceManager::lockSurface()
|
||||
{
|
||||
SDL_Surface* sdl_surface = SDL_GetVideoSurface();
|
||||
if (SDL_MUSTLOCK(sdl_surface))
|
||||
SDL_LockSurface(sdl_surface);
|
||||
if (SDL_MUSTLOCK(mSDLSoftwareSurface))
|
||||
SDL_LockSurface(mSDLSoftwareSurface);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// ISDL12SoftwareWindowSurfaceManager::unlockSurface
|
||||
//
|
||||
void ISDL12SoftwareWindowSurfaceManager::unlockSurface()
|
||||
{
|
||||
SDL_Surface* sdl_surface = SDL_GetVideoSurface();
|
||||
if (SDL_MUSTLOCK(sdl_surface))
|
||||
SDL_UnlockSurface(sdl_surface);
|
||||
if (SDL_MUSTLOCK(mSDLSoftwareSurface))
|
||||
SDL_UnlockSurface(mSDLSoftwareSurface);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// ISDL12SoftwareWindowSurfaceManager::startRefresh
|
||||
//
|
||||
void ISDL12SoftwareWindowSurfaceManager::startRefresh()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// ISDL12SoftwareWindowSurfaceManager::finishRefresh
|
||||
//
|
||||
void ISDL12SoftwareWindowSurfaceManager::finishRefresh()
|
||||
{
|
||||
SDL_Surface* main_sdl_surface = SDL_GetVideoSurface();
|
||||
assert(main_sdl_surface != NULL);
|
||||
SDL_BlitSurface(mSDLSoftwareSurface, NULL, main_sdl_surface, NULL);
|
||||
SDL_Flip(main_sdl_surface);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// ============================================================================
|
||||
//
|
||||
// ISDL12Window class implementation
|
||||
//
|
||||
// ============================================================================
|
||||
|
||||
|
||||
//
|
||||
// ISDL12Window::ISDL12Window (if windowed modes are supported)
|
||||
//
|
||||
// Constructs a new application window using SDL 1.2.
|
||||
// A ISDL12WindowSurface object is instantiated for frame rendering.
|
||||
//
|
||||
ISDL12Window::ISDL12Window(uint16_t width, uint16_t height, uint8_t bpp, EWindowMode window_mode, bool vsync) :
|
||||
IWindow(),
|
||||
mSurfaceManager(NULL),
|
||||
mVideoMode(0, 0, 0, WINDOW_Windowed),
|
||||
mNeedPaletteRefresh(true), mBlit(true), mIgnoreResize(false), mLocks(0)
|
||||
{ }
|
||||
|
||||
|
||||
//
|
||||
// ISDL12Window::~ISDL12Window
|
||||
//
|
||||
ISDL12Window::~ISDL12Window()
|
||||
{
|
||||
delete mSurfaceManager;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// ISDL12Window::lockSurface
|
||||
//
|
||||
// Locks the surface for direct pixel access. This must be called prior to
|
||||
// accessing the primary surface's buffer.
|
||||
//
|
||||
void ISDL12Window::lockSurface()
|
||||
{
|
||||
if (++mLocks == 1)
|
||||
mSurfaceManager->lockSurface();
|
||||
|
||||
assert(mLocks >= 1 && mLocks < 100);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// ISDL12Window::unlockSurface
|
||||
//
|
||||
// Unlocks the surface after direct pixel access. This must be called after
|
||||
// accessing the primary surface's buffer.
|
||||
//
|
||||
void ISDL12Window::unlockSurface()
|
||||
{
|
||||
if (--mLocks == 0)
|
||||
mSurfaceManager->unlockSurface();
|
||||
|
||||
assert(mLocks >= 0 && mLocks < 100);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// ISDL12Window::getEvents
|
||||
//
|
||||
// Retrieves events for the application window and processes them.
|
||||
//
|
||||
void ISDL12Window::getEvents()
|
||||
{
|
||||
// Force SDL to gather events from input devices. This is called
|
||||
// implicitly from SDL_PollEvent but since we're using SDL_PeepEvents to
|
||||
// process only mouse events, SDL_PumpEvents is necessary.
|
||||
SDL_PumpEvents();
|
||||
|
||||
// Retrieve chunks of up to 1024 events from SDL
|
||||
int num_events = 0;
|
||||
const int max_events = 1024;
|
||||
SDL_Event sdl_events[max_events];
|
||||
|
||||
// set mask to get all events except keyboard, mouse, and joystick events
|
||||
const int event_mask = SDL_ALLEVENTS & ~SDL_KEYEVENTMASK & ~SDL_MOUSEEVENTMASK & ~SDL_JOYEVENTMASK;
|
||||
|
||||
while ((num_events = SDL_PeepEvents(sdl_events, max_events, SDL_GETEVENT, event_mask)))
|
||||
{
|
||||
for (int i = 0; i < num_events; i++)
|
||||
{
|
||||
const SDL_Event& sdl_ev = sdl_events[i];
|
||||
|
||||
if (sdl_ev.type == SDL_QUIT)
|
||||
{
|
||||
AddCommandString("quit");
|
||||
}
|
||||
else if (sdl_ev.type == SDL_VIDEORESIZE)
|
||||
{
|
||||
// Resizable window mode resolutions
|
||||
if ((EWindowMode)vid_fullscreen.asInt() == WINDOW_Windowed && !mIgnoreResize)
|
||||
{
|
||||
char tmp[256];
|
||||
sprintf(tmp, "vid_setmode %i %i", sdl_ev.resize.w, sdl_ev.resize.h);
|
||||
AddCommandString(tmp);
|
||||
}
|
||||
}
|
||||
else if (sdl_ev.type == SDL_ACTIVEEVENT)
|
||||
{
|
||||
// Debugging messages
|
||||
if (sdl_ev.active.state & SDL_APPMOUSEFOCUS)
|
||||
DPrintFmt("SDL_ACTIVEEVENT SDL_APPMOUSEFOCUS {}\n", sdl_ev.active.gain ? "gained" : "lost");
|
||||
if (sdl_ev.active.state & SDL_APPINPUTFOCUS)
|
||||
DPrintFmt("SDL_ACTIVEEVENT SDL_APPINPUTFOCUS {}\n", sdl_ev.active.gain ? "gained" : "lost");
|
||||
if (sdl_ev.active.state & SDL_APPACTIVE)
|
||||
DPrintFmt("SDL_ACTIVEEVENT SDL_APPACTIVE {}\n", sdl_ev.active.gain ? "gained" : "lost");
|
||||
|
||||
// TODO: do we need to do anything here anymore?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mIgnoreResize = false;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// ISDL12Window::startRefresh
|
||||
//
|
||||
void ISDL12Window::startRefresh()
|
||||
{
|
||||
getEvents();
|
||||
|
||||
mSurfaceManager->startRefresh();
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// ISDL12Window::finishRefresh
|
||||
//
|
||||
void ISDL12Window::finishRefresh()
|
||||
{
|
||||
assert(mLocks == 0); // window surface shouldn't be locked when blitting
|
||||
|
||||
SDL_Surface* sdlsurface = SDL_GetVideoSurface();
|
||||
|
||||
if (mNeedPaletteRefresh)
|
||||
{
|
||||
Uint32 flags = SDL_LOGPAL | SDL_PHYSPAL;
|
||||
|
||||
if (sdlsurface->format->BitsPerPixel == 8)
|
||||
SDL_SetPalette(sdlsurface, flags, sdlsurface->format->palette->colors, 0, 256);
|
||||
// if (mSDLSoftwareSurface && mSDLSoftwareSurface->format->BitsPerPixel == 8)
|
||||
// SDL_SetPalette(mSDLSoftwareSurface, flags, mSDLSoftwareSurface->format->palette->colors, 0, 256);
|
||||
}
|
||||
|
||||
mNeedPaletteRefresh = false;
|
||||
|
||||
if (mBlit)
|
||||
{
|
||||
mSurfaceManager->finishRefresh();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// ISDL12Window::setWindowTitle
|
||||
//
|
||||
// Sets the title caption of the window.
|
||||
//
|
||||
void ISDL12Window::setWindowTitle(const std::string& str)
|
||||
{
|
||||
SDL_WM_SetCaption(str.c_str(), str.c_str());
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// ISDL12Window::setWindowIcon
|
||||
//
|
||||
// Sets the icon for the application window, which will appear in the
|
||||
// window manager's task list.
|
||||
//
|
||||
void ISDL12Window::setWindowIcon()
|
||||
{
|
||||
#if defined(_WIN32) && !defined(_XBOX)
|
||||
// [SL] Use Win32-specific code to make use of multiple-icon sizes
|
||||
// stored in the executable resources. SDL 1.2 only allows a fixed
|
||||
// 32x32 px icon.
|
||||
//
|
||||
// [Russell] - Just for windows, display the icon in the system menu and
|
||||
// alt-tab display
|
||||
|
||||
HICON hIcon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON1));
|
||||
|
||||
if (hIcon)
|
||||
{
|
||||
SDL_SysWMinfo wminfo;
|
||||
SDL_VERSION(&wminfo.version)
|
||||
SDL_GetWMInfo(&wminfo);
|
||||
HWND WindowHandle = wminfo.window;
|
||||
|
||||
if (WindowHandle)
|
||||
{
|
||||
SendMessage(WindowHandle, WM_SETICON, ICON_SMALL, (LPARAM)hIcon);
|
||||
SendMessage(WindowHandle, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
|
||||
}
|
||||
}
|
||||
#endif // _WIN32 && !_XBOX
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// ISDL12Window::isFocused
|
||||
//
|
||||
// Returns true if this window has input focus.
|
||||
//
|
||||
bool ISDL12Window::isFocused() const
|
||||
{
|
||||
SDL_PumpEvents();
|
||||
int app_state = SDL_GetAppState();
|
||||
return (app_state & SDL_APPINPUTFOCUS) && (app_state & SDL_APPACTIVE);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// ISDL12Window::getVideoDriverName
|
||||
//
|
||||
// Returns the name of the video driver that SDL is currently
|
||||
// configured to use.
|
||||
//
|
||||
std::string ISDL12Window::getVideoDriverName() const
|
||||
{
|
||||
char driver[128];
|
||||
|
||||
if ((SDL_VideoDriverName(driver, 128)) == NULL)
|
||||
{
|
||||
const char* pdrv = getenv("SDL_VIDEODRIVER");
|
||||
|
||||
if (pdrv == NULL)
|
||||
return "";
|
||||
return std::string(pdrv);
|
||||
}
|
||||
|
||||
return std::string(driver);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// I_SetSDL12Palette
|
||||
//
|
||||
// Helper function for ISDL12Window::setPalette
|
||||
//
|
||||
static void I_SetSDL12Palette(SDL_Surface* sdlsurface, const argb_t* palette_colors)
|
||||
{
|
||||
if (sdlsurface->format->BitsPerPixel == 8)
|
||||
{
|
||||
assert(sdlsurface->format->palette != NULL);
|
||||
assert(sdlsurface->format->palette->ncolors == 256);
|
||||
|
||||
SDL_Color* sdlcolors = sdlsurface->format->palette->colors;
|
||||
for (int c = 0; c < 256; c++)
|
||||
{
|
||||
argb_t color = palette_colors[c];
|
||||
sdlcolors[c].r = color.getr();
|
||||
sdlcolors[c].g = color.getg();
|
||||
sdlcolors[c].b = color.getb();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// ISDL12Window::setPalette
|
||||
//
|
||||
// Saves the given palette and updates it during refresh.
|
||||
//
|
||||
void ISDL12Window::setPalette(const argb_t* palette_colors)
|
||||
{
|
||||
lockSurface();
|
||||
|
||||
I_SetSDL12Palette(SDL_GetVideoSurface(), palette_colors);
|
||||
|
||||
// if (mSDLSoftwareSurface)
|
||||
// I_SetSDL12Palette(mSDLSoftwareSurface, palette_colors);
|
||||
|
||||
getPrimarySurface()->setPalette(palette_colors);
|
||||
|
||||
mNeedPaletteRefresh = true;
|
||||
|
||||
unlockSurface();
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// I_BuildPixelFormatFromSDLSurface
|
||||
//
|
||||
// Helper function that extracts information about the pixel format
|
||||
// from an SDL_Surface and uses it to initialize a PixelFormat object.
|
||||
// Note: the SDL_Surface should be locked prior to calling this.
|
||||
//
|
||||
static void I_BuildPixelFormatFromSDLSurface(const SDL_Surface* sdlsurface, PixelFormat* format)
|
||||
{
|
||||
const SDL_PixelFormat* sdlformat = sdlsurface->format;
|
||||
uint8_t bpp = sdlformat->BitsPerPixel;
|
||||
|
||||
// handle SDL not reporting correct Ashift/Aloss
|
||||
uint8_t aloss = bpp == 32 ? 0 : 8;
|
||||
uint8_t ashift = bpp == 32 ? 48 - sdlformat->Rshift - sdlformat->Gshift - sdlformat->Bshift : 0;
|
||||
|
||||
// Create the PixelFormat specification
|
||||
*format = PixelFormat(
|
||||
bpp,
|
||||
8 - aloss, 8 - sdlformat->Rloss, 8 - sdlformat->Gloss, 8 - sdlformat->Bloss,
|
||||
ashift, sdlformat->Rshift, sdlformat->Gshift, sdlformat->Bshift);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// ISDL12Window::getPixelFormat
|
||||
//
|
||||
const PixelFormat* ISDL12Window::getPixelFormat() const
|
||||
{
|
||||
static PixelFormat format;
|
||||
const SDL_Surface* sdl_surface = SDL_GetVideoSurface();
|
||||
I_BuildPixelFormatFromSDLSurface(sdl_surface, &format);
|
||||
return &format;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// ISDL12Window::setMode
|
||||
//
|
||||
// Sets the window size to the specified size and frees the existing primary
|
||||
// surface before instantiating a new primary surface. This function performs
|
||||
// no sanity checks on the desired video mode.
|
||||
//
|
||||
// NOTE: If a hardware surface is obtained or the surface's screen pitch
|
||||
// will create cache thrashing (tested by pitch & 511 == 0), a SDL software
|
||||
// surface will be created and used for drawing video frames. This software
|
||||
// surface is then blitted to the screen at the end of the frame, prior to
|
||||
// calling SDL_Flip.
|
||||
//
|
||||
bool ISDL12Window::setMode(const IVideoMode& video_mode)
|
||||
{
|
||||
bool is_windowed = video_mode.window_mode != WINDOW_Fullscreen;
|
||||
|
||||
uint32_t flags = 0;
|
||||
|
||||
if (video_mode.vsync)
|
||||
flags |= SDL_HWSURFACE | SDL_DOUBLEBUF;
|
||||
else
|
||||
flags |= SDL_SWSURFACE;
|
||||
|
||||
if (is_windowed)
|
||||
{
|
||||
flags |= SDL_RESIZABLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
flags |= SDL_FULLSCREEN;
|
||||
if (video_mode.bpp == 8)
|
||||
flags |= SDL_HWPALETTE;
|
||||
}
|
||||
|
||||
flags |= SDL_ASYNCBLIT;
|
||||
|
||||
#ifdef SDL_GL_SWAP_CONTROL
|
||||
SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, video_mode.vsync);
|
||||
#endif
|
||||
|
||||
SDL_Surface* sdl_surface = SDL_SetVideoMode(video_mode.width, video_mode.height, video_mode.bpp, flags);
|
||||
if (sdl_surface == NULL)
|
||||
{
|
||||
I_FatalError("I_SetVideoMode: unable to set video mode {}x{}x{} ({}): {}\n",
|
||||
video_mode.width, video_mode.height, video_mode.bpp, is_windowed ? "windowed" : "fullscreen",
|
||||
SDL_GetError());
|
||||
return false;
|
||||
}
|
||||
|
||||
assert(sdl_surface == SDL_GetVideoSurface());
|
||||
|
||||
const PixelFormat* format = getPixelFormat();
|
||||
|
||||
// just in case SDL couldn't set the exact video mode we asked for...
|
||||
mVideoMode.width = sdl_surface->w;
|
||||
mVideoMode.height = sdl_surface->h;
|
||||
//mVideoMode.bpp = format->getBitsPerPixel();
|
||||
mVideoMode.bpp = video_mode.bpp;
|
||||
if ((sdl_surface->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN)
|
||||
mVideoMode.window_mode = WINDOW_Fullscreen;
|
||||
else
|
||||
mVideoMode.window_mode = WINDOW_Windowed;
|
||||
mVideoMode.vsync = video_mode.vsync;
|
||||
mVideoMode.stretch_mode = video_mode.stretch_mode;
|
||||
|
||||
if (SDL_MUSTLOCK(sdl_surface))
|
||||
SDL_LockSurface(sdl_surface); // lock prior to accessing pixel format
|
||||
|
||||
delete mSurfaceManager;
|
||||
|
||||
bool got_hardware_surface = (sdl_surface->flags & SDL_HWSURFACE) == SDL_HWSURFACE;
|
||||
|
||||
bool create_software_surface =
|
||||
(sdl_surface->pitch & 511) == 0 || // pitch is a multiple of 512 (thrashes the cache)
|
||||
got_hardware_surface; // drawing directly to hardware surfaces is slower
|
||||
|
||||
if (create_software_surface)
|
||||
mSurfaceManager = new ISDL12SoftwareWindowSurfaceManager(mVideoMode.width, mVideoMode.height, format);
|
||||
else
|
||||
mSurfaceManager = new ISDL12DirectWindowSurfaceManager(mVideoMode.width, mVideoMode.height, format);
|
||||
|
||||
assert(mSurfaceManager != NULL);
|
||||
assert(getPrimarySurface() != NULL);
|
||||
|
||||
if (SDL_MUSTLOCK(sdl_surface))
|
||||
SDL_UnlockSurface(sdl_surface);
|
||||
|
||||
// Tell argb_t the pixel format
|
||||
if (format->getBitsPerPixel() == 32)
|
||||
argb_t::setChannels(format->getAPos(), format->getRPos(), format->getGPos(), format->getBPos());
|
||||
else
|
||||
{
|
||||
#if defined(__SWITCH__)
|
||||
argb_t::setChannels(0, 3, 2, 1);
|
||||
#else
|
||||
argb_t::setChannels(3, 2, 1, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
// [SL] SDL can create SDL_VIDEORESIZE events in response to SDL_SetVideoMode
|
||||
// and we need to filter those out.
|
||||
mIgnoreResize = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// ****************************************************************************
|
||||
|
||||
// ============================================================================
|
||||
//
|
||||
// ISDL12VideoSubsystem class implementation
|
||||
//
|
||||
// ============================================================================
|
||||
|
||||
|
||||
//
|
||||
// ISDL12VideoSubsystem::ISDL12VideoSubsystem
|
||||
//
|
||||
// Initializes SDL video and sets a few SDL configuration options.
|
||||
//
|
||||
ISDL12VideoSubsystem::ISDL12VideoSubsystem() : IVideoSubsystem()
|
||||
{
|
||||
const SDL_version* SDLVersion = SDL_Linked_Version();
|
||||
|
||||
if (SDLVersion->major != SDL_MAJOR_VERSION || SDLVersion->minor != SDL_MINOR_VERSION)
|
||||
{
|
||||
I_FatalError("SDL version conflict ({}.{}.{} vs {}.{}.{} dll)\n",
|
||||
SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL,
|
||||
SDLVersion->major, SDLVersion->minor, SDLVersion->patch);
|
||||
return;
|
||||
}
|
||||
|
||||
if (SDLVersion->patch != SDL_PATCHLEVEL)
|
||||
{
|
||||
Printf(PRINT_WARNING, "SDL version warning (%d.%d.%d vs %d.%d.%d dll)\n",
|
||||
SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL,
|
||||
SDLVersion->major, SDLVersion->minor, SDLVersion->patch);
|
||||
}
|
||||
|
||||
if (SDL_InitSubSystem(SDL_INIT_VIDEO) == -1)
|
||||
{
|
||||
I_FatalError("Could not initialize SDL video.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
mVideoCapabilities = new ISDL12VideoCapabilities();
|
||||
|
||||
mWindow = new ISDL12Window(640, 480, 8, WINDOW_Windowed, false);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// ISDL12VideoSubsystem::~ISDL12VideoSubsystem
|
||||
//
|
||||
ISDL12VideoSubsystem::~ISDL12VideoSubsystem()
|
||||
{
|
||||
delete mWindow;
|
||||
delete mVideoCapabilities;
|
||||
|
||||
SDL_QuitSubSystem(SDL_INIT_VIDEO);
|
||||
}
|
||||
#endif // SDL12
|
||||
|
||||
VERSION_CONTROL (i_video_sdl12_cpp, "$Id$")
|
||||
|
|
@ -1,257 +0,0 @@
|
|||
// Emacs style mode select -*- C++ -*-
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Copyright (C) 2006-2025 by The Odamex Team.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// DESCRIPTION:
|
||||
// SDL 1.2 implementation of the IWindow class
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "i_sdl.h"
|
||||
#include "i_video.h"
|
||||
|
||||
#ifdef SDL12
|
||||
// ============================================================================
|
||||
//
|
||||
// ISDL12VideoCapabilities class interface
|
||||
//
|
||||
// Defines an interface for querying video capabilities. This includes listing
|
||||
// availible video modes and supported operations.
|
||||
//
|
||||
// ============================================================================
|
||||
|
||||
class ISDL12VideoCapabilities : public IVideoCapabilities
|
||||
{
|
||||
public:
|
||||
ISDL12VideoCapabilities();
|
||||
virtual ~ISDL12VideoCapabilities() { }
|
||||
|
||||
virtual const IVideoModeList* getSupportedVideoModes() const
|
||||
{ return &mModeList; }
|
||||
|
||||
virtual EDisplayType getDisplayType() const
|
||||
{
|
||||
#ifdef GCONSOLE
|
||||
return DISPLAY_FullscreenOnly;
|
||||
#else
|
||||
return DISPLAY_Both;
|
||||
#endif
|
||||
}
|
||||
|
||||
virtual const IVideoMode& getNativeMode() const
|
||||
{ return mNativeMode; }
|
||||
|
||||
private:
|
||||
IVideoModeList mModeList;
|
||||
IVideoMode mNativeMode;
|
||||
};
|
||||
|
||||
|
||||
// ============================================================================
|
||||
//
|
||||
// ISDL12DirectWindowSurfaceManager
|
||||
//
|
||||
// Helper class for IWindow to encapsulate the creation of a IWindowSurface
|
||||
// primary surface and to assist in using it to refresh the window.
|
||||
//
|
||||
// This creates a IWindowSurface based on SDL's primary surface.
|
||||
//
|
||||
// ============================================================================
|
||||
|
||||
class ISDL12DirectWindowSurfaceManager : public IWindowSurfaceManager
|
||||
{
|
||||
public:
|
||||
ISDL12DirectWindowSurfaceManager(uint16_t width, uint16_t height, const PixelFormat* format);
|
||||
|
||||
virtual ~ISDL12DirectWindowSurfaceManager();
|
||||
|
||||
virtual const IWindowSurface* getWindowSurface() const
|
||||
{ return mSurface; }
|
||||
|
||||
virtual void lockSurface();
|
||||
virtual void unlockSurface();
|
||||
|
||||
virtual void startRefresh();
|
||||
virtual void finishRefresh();
|
||||
|
||||
private:
|
||||
IWindowSurface* mSurface;
|
||||
};
|
||||
|
||||
|
||||
// ============================================================================
|
||||
//
|
||||
// ISDL12SoftwareWindowSurfaceManager
|
||||
//
|
||||
// Helper class for IWindow to encapsulate the creation of a IWindowSurface
|
||||
// primary surface and to assist in using it to refresh the window.
|
||||
//
|
||||
//
|
||||
// ============================================================================
|
||||
|
||||
class ISDL12SoftwareWindowSurfaceManager : public IWindowSurfaceManager
|
||||
{
|
||||
public:
|
||||
ISDL12SoftwareWindowSurfaceManager(uint16_t width, uint16_t height, const PixelFormat* format);
|
||||
|
||||
virtual ~ISDL12SoftwareWindowSurfaceManager();
|
||||
|
||||
virtual const IWindowSurface* getWindowSurface() const
|
||||
{ return mSurface; }
|
||||
|
||||
virtual void lockSurface();
|
||||
virtual void unlockSurface();
|
||||
|
||||
virtual void startRefresh();
|
||||
virtual void finishRefresh();
|
||||
|
||||
private:
|
||||
SDL_Surface* mSDLSoftwareSurface;
|
||||
IWindowSurface* mSurface;
|
||||
};
|
||||
|
||||
|
||||
// ============================================================================
|
||||
//
|
||||
// ISDL12Window class interface
|
||||
//
|
||||
// ============================================================================
|
||||
|
||||
class ISDL12Window : public IWindow
|
||||
{
|
||||
public:
|
||||
ISDL12Window(uint16_t width, uint16_t height, uint8_t bpp, EWindowMode window_mode, bool vsync);
|
||||
|
||||
virtual ~ISDL12Window();
|
||||
|
||||
virtual const IWindowSurface* getPrimarySurface() const
|
||||
{
|
||||
if (mSurfaceManager)
|
||||
return mSurfaceManager->getWindowSurface();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
virtual IWindowSurface* getPrimarySurface()
|
||||
{
|
||||
return const_cast<IWindowSurface*>(static_cast<const ISDL12Window&>(*this).getPrimarySurface());
|
||||
}
|
||||
|
||||
virtual uint16_t getWidth() const
|
||||
{ return mVideoMode.width; }
|
||||
|
||||
virtual uint16_t getHeight() const
|
||||
{ return mVideoMode.height; }
|
||||
|
||||
virtual uint8_t getBitsPerPixel() const
|
||||
{ return mVideoMode.bpp; }
|
||||
|
||||
virtual int getBytesPerPixel() const
|
||||
{ return mVideoMode.bpp >> 3; }
|
||||
|
||||
virtual const IVideoMode& getVideoMode() const
|
||||
{ return mVideoMode; }
|
||||
|
||||
virtual const PixelFormat* getPixelFormat() const;
|
||||
|
||||
virtual bool setMode(const IVideoMode& video_mode);
|
||||
|
||||
virtual bool isFullScreen() const
|
||||
{ return mVideoMode.window_mode != WINDOW_Windowed; }
|
||||
|
||||
virtual EWindowMode getWindowMode() const
|
||||
{ return mVideoMode.window_mode; }
|
||||
|
||||
virtual bool isFocused() const;
|
||||
|
||||
virtual bool usingVSync() const
|
||||
{ return mVideoMode.vsync; }
|
||||
|
||||
virtual void enableRefresh()
|
||||
{ mBlit = true; }
|
||||
|
||||
virtual void disableRefresh()
|
||||
{
|
||||
mBlit = false;
|
||||
mSurfaceManager->lockSurface();
|
||||
mSurfaceManager->getWindowSurface()->clear();
|
||||
mSurfaceManager->finishRefresh();
|
||||
mSurfaceManager->unlockSurface();
|
||||
}
|
||||
|
||||
virtual void startRefresh();
|
||||
virtual void finishRefresh();
|
||||
|
||||
virtual void lockSurface();
|
||||
virtual void unlockSurface();
|
||||
|
||||
virtual void setWindowTitle(const std::string& str = "");
|
||||
virtual void setWindowIcon();
|
||||
|
||||
virtual std::string getVideoDriverName() const;
|
||||
|
||||
virtual void setPalette(const argb_t* palette);
|
||||
|
||||
private:
|
||||
// disable copy constructor and assignment operator
|
||||
ISDL12Window(const ISDL12Window&);
|
||||
ISDL12Window& operator=(const ISDL12Window&);
|
||||
|
||||
void getEvents();
|
||||
|
||||
IWindowSurfaceManager* mSurfaceManager;
|
||||
|
||||
IVideoMode mVideoMode;
|
||||
|
||||
bool mNeedPaletteRefresh;
|
||||
bool mBlit;
|
||||
|
||||
bool mIgnoreResize;
|
||||
|
||||
int16_t mLocks;
|
||||
};
|
||||
|
||||
// ****************************************************************************
|
||||
|
||||
// ============================================================================
|
||||
//
|
||||
// ISDL12VideoSubsystem class interface
|
||||
//
|
||||
// Provides intialization and shutdown mechanics for the video subsystem.
|
||||
// This is really an abstract factory pattern as it instantiates a family
|
||||
// of concrete types.
|
||||
//
|
||||
// ============================================================================
|
||||
|
||||
class ISDL12VideoSubsystem : public IVideoSubsystem
|
||||
{
|
||||
public:
|
||||
ISDL12VideoSubsystem();
|
||||
virtual ~ISDL12VideoSubsystem();
|
||||
|
||||
virtual const IVideoCapabilities* getVideoCapabilities() const
|
||||
{ return mVideoCapabilities; }
|
||||
|
||||
virtual const IWindow* getWindow() const
|
||||
{ return mWindow; }
|
||||
|
||||
private:
|
||||
const IVideoCapabilities* mVideoCapabilities;
|
||||
|
||||
IWindow* mWindow;
|
||||
};
|
||||
#endif // SDL12
|
||||
|
|
@ -44,15 +44,11 @@
|
|||
|
||||
// [Russell] - Just for windows, display the icon in the system menu and alt-tab display
|
||||
#include "win32inc.h"
|
||||
#if defined(_WIN32) && !defined(_XBOX)
|
||||
#if defined(_WIN32)
|
||||
#include <SDL_syswm.h>
|
||||
#include "resource.h"
|
||||
#endif // WIN32
|
||||
|
||||
#ifdef _XBOX
|
||||
#include "i_xbox.h"
|
||||
#endif
|
||||
|
||||
EXTERN_CVAR (vid_fullscreen)
|
||||
EXTERN_CVAR (vid_widescreen)
|
||||
EXTERN_CVAR (vid_pillarbox)
|
||||
|
|
@ -395,7 +391,7 @@ ISDL20Window::ISDL20Window(uint16_t width, uint16_t height, uint8_t bpp, EWindow
|
|||
{
|
||||
setRendererDriver();
|
||||
const char* driver_name = getRendererDriver();
|
||||
Printf(PRINT_HIGH, "V_Init: rendering mode \"%s\"\n", driver_name);
|
||||
PrintFmt(PRINT_HIGH, "V_Init: rendering mode \"{}\"\n", driver_name);
|
||||
|
||||
SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "0");
|
||||
|
||||
|
|
@ -664,7 +660,7 @@ void ISDL20Window::setWindowTitle(const std::string& str)
|
|||
//
|
||||
void ISDL20Window::setWindowIcon()
|
||||
{
|
||||
#if defined(_WIN32) && !defined(_XBOX)
|
||||
#if defined(_WIN32)
|
||||
// [SL] Use Win32-specific code to make use of multiple-icon sizes
|
||||
// stored in the executable resources.
|
||||
//
|
||||
|
|
@ -686,9 +682,9 @@ void ISDL20Window::setWindowIcon()
|
|||
SendMessage(WindowHandle, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
|
||||
}
|
||||
}
|
||||
#endif // _WIN32 && !_XBOX
|
||||
#endif // _WIN32
|
||||
|
||||
#if !defined(_WIN32) && !defined(_XBOX)
|
||||
#if !defined(_WIN32)
|
||||
SDL_Surface* icon_surface = SDL_CreateRGBSurfaceFrom(
|
||||
(void*)app_icon.pixel_data, app_icon.width, app_icon.height,
|
||||
app_icon.bytes_per_pixel * 8, app_icon.width * app_icon.bytes_per_pixel,
|
||||
|
|
@ -696,7 +692,7 @@ void ISDL20Window::setWindowIcon()
|
|||
|
||||
SDL_SetWindowIcon(mSDLWindow, icon_surface);
|
||||
SDL_FreeSurface(icon_surface);
|
||||
#endif // !_WIN32 && !_XBOX
|
||||
#endif // !_WIN32
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@ argb_t CL_GetPlayerColor(player_t*);
|
|||
EXTERN_CVAR(am_followplayer)
|
||||
|
||||
static int lockglow = 0;
|
||||
static int bossglow = 0;
|
||||
|
||||
EXTERN_CVAR(am_rotate)
|
||||
EXTERN_CVAR(am_overlay)
|
||||
|
|
@ -194,6 +195,7 @@ typedef struct
|
|||
// vector graphics for the automap for things.
|
||||
std::vector<mline_t> thintriangle_guy;
|
||||
std::vector<mline_t> thinrectangle_guy;
|
||||
std::vector<mline_t> hordeboss_guy;
|
||||
|
||||
am_default_colors_t AutomapDefaultColors;
|
||||
am_colors_t AutomapDefaultCurrentColors;
|
||||
|
|
@ -270,21 +272,21 @@ void AM_minOutWindowScale();
|
|||
BEGIN_COMMAND(am_grid)
|
||||
{
|
||||
grid = !grid;
|
||||
Printf(PRINT_HIGH, "%s\n", grid ? GStrings(AMSTR_GRIDON) : GStrings(AMSTR_GRIDOFF));
|
||||
PrintFmt(PRINT_HIGH, "{}\n", grid ? GStrings(AMSTR_GRIDON) : GStrings(AMSTR_GRIDOFF));
|
||||
}
|
||||
END_COMMAND(am_grid)
|
||||
|
||||
BEGIN_COMMAND(am_setmark)
|
||||
{
|
||||
AM_addMark();
|
||||
Printf(PRINT_HIGH, "%s %d\n", GStrings(AMSTR_MARKEDSPOT), markpointnum);
|
||||
PrintFmt(PRINT_HIGH, "{} {}\n", GStrings(AMSTR_MARKEDSPOT), markpointnum);
|
||||
}
|
||||
END_COMMAND(am_setmark)
|
||||
|
||||
BEGIN_COMMAND(am_clearmarks)
|
||||
{
|
||||
AM_clearMarks();
|
||||
Printf(PRINT_HIGH, "%s\n", GStrings(AMSTR_MARKSCLEARED));
|
||||
PrintFmt(PRINT_HIGH, "{}\n", GStrings(AMSTR_MARKSCLEARED));
|
||||
}
|
||||
END_COMMAND(am_clearmarks)
|
||||
|
||||
|
|
@ -304,9 +306,9 @@ END_COMMAND(am_big)
|
|||
BEGIN_COMMAND(am_togglefollow)
|
||||
{
|
||||
am_followplayer = !am_followplayer;
|
||||
f_oldloc.x = MAXINT;
|
||||
Printf(PRINT_HIGH, "%s\n",
|
||||
am_followplayer ? GStrings(AMSTR_FOLLOWON) : GStrings(AMSTR_FOLLOWOFF));
|
||||
f_oldloc.x = limits::MAXINT;
|
||||
PrintFmt(PRINT_HIGH, "{}\n",
|
||||
am_followplayer ? GStrings(AMSTR_FOLLOWON) : GStrings(AMSTR_FOLLOWOFF));
|
||||
}
|
||||
END_COMMAND(am_togglefollow)
|
||||
|
||||
|
|
@ -383,8 +385,8 @@ void AM_addMark()
|
|||
//
|
||||
void AM_findMinMaxBoundaries()
|
||||
{
|
||||
M_SetVec2Fixed64(&min, MAXLONG, MAXLONG);
|
||||
M_SetVec2Fixed64(&max, -MAXLONG, -MAXLONG);
|
||||
M_SetVec2Fixed64(&min, limits::MAXFIXED64, limits::MAXFIXED64);
|
||||
M_SetVec2Fixed64(&max, limits::MINFIXED64, limits::MINFIXED64);
|
||||
|
||||
for (const auto [x, y]: R_GetVertices())
|
||||
{
|
||||
|
|
@ -419,7 +421,7 @@ void AM_changeWindowLoc()
|
|||
if (m_paninc.x || m_paninc.y)
|
||||
{
|
||||
am_followplayer.Set(0.0f);
|
||||
f_oldloc.x = MAXINT;
|
||||
f_oldloc.x = limits::MAXINT;
|
||||
}
|
||||
|
||||
M_AddVec2Fixed64(&m_ll, &m_paninc, &m_ll);
|
||||
|
|
@ -446,6 +448,7 @@ void AM_initVariables()
|
|||
|
||||
thintriangle_guy.clear();
|
||||
thinrectangle_guy.clear();
|
||||
hordeboss_guy.clear();
|
||||
|
||||
mline_t ml;
|
||||
|
||||
|
|
@ -466,12 +469,30 @@ void AM_initVariables()
|
|||
ADD_TO_VEC(thinrectangle_guy, -1, -1, -1, 1)
|
||||
ADD_TO_VEC(thinrectangle_guy, -1, 1, 1, 1)
|
||||
|
||||
static const OLumpName bossicon = "OBOSSMAP";
|
||||
const auto hordeboss_lines = AM_ParseVectorLump(bossicon);
|
||||
if (!hordeboss_lines)
|
||||
{
|
||||
switch (hordeboss_lines.error())
|
||||
{
|
||||
case am_lump_parse_error_t::LUMP_NOT_FOUND:
|
||||
DPrintFmt("Horde boss automap icon lump \"{}\" could not be found", bossicon);
|
||||
break;
|
||||
default:
|
||||
DPrintFmt("Error while parsing horde boss automap icon lump \"{}\"", bossicon);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
hordeboss_guy = hordeboss_lines.value();
|
||||
}
|
||||
|
||||
#undef ADD_TO_VEC
|
||||
#undef L
|
||||
|
||||
automapactive = true;
|
||||
|
||||
f_oldloc.x = MAXINT;
|
||||
f_oldloc.x = limits::MAXINT;
|
||||
amclock = 0;
|
||||
|
||||
M_SetVec2Fixed64(&m_wh, FTOM(I_GetSurfaceWidth()), FTOM(I_GetSurfaceHeight()));
|
||||
|
|
@ -919,6 +940,15 @@ void AM_doFollowPlayer()
|
|||
m_ll.y + m_wh.y);
|
||||
}
|
||||
|
||||
struct
|
||||
{
|
||||
std::array<uint8_t, 3> reddoor;
|
||||
std::array<uint8_t, 3> bluedoor;
|
||||
std::array<uint8_t, 3> yellowdoor;
|
||||
std::array<uint8_t, 3> multidoor;
|
||||
} doorColors;
|
||||
|
||||
|
||||
//
|
||||
// Updates on Game Tick
|
||||
//
|
||||
|
|
@ -934,6 +964,77 @@ void AM_Ticker()
|
|||
lockglow++;
|
||||
else
|
||||
lockglow = 0;
|
||||
|
||||
if (bossglow < 60)
|
||||
bossglow++;
|
||||
else
|
||||
bossglow = 0;
|
||||
|
||||
const std::array<uint8_t,3> baseDoorColor = {
|
||||
gameinfo.currentAutomapColors.LockedColor.rgb.getr(),
|
||||
gameinfo.currentAutomapColors.LockedColor.rgb.getg(),
|
||||
gameinfo.currentAutomapColors.LockedColor.rgb.getb()
|
||||
};
|
||||
|
||||
if (am_usecustomcolors || am_showlocked)
|
||||
{
|
||||
const auto lerp = [](uint8_t a, uint8_t b, int t, int max) -> uint8_t
|
||||
{
|
||||
return static_cast<uint8_t>(a + (b - a) * t / max);
|
||||
};
|
||||
|
||||
const auto lerp3 = [&lerp](const std::array<uint8_t,3>& a,
|
||||
const std::array<uint8_t,3>& b,
|
||||
int t, int max)
|
||||
{
|
||||
return std::array<uint8_t, 3>{
|
||||
lerp(a[0], b[0], t, max),
|
||||
lerp(a[1], b[1], t, max),
|
||||
lerp(a[2], b[2], t, max)
|
||||
};
|
||||
};
|
||||
|
||||
const auto pulse = [&baseDoorColor, &lerp3](const std::array<uint8_t, 3>& color) -> std::array<uint8_t, 3>
|
||||
{
|
||||
if (lockglow < 30)
|
||||
{
|
||||
return lerp3(baseDoorColor, color, lockglow, 30);
|
||||
}
|
||||
else if (lockglow < 60)
|
||||
{
|
||||
return lerp3(baseDoorColor, color, 60 - lockglow, 30);
|
||||
}
|
||||
else
|
||||
{
|
||||
return baseDoorColor;
|
||||
}
|
||||
};
|
||||
|
||||
static constexpr std::array<uint8_t, 3> red = {255, 0, 0};
|
||||
static constexpr std::array<uint8_t, 3> blue = {0, 0, 255};
|
||||
static constexpr std::array<uint8_t, 3> yellow = {255, 255, 0};
|
||||
|
||||
doorColors.reddoor = pulse(red);
|
||||
doorColors.bluedoor = pulse(blue);
|
||||
doorColors.yellowdoor = pulse(yellow);
|
||||
|
||||
static constexpr std::array<std::array<uint8_t,3>, 3> seq = {
|
||||
red, blue, yellow
|
||||
};
|
||||
|
||||
const int segment = (lockglow / 30) % 3;
|
||||
const int next = (segment + 1) % 3;
|
||||
const int t = lockglow % 30;
|
||||
|
||||
doorColors.multidoor = lerp3(seq[segment], seq[next], t, 30);
|
||||
}
|
||||
else
|
||||
{
|
||||
doorColors.reddoor = baseDoorColor;
|
||||
doorColors.bluedoor = baseDoorColor;
|
||||
doorColors.yellowdoor = baseDoorColor;
|
||||
doorColors.multidoor = baseDoorColor;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -1354,49 +1455,56 @@ void AM_drawWalls()
|
|||
AM_drawMline(&l, gameinfo.currentAutomapColors.TSWallColor);
|
||||
}
|
||||
|
||||
// NES - Locked doors glow from a predefined color to either blue,
|
||||
// yellow, or red.
|
||||
if (map_format.getZDoom())
|
||||
{
|
||||
if (line.special == Door_LockedRaise)
|
||||
if (line.special == Door_LockedRaise || line.special == Generic_Door)
|
||||
{
|
||||
// NES - Locked doors glow from a predefined color to either blue,
|
||||
// yellow, or red.
|
||||
r = gameinfo.currentAutomapColors.LockedColor.rgb.getr();
|
||||
g = gameinfo.currentAutomapColors.LockedColor.rgb.getg();
|
||||
b = gameinfo.currentAutomapColors.LockedColor.rgb.getb();
|
||||
|
||||
if (am_usecustomcolors || am_showlocked)
|
||||
const short lock = line.special == Door_LockedRaise ? line.args[3] : line.args[4];
|
||||
switch (lock)
|
||||
{
|
||||
if (line.args[3] == (zk_blue_card | zk_blue))
|
||||
{
|
||||
rdif = (0 - r) / 30;
|
||||
gdif = (0 - g) / 30;
|
||||
bdif = (255 - b) / 30;
|
||||
}
|
||||
else if (line.args[3] == (zk_yellow_card | zk_yellow))
|
||||
{
|
||||
rdif = (255 - r) / 30;
|
||||
gdif = (255 - g) / 30;
|
||||
bdif = (0 - b) / 30;
|
||||
}
|
||||
else
|
||||
{
|
||||
rdif = (255 - r) / 30;
|
||||
gdif = (0 - g) / 30;
|
||||
bdif = (0 - b) / 30;
|
||||
}
|
||||
|
||||
if (lockglow < 30)
|
||||
{
|
||||
r += static_cast<int>(rdif) * lockglow;
|
||||
g += static_cast<int>(gdif) * lockglow;
|
||||
b += static_cast<int>(bdif) * lockglow;
|
||||
}
|
||||
else if (lockglow < 60)
|
||||
{
|
||||
r += static_cast<int>(rdif) * (60 - lockglow);
|
||||
g += static_cast<int>(gdif) * (60 - lockglow);
|
||||
b += static_cast<int>(bdif) * (60 - lockglow);
|
||||
}
|
||||
case zk_blue_card:
|
||||
case zk_blue:
|
||||
case zk_blue_skull:
|
||||
case zk_bluex:
|
||||
r = doorColors.bluedoor[0];
|
||||
g = doorColors.bluedoor[1];
|
||||
b = doorColors.bluedoor[2];
|
||||
break;
|
||||
case zk_yellow_card:
|
||||
case zk_yellow:
|
||||
case zk_yellow_skull:
|
||||
case zk_yellowx:
|
||||
r = doorColors.yellowdoor[0];
|
||||
g = doorColors.yellowdoor[1];
|
||||
b = doorColors.yellowdoor[2];
|
||||
break;
|
||||
case zk_red_card:
|
||||
case zk_red:
|
||||
case zk_red_skull:
|
||||
case zk_redx:
|
||||
r = doorColors.reddoor[0];
|
||||
g = doorColors.reddoor[1];
|
||||
b = doorColors.reddoor[2];
|
||||
break;
|
||||
case zk_all:
|
||||
case zk_any:
|
||||
case zk_each_color:
|
||||
r = doorColors.multidoor[0];
|
||||
g = doorColors.multidoor[1];
|
||||
b = doorColors.multidoor[2];
|
||||
break;
|
||||
case zk_none:
|
||||
r = gameinfo.currentAutomapColors.CDWallColor.rgb.getr();
|
||||
g = gameinfo.currentAutomapColors.CDWallColor.rgb.getg();
|
||||
b = gameinfo.currentAutomapColors.CDWallColor.rgb.getb();
|
||||
break;
|
||||
default:
|
||||
r = gameinfo.currentAutomapColors.LockedColor.rgb.getr();
|
||||
g = gameinfo.currentAutomapColors.LockedColor.rgb.getg();
|
||||
b = gameinfo.currentAutomapColors.LockedColor.rgb.getb();
|
||||
break;
|
||||
}
|
||||
|
||||
AM_drawMline(&l, AM_BestColor(pal->basecolors, r, g, b));
|
||||
|
|
@ -1408,42 +1516,31 @@ void AM_drawWalls()
|
|||
{
|
||||
// NES - Locked doors glow from a predefined color to either blue,
|
||||
// yellow, or red.
|
||||
r = gameinfo.currentAutomapColors.LockedColor.rgb.getr();
|
||||
g = gameinfo.currentAutomapColors.LockedColor.rgb.getg();
|
||||
b = gameinfo.currentAutomapColors.LockedColor.rgb.getb();
|
||||
|
||||
if (am_usecustomcolors || am_showlocked)
|
||||
if (P_IsCompatibleMultiKeyDoorLine(line.special))
|
||||
{
|
||||
r = doorColors.multidoor[0];
|
||||
g = doorColors.multidoor[1];
|
||||
b = doorColors.multidoor[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (P_IsCompatibleBlueDoorLine(line.special))
|
||||
{
|
||||
rdif = (0 - r) / 30;
|
||||
gdif = (0 - g) / 30;
|
||||
bdif = (255 - b) / 30;
|
||||
r = doorColors.bluedoor[0];
|
||||
g = doorColors.bluedoor[1];
|
||||
b = doorColors.bluedoor[2];
|
||||
}
|
||||
else if (P_IsCompatibleYellowDoorLine(line.special))
|
||||
{
|
||||
rdif = (255 - r) / 30;
|
||||
gdif = (255 - g) / 30;
|
||||
bdif = (0 - b) / 30;
|
||||
r = doorColors.yellowdoor[0];
|
||||
g = doorColors.yellowdoor[1];
|
||||
b = doorColors.yellowdoor[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
rdif = (255 - r) / 30;
|
||||
gdif = (0 - g) / 30;
|
||||
bdif = (0 - b) / 30;
|
||||
}
|
||||
|
||||
if (lockglow < 30)
|
||||
{
|
||||
r += static_cast<int>(rdif) * lockglow;
|
||||
g += static_cast<int>(gdif) * lockglow;
|
||||
b += static_cast<int>(bdif) * lockglow;
|
||||
}
|
||||
else if (lockglow < 60)
|
||||
{
|
||||
r += static_cast<int>(rdif) * (60 - lockglow);
|
||||
g += static_cast<int>(gdif) * (60 - lockglow);
|
||||
b += static_cast<int>(bdif) * (60 - lockglow);
|
||||
r = doorColors.reddoor[0];
|
||||
g = doorColors.reddoor[1];
|
||||
b = doorColors.reddoor[2];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1512,7 +1609,7 @@ void AM_rotatePoint(mpoint_t& pt)
|
|||
pt.y += y;
|
||||
}
|
||||
|
||||
void AM_drawLineCharacter(const std::vector<mline_t>& lineguy, fixed64_t scale,
|
||||
void AM_drawLineCharacter(nonstd::span<const mline_t> lineguy, fixed64_t scale,
|
||||
angle_t angle, am_color_t color, fixed64_t x, fixed64_t y)
|
||||
{
|
||||
for (const auto& mline : lineguy)
|
||||
|
|
@ -1670,7 +1767,7 @@ void AM_drawPlayers()
|
|||
}
|
||||
}
|
||||
|
||||
bool AM_actorIsKey(AActor* t)
|
||||
bool AM_actorIsKey(const AActor* t)
|
||||
{
|
||||
if (t->sprite == SPR_BKEY || t->sprite == SPR_YKEY || t->sprite == SPR_RKEY ||
|
||||
t->sprite == SPR_BSKU || t->sprite == SPR_YSKU || t->sprite == SPR_RSKU)
|
||||
|
|
@ -1681,7 +1778,7 @@ bool AM_actorIsKey(AActor* t)
|
|||
return false;
|
||||
}
|
||||
|
||||
am_color_t AM_getKeyColor(AActor *t)
|
||||
am_color_t AM_getKeyColor(const AActor *t)
|
||||
{
|
||||
am_color_t color = gameinfo.currentAutomapColors.ThingColor;
|
||||
const argb_t* palette = V_GetDefaultPalette()->colors;
|
||||
|
|
@ -1696,123 +1793,177 @@ am_color_t AM_getKeyColor(AActor *t)
|
|||
return color;
|
||||
}
|
||||
|
||||
void AM_drawEasyKeys()
|
||||
void AM_drawEasyKey(const AActor* t)
|
||||
{
|
||||
for (const sector_t& sector : R_GetSectors())
|
||||
if (AM_actorIsKey(t))
|
||||
{
|
||||
AActor* t = sector.thinglist;
|
||||
while (t)
|
||||
mpoint_t p;
|
||||
M_SetVec2Fixed64(&p, FIXED2FIXED64(t->x), FIXED2FIXED64(t->y));
|
||||
|
||||
const am_color_t key_color = AM_getKeyColor(t);
|
||||
|
||||
AM_drawLineCharacter(gameinfo.easyKey, FIXED2FIXED64(t->radius), 0, key_color, p.x, p.y);
|
||||
}
|
||||
}
|
||||
|
||||
void AM_drawHordeBoss(const AActor* t)
|
||||
{
|
||||
OInterpolation& oi = OInterpolation::getInstance();
|
||||
|
||||
if (t->oflags & MFO_BOSSPOOL)
|
||||
{
|
||||
fixed_t thingx;
|
||||
fixed_t thingy;
|
||||
|
||||
if (oi.enabled())
|
||||
{
|
||||
if (AM_actorIsKey(t))
|
||||
{
|
||||
mpoint_t p;
|
||||
M_SetVec2Fixed64(&p, FIXED2FIXED64(t->x), FIXED2FIXED64(t->y));
|
||||
|
||||
const am_color_t key_color = AM_getKeyColor(t);
|
||||
|
||||
AM_drawLineCharacter(gameinfo.easyKey, FIXED2FIXED64(t->radius), 0, key_color, p.x, p.y);
|
||||
}
|
||||
t = t->snext;
|
||||
thingx = t->prevx + FixedMul(t->x - t->prevx, render_lerp_amount);
|
||||
thingy = t->prevy + FixedMul(t->y - t->prevy, render_lerp_amount);
|
||||
}
|
||||
else
|
||||
{
|
||||
thingx = t->x;
|
||||
thingy = t->y;
|
||||
}
|
||||
|
||||
mpoint_t p;
|
||||
M_SetVec2Fixed64(&p, FIXED2FIXED64(thingx), FIXED2FIXED64(thingy));
|
||||
if (am_rotate)
|
||||
AM_rotatePoint(p);
|
||||
|
||||
const palette_t* palette = V_GetDefaultPalette();
|
||||
am_color_t gold = AM_GetColorFromString(palette->colors, "light goldenrod yellow");
|
||||
auto r = gold.rgb.getr();
|
||||
auto g = gold.rgb.getg();
|
||||
auto b = gold.rgb.getb();
|
||||
float rdif = (255 - r) / 30;
|
||||
float gdif = (0 - g) / 30;
|
||||
float bdif = (0 - b) / 30;
|
||||
|
||||
if (bossglow < 20)
|
||||
{
|
||||
r += static_cast<int>(rdif) * bossglow;
|
||||
g += static_cast<int>(gdif) * bossglow;
|
||||
b += static_cast<int>(bdif) * bossglow;
|
||||
}
|
||||
else if (bossglow < 40)
|
||||
{
|
||||
r += static_cast<int>(rdif) * (40 - bossglow);
|
||||
g += static_cast<int>(gdif) * (40 - bossglow);
|
||||
b += static_cast<int>(bdif) * (40 - bossglow);
|
||||
}
|
||||
|
||||
AM_drawLineCharacter(hordeboss_guy, FIXED2FIXED64(t->radius), 0, AM_BestColor(palette->basecolors, r, g, b),
|
||||
p.x, p.y);
|
||||
}
|
||||
}
|
||||
|
||||
void AM_drawCheatThing(const AActor* t)
|
||||
{
|
||||
OInterpolation& oi = OInterpolation::getInstance();
|
||||
|
||||
mpoint_t p;
|
||||
|
||||
fixed_t thingx;
|
||||
fixed_t thingy;
|
||||
|
||||
fixed_t tangle;
|
||||
|
||||
if (oi.enabled())
|
||||
{
|
||||
thingx = t->prevx + FixedMul(t->x - t->prevx, render_lerp_amount);
|
||||
thingy = t->prevy + FixedMul(t->y - t->prevy, render_lerp_amount);
|
||||
tangle = t->prevangle + FixedMul(t->angle - t->prevangle, render_lerp_amount);
|
||||
}
|
||||
else
|
||||
{
|
||||
thingx = t->x;
|
||||
thingy = t->y;
|
||||
tangle = t->angle;
|
||||
}
|
||||
|
||||
M_SetVec2Fixed64(&p, FIXED2FIXED64(thingx), FIXED2FIXED64(thingy));
|
||||
angle_t rotate_angle = 0;
|
||||
angle_t triangle_angle = tangle;
|
||||
|
||||
if (am_rotate)
|
||||
{
|
||||
AM_rotatePoint(p);
|
||||
|
||||
fixed_t conangle;
|
||||
|
||||
if (oi.enabled())
|
||||
{
|
||||
conangle = displayplayer().camera->prevangle +
|
||||
FixedMul(displayplayer().camera->angle -
|
||||
displayplayer().camera->prevangle,
|
||||
render_lerp_amount);
|
||||
}
|
||||
else
|
||||
{
|
||||
conangle = displayplayer().camera->angle;
|
||||
}
|
||||
|
||||
rotate_angle = ANG90 - conangle;
|
||||
triangle_angle += rotate_angle;
|
||||
}
|
||||
|
||||
if (AM_actorIsKey(t))
|
||||
{
|
||||
if (!G_GetCurrentSkill().easy_key)
|
||||
{
|
||||
const am_color_t key_color = AM_getKeyColor(t);
|
||||
|
||||
AM_drawLineCharacter(gameinfo.cheatKey, FIXED2FIXED64(t->radius), 0, key_color, p.x,
|
||||
p.y);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
am_color_t color = gameinfo.currentAutomapColors.ThingColor;
|
||||
|
||||
AM_drawLineCharacter(thintriangle_guy, FIXED2FIXED64(t->radius), triangle_angle, color,
|
||||
p.x, p.y);
|
||||
|
||||
if (t->flags & MF_MISSILE)
|
||||
{
|
||||
color = gameinfo.currentAutomapColors.ThingColor_Projectile;
|
||||
}
|
||||
else if (t->flags & MF_SPECIAL)
|
||||
{
|
||||
if (t->flags & MF_COUNTITEM)
|
||||
color = gameinfo.currentAutomapColors.ThingColor_CountItem;
|
||||
else
|
||||
color = gameinfo.currentAutomapColors.ThingColor_Item;
|
||||
}
|
||||
else if (t->flags & MF_SOLID && t->flags & MF_SHOOTABLE)
|
||||
{
|
||||
if (t->flags & MF_FRIEND)
|
||||
color = gameinfo.currentAutomapColors.ThingColor_Friend;
|
||||
else if (t->flags & MF_COUNTKILL)
|
||||
color = gameinfo.currentAutomapColors.ThingColor_Monster;
|
||||
else
|
||||
color = gameinfo.currentAutomapColors.ThingColor_NoCountMonster;
|
||||
}
|
||||
|
||||
AM_drawLineCharacter(thinrectangle_guy, FIXED2FIXED64(t->radius), rotate_angle, color,
|
||||
p.x, p.y);
|
||||
}
|
||||
}
|
||||
|
||||
void AM_drawThings()
|
||||
{
|
||||
OInterpolation& oi = OInterpolation::getInstance();
|
||||
|
||||
for (const sector_t& sector : R_GetSectors())
|
||||
{
|
||||
AActor* t = sector.thinglist;
|
||||
const AActor* t = sector.thinglist;
|
||||
while (t)
|
||||
{
|
||||
mpoint_t p;
|
||||
|
||||
fixed_t thingx;
|
||||
fixed_t thingy;
|
||||
|
||||
fixed_t tangle;
|
||||
|
||||
if (oi.enabled())
|
||||
{
|
||||
thingx = t->prevx + FixedMul(t->x - t->prevx, render_lerp_amount);
|
||||
thingy = t->prevy + FixedMul(t->y - t->prevy, render_lerp_amount);
|
||||
tangle = t->prevangle + FixedMul(t->angle - t->prevangle, render_lerp_amount);
|
||||
}
|
||||
else
|
||||
{
|
||||
thingx = t->x;
|
||||
thingy = t->y;
|
||||
tangle = t->angle;
|
||||
}
|
||||
|
||||
M_SetVec2Fixed64(&p, FIXED2FIXED64(thingx), FIXED2FIXED64(thingy));
|
||||
angle_t rotate_angle = 0;
|
||||
angle_t triangle_angle = tangle;
|
||||
|
||||
if (am_rotate)
|
||||
{
|
||||
AM_rotatePoint(p);
|
||||
|
||||
fixed_t conangle;
|
||||
|
||||
if (oi.enabled())
|
||||
{
|
||||
conangle = displayplayer().camera->prevangle +
|
||||
FixedMul(displayplayer().camera->angle -
|
||||
displayplayer().camera->prevangle,
|
||||
render_lerp_amount);
|
||||
}
|
||||
else
|
||||
{
|
||||
conangle = displayplayer().camera->angle;
|
||||
}
|
||||
|
||||
rotate_angle = ANG90 - conangle;
|
||||
triangle_angle += rotate_angle;
|
||||
}
|
||||
|
||||
if (AM_actorIsKey(t))
|
||||
{
|
||||
if (!G_GetCurrentSkill().easy_key)
|
||||
{
|
||||
const am_color_t key_color = AM_getKeyColor(t);
|
||||
|
||||
AM_drawLineCharacter(gameinfo.cheatKey, FIXED2FIXED64(t->radius), 0, key_color, p.x,
|
||||
p.y);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
am_color_t color = gameinfo.currentAutomapColors.ThingColor;
|
||||
|
||||
AM_drawLineCharacter(thintriangle_guy, FIXED2FIXED64(t->radius), triangle_angle, color,
|
||||
p.x, p.y);
|
||||
|
||||
if (t->flags & MF_MISSILE)
|
||||
{
|
||||
color = gameinfo.currentAutomapColors.ThingColor_Projectile;
|
||||
}
|
||||
else if (t->flags & MF_SPECIAL)
|
||||
{
|
||||
if (t->flags & MF_COUNTITEM)
|
||||
color = gameinfo.currentAutomapColors.ThingColor_CountItem;
|
||||
else
|
||||
color = gameinfo.currentAutomapColors.ThingColor_Item;
|
||||
}
|
||||
else if (t->flags & MF_SOLID && t->flags & MF_SHOOTABLE)
|
||||
{
|
||||
if (t->flags & MF_FRIEND)
|
||||
color = gameinfo.currentAutomapColors.ThingColor_Friend;
|
||||
else if (t->flags & MF_COUNTKILL)
|
||||
color = gameinfo.currentAutomapColors.ThingColor_Monster;
|
||||
else
|
||||
color = gameinfo.currentAutomapColors.ThingColor_NoCountMonster;
|
||||
}
|
||||
|
||||
AM_drawLineCharacter(thinrectangle_guy, FIXED2FIXED64(t->radius), rotate_angle, color,
|
||||
p.x, p.y);
|
||||
}
|
||||
if (G_IsHordeMode())
|
||||
AM_drawHordeBoss(t);
|
||||
if (G_GetCurrentSkill().easy_key)
|
||||
AM_drawEasyKey(t);
|
||||
if (am_cheating == 2)
|
||||
AM_drawCheatThing(t);
|
||||
t = t->snext;
|
||||
}
|
||||
}
|
||||
|
|
@ -1922,9 +2073,7 @@ void AM_Drawer()
|
|||
|
||||
AM_drawWalls();
|
||||
AM_drawPlayers();
|
||||
if (G_GetCurrentSkill().easy_key)
|
||||
AM_drawEasyKeys();
|
||||
if (am_cheating == 2)
|
||||
if (G_IsHordeMode() || G_GetCurrentSkill().easy_key || (am_cheating == 2))
|
||||
AM_drawThings();
|
||||
|
||||
if (!(viewactive && am_overlay < 2))
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ OBinding DefaultBindings[] =
|
|||
{"s", "+back"},
|
||||
{"a", "+moveleft"},
|
||||
{"d", "+moveright"},
|
||||
#ifdef _XBOX
|
||||
#ifdef GCONSOLE
|
||||
{"hat1right", "messagemode2"},
|
||||
{"hat1left", "spynext"},
|
||||
{"hat1up", "messagemode"},
|
||||
|
|
@ -579,8 +579,8 @@ END_COMMAND(bind)
|
|||
BEGIN_COMMAND(unbind)
|
||||
{
|
||||
if (argc < 2) {
|
||||
Printf(PRINT_WARNING, "Unbinds a key. \"all\" unbinds every key.\n");
|
||||
Printf(PRINT_WARNING, "Usage: unbind <key>\n");
|
||||
PrintFmt(PRINT_WARNING, "Unbinds a key. \"all\" unbinds every key.\n");
|
||||
PrintFmt(PRINT_WARNING, "Usage: unbind <key>\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -603,8 +603,8 @@ BEGIN_COMMAND(undoublebind)
|
|||
{
|
||||
if (argc < 2)
|
||||
{
|
||||
Printf(PRINT_WARNING, "Unbinds a doublekey. \"all\" unbinds every doublebind key.\n");
|
||||
Printf(PRINT_WARNING, "Usage: undoublebind <key>\n");
|
||||
PrintFmt(PRINT_WARNING, "Unbinds a doublekey. \"all\" unbinds every doublebind key.\n");
|
||||
PrintFmt(PRINT_WARNING, "Usage: undoublebind <key>\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -626,8 +626,8 @@ BEGIN_COMMAND(unambind)
|
|||
{
|
||||
if (argc < 2)
|
||||
{
|
||||
Printf(PRINT_WARNING, "Unbinds an automap key. \"all\" unbinds every automap key.\n");
|
||||
Printf(PRINT_WARNING, "Usage: unambind <key>\n");
|
||||
PrintFmt(PRINT_WARNING, "Unbinds an automap key. \"all\" unbinds every automap key.\n");
|
||||
PrintFmt(PRINT_WARNING, "Usage: unambind <key>\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -652,9 +652,9 @@ BEGIN_COMMAND(unnetdemobind)
|
|||
{
|
||||
if (argc < 2)
|
||||
{
|
||||
Printf(PRINT_WARNING,
|
||||
"Unbinds a netdemo key. \"all\" unbinds every existing netdemo key.\n");
|
||||
Printf(PRINT_WARNING, "Usage: unnetdemobind <key>\n");
|
||||
PrintFmt(PRINT_WARNING,
|
||||
"Unbinds a netdemo key. \"all\" unbinds every existing netdemo key.\n");
|
||||
PrintFmt(PRINT_WARNING, "Usage: unnetdemobind <key>\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -638,7 +638,7 @@ void ConsoleHistory::movePositionDown()
|
|||
void ConsoleHistory::dump()
|
||||
{
|
||||
for (const auto& it : history)
|
||||
Printf(PRINT_HIGH, " %s\n", it);
|
||||
PrintFmt(PRINT_HIGH, " {}\n", it);
|
||||
}
|
||||
|
||||
class ConsoleCompletions
|
||||
|
|
@ -1163,6 +1163,10 @@ void C_AddNotifyString(int printlevel, const char* color_code, const char* sourc
|
|||
if (printlevel == PRINT_FILTERCHAT)
|
||||
return;
|
||||
|
||||
// Do not display filtered normal messages
|
||||
if (printlevel == PRINT_FILTERHIGH)
|
||||
return;
|
||||
|
||||
const int width = I_GetSurfaceWidth() / V_TextScaleXAmount();
|
||||
|
||||
if (addtype == APPENDLINE && NotifyStrings[NUMNOTIFIES-1].printlevel == printlevel)
|
||||
|
|
@ -1211,15 +1215,14 @@ void C_AddNotifyString(int printlevel, const char* color_code, const char* sourc
|
|||
// Prints the given string to stdout, stripping away any color markup
|
||||
// escape codes.
|
||||
//
|
||||
static size_t C_PrintStringStdOut(const char* str)
|
||||
static size_t C_PrintStringStdOut(std::string str)
|
||||
{
|
||||
std::string sanitized_str(str);
|
||||
StripColorCodes(sanitized_str);
|
||||
StripColorCodes(str);
|
||||
|
||||
fmt::print("{}", sanitized_str);
|
||||
fmt::print("{}", str);
|
||||
fflush(stdout);
|
||||
|
||||
return sanitized_str.length();
|
||||
return str.length();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1244,6 +1247,9 @@ static size_t C_PrintString(int printlevel, const char* color_code, const char*
|
|||
if (printlevel == PRINT_FILTERCHAT)
|
||||
printlevel = PRINT_CHAT;
|
||||
|
||||
if (printlevel == PRINT_FILTERHIGH)
|
||||
printlevel = PRINT_HIGH;
|
||||
|
||||
const char* line_start = outline;
|
||||
const char* line_end = line_start;
|
||||
|
||||
|
|
@ -1344,7 +1350,7 @@ size_t C_BasePrint(const int printlevel, const char* color_code, const std::stri
|
|||
}
|
||||
|
||||
if (print_stdout && gamestate != GS_FORCEWIPE)
|
||||
C_PrintStringStdOut(newStr.c_str());
|
||||
C_PrintStringStdOut(newStr);
|
||||
|
||||
if (!con_coloredmessages)
|
||||
StripColorCodes(newStr);
|
||||
|
|
@ -2008,7 +2014,7 @@ static bool C_HandleKey(const event_t* ev)
|
|||
History.addString(text);
|
||||
History.resetPosition();
|
||||
|
||||
Printf(127, "]%s\n", text);
|
||||
PrintFmt(127, "]{}\n", text);
|
||||
AddCommandString(text);
|
||||
CmdLine.clear();
|
||||
}
|
||||
|
|
@ -2139,7 +2145,7 @@ static bool C_HandleKey(const event_t* ev)
|
|||
History.addString(CmdLine.text);
|
||||
History.resetPosition();
|
||||
|
||||
Printf(127, "]%s\n", CmdLine.text.c_str());
|
||||
PrintFmt(127, "]{}\n", CmdLine.text.c_str());
|
||||
AddCommandString(CmdLine.text.c_str());
|
||||
CmdLine.clear();
|
||||
CmdCompletions.clear();
|
||||
|
|
@ -2242,7 +2248,7 @@ BEGIN_COMMAND(echo)
|
|||
if (argc > 1)
|
||||
{
|
||||
const std::string str = C_ArgCombine(argc - 1, (const char **)(argv + 1));
|
||||
Printf(PRINT_HIGH, "%s\n", str.c_str());
|
||||
PrintFmt(PRINT_HIGH, "{}\n", str);
|
||||
}
|
||||
}
|
||||
END_COMMAND(echo)
|
||||
|
|
@ -2285,7 +2291,7 @@ void C_MidPrint(const char *msg, player_t *p, int msgtime)
|
|||
|
||||
char *newmsg = strdup(str.c_str());
|
||||
|
||||
Printf(PRINT_HIGH, "%s\n", newmsg);
|
||||
PrintFmt(PRINT_HIGH, "{}\n", newmsg);
|
||||
midprinting = false;
|
||||
|
||||
if ( (MidMsg = V_BreakLines(I_GetSurfaceWidth() / V_TextScaleXAmount(), (byte *)newmsg)) )
|
||||
|
|
|
|||
|
|
@ -315,7 +315,7 @@ CVAR (joy_turnaxis, "2", "", CVARTYPE_FLOAT, CVAR_CLIENTARCHIVE | CVAR_NOENABLED
|
|||
CVAR (joy_lookaxis, "3", "", CVARTYPE_FLOAT, CVAR_CLIENTARCHIVE | CVAR_NOENABLEDISABLE)
|
||||
CVAR (joy_sensitivity, "10.0", "", CVARTYPE_FLOAT, CVAR_CLIENTARCHIVE | CVAR_NOENABLEDISABLE)
|
||||
CVAR (joy_fastsensitivity, "15.0", "", CVARTYPE_FLOAT, CVAR_CLIENTARCHIVE | CVAR_NOENABLEDISABLE)
|
||||
CVAR (joy_freelook, "0", "", CVARTYPE_FLOAT, CVAR_CLIENTARCHIVE)
|
||||
CVAR_FUNC_DECL (joy_freelook, "0", "Look up or down with the joystick", CVARTYPE_BOOL, CVAR_CLIENTARCHIVE)
|
||||
CVAR (joy_invert, "0", "", CVARTYPE_FLOAT, CVAR_CLIENTARCHIVE)
|
||||
|
||||
CVAR_RANGE (joy_deadzone, "0.20", "", CVARTYPE_FLOAT, CVAR_CLIENTARCHIVE | CVAR_NOENABLEDISABLE, 0.0f, 0.75f)
|
||||
|
|
@ -386,8 +386,8 @@ CVAR( cl_forcedownload, "0", "Forces the client to download the last WAD file
|
|||
// Client Preferences
|
||||
// ------------------
|
||||
|
||||
#ifdef _XBOX // Because Xbox players may be unable to communicate for now -- Hyper_Eye
|
||||
CVAR_FUNC_DECL( cl_name, "Xbox Player", "",
|
||||
#ifdef GCONSOLE // Because Xbox players may be unable to communicate for now -- Hyper_Eye
|
||||
CVAR_FUNC_DECL( cl_name, "Console Player", "",
|
||||
CVARTYPE_STRING, CVAR_USERINFO | CVAR_CLIENTARCHIVE | CVAR_NOENABLEDISABLE)
|
||||
#else
|
||||
CVAR_FUNC_DECL( cl_name, "Player", "",
|
||||
|
|
@ -424,6 +424,9 @@ CVAR(in_autosr50, "1", "+strafe activates automatic SR50", CVARTYPE_BOOL,
|
|||
CVAR( cl_showspawns, "0", "Show spawn points as particle fountains",
|
||||
CVARTYPE_BOOL, CVAR_CLIENTARCHIVE | CVAR_LATCH)
|
||||
|
||||
CVAR_FUNC_DECL( cl_showfriends, "0", "Show an indicator on friendly monsters.",
|
||||
CVARTYPE_BOOL, CVAR_CLIENTARCHIVE)
|
||||
|
||||
// Netdemo Preferences
|
||||
// --------------------
|
||||
|
||||
|
|
@ -598,7 +601,7 @@ CVAR_RANGE(hud_extendedinfo, "0",
|
|||
"Show kills, items, and secrets:\n// 0: Off\n// 1: DIGFONT\n// 2: SMALLFONT\n// 3: DIGFONT, vertical arrangement\n// 4: SMALLFONT, vertical arrangement",
|
||||
CVARTYPE_INT, CVAR_CLIENTARCHIVE | CVAR_NOENABLEDISABLE, 0.0, 4.0)
|
||||
|
||||
#ifdef _XBOX
|
||||
#ifdef GCONSOLE
|
||||
CVAR (chatmacro0, "Hi.", "", CVARTYPE_STRING, CVAR_CLIENTARCHIVE | CVAR_NOENABLEDISABLE) // A
|
||||
CVAR (chatmacro1, "I'm ready to kick butt!", "", CVARTYPE_STRING, CVAR_CLIENTARCHIVE | CVAR_NOENABLEDISABLE) // B
|
||||
CVAR (chatmacro2, "Help!", "", CVARTYPE_STRING, CVAR_CLIENTARCHIVE | CVAR_NOENABLEDISABLE) // X
|
||||
|
|
@ -608,7 +611,7 @@ CVAR (chatmacro5, "Yes", "", CVARTYPE_STRING, CVAR_CLIENTARCHIVE | CVAR_NOENABLE
|
|||
CVAR (chatmacro6, "I'll take care of it.", "", CVARTYPE_STRING, CVAR_CLIENTARCHIVE | CVAR_NOENABLEDISABLE) // Left Trigger
|
||||
CVAR (chatmacro7, "Come here!", "", CVARTYPE_STRING, CVAR_CLIENTARCHIVE | CVAR_NOENABLEDISABLE) // Right Trigger
|
||||
CVAR (chatmacro8, "Thanks for the game. Bye.", "", CVARTYPE_STRING, CVAR_CLIENTARCHIVE | CVAR_NOENABLEDISABLE) // Start
|
||||
CVAR (chatmacro9, "I am on Xbox and can only use chat macros.", "", CVARTYPE_STRING, CVAR_CLIENTARCHIVE | CVAR_NOENABLEDISABLE) // Back
|
||||
CVAR (chatmacro9, "I am on a game console and can only use chat macros.", "", CVARTYPE_STRING, CVAR_CLIENTARCHIVE | CVAR_NOENABLEDISABLE) // Back
|
||||
#else
|
||||
// GhostlyDeath <November 2, 2008> -- someone had the order wrong (0-9!)
|
||||
CVAR (chatmacro1, "I'm ready to kick butt!", "", CVARTYPE_STRING, CVAR_CLIENTARCHIVE | CVAR_NOENABLEDISABLE)
|
||||
|
|
@ -640,6 +643,8 @@ CVAR_RANGE( snd_voxtype, "2", "Voice announcer type",
|
|||
|
||||
CVAR( snd_gamesfx, "1", "Game SFX", CVARTYPE_BOOL, CVAR_CLIENTARCHIVE)
|
||||
|
||||
CVAR( snd_votesfx, "1", "Enable vote UI sounds", CVARTYPE_BOOL, CVAR_CLIENTARCHIVE)
|
||||
|
||||
CVAR( snd_crossover, "0", "Stereo switch", CVARTYPE_BOOL, CVAR_CLIENTARCHIVE)
|
||||
|
||||
CVAR_RANGE_FUNC_DECL(snd_samplerate, "44100", "Audio samplerate",
|
||||
|
|
@ -678,7 +683,7 @@ static char *C_GetDefaultMusicSystem()
|
|||
defaultmusicsystem = MS_AUDIOUNIT;
|
||||
#endif
|
||||
|
||||
#if defined _WIN32 && !defined _XBOX
|
||||
#if defined _WIN32
|
||||
defaultmusicsystem = MS_PORTMIDI;
|
||||
#endif
|
||||
|
||||
|
|
@ -739,6 +744,12 @@ CVAR( r_flashhom, "0", "Draws flashing colors where there is HOM",
|
|||
CVAR( r_drawflat, "0", "Disables all texturing of walls, floors and ceilings",
|
||||
CVARTYPE_BOOL, CVAR_NULL)
|
||||
|
||||
CVAR( r_clipmaskedspecial, "1", "Vertically clip masked midtextures when surrounding sectors have differing specials (mimics Hexen and DSDA-Doom behavior)",
|
||||
CVARTYPE_BOOL, CVAR_NULL)
|
||||
|
||||
CVAR( r_thingsectorlight, "0", "MObjs are lit according to the average of the transfered light levels (mimics MBF behavior)",
|
||||
CVARTYPE_BOOL, CVAR_NULL)
|
||||
|
||||
#if 0
|
||||
CVAR( r_drawhitboxes, "0", "Draws a box outlining every actor's hitboxes",
|
||||
CVARTYPE_BOOL, CVAR_NULL)
|
||||
|
|
@ -771,13 +782,8 @@ CVAR_FUNC_DECL( r_forceteamcolor, "0", "Changes the color of all teammates to th
|
|||
CVAR_FUNC_DECL( r_teamcolor, "40 cf 00", "",
|
||||
CVARTYPE_STRING, CVAR_CLIENTARCHIVE | CVAR_NOENABLEDISABLE)
|
||||
|
||||
#ifdef _XBOX // The burn wipe works better in 720p
|
||||
CVAR_RANGE( r_wipetype, "2", "",
|
||||
CVARTYPE_BYTE, CVAR_CLIENTARCHIVE | CVAR_NOENABLEDISABLE, 0.0f, 3.0f)
|
||||
#else
|
||||
CVAR_RANGE( r_wipetype, "1", "",
|
||||
CVARTYPE_BYTE, CVAR_CLIENTARCHIVE | CVAR_NOENABLEDISABLE, 0.0f, 3.0f)
|
||||
#endif
|
||||
|
||||
CVAR_RANGE( r_showendoom, "0", "Display the ENDDOOM text after quitting",
|
||||
CVARTYPE_BYTE, CVAR_CLIENTARCHIVE | CVAR_NOENABLEDISABLE, 0.0f, 2.0f) // [ML] 1/5/10: Add endoom support
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ void NetDemo::cleanUp()
|
|||
void NetDemo::error(const std::string &message)
|
||||
{
|
||||
cleanUp();
|
||||
Printf(PRINT_HIGH, "%s\n", message);
|
||||
PrintFmt(PRINT_HIGH, "{}\n", message);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -175,7 +175,7 @@ void NetDemo::fatalError(const std::string &message)
|
|||
gameaction = ga_nothing;
|
||||
gamestate = GS_FULLCONSOLE;
|
||||
|
||||
Printf(PRINT_HIGH, "%s\n", message);
|
||||
PrintFmt(PRINT_HIGH, "{}\n", message);
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -455,7 +455,7 @@ bool NetDemo::startRecording(const std::string &filename)
|
|||
|
||||
state = NetDemo::st_recording;
|
||||
header.starting_gametic = gametic;
|
||||
Printf(PRINT_HIGH, "Recording netdemo %s.\n", filename);
|
||||
PrintFmt(PRINT_HIGH, "Recording netdemo {}.\n", filename);
|
||||
|
||||
if (connected)
|
||||
{
|
||||
|
|
@ -584,7 +584,7 @@ bool NetDemo::startPlaying(const std::string &filename)
|
|||
fseek(demofp, NetDemo::HEADER_SIZE, SEEK_SET);
|
||||
state = NetDemo::st_playing;
|
||||
|
||||
Printf(PRINT_HIGH, "Playing netdemo %s.\n", filename);
|
||||
PrintFmt(PRINT_HIGH, "Playing netdemo {}.\n", filename);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -683,7 +683,7 @@ bool NetDemo::stopRecording()
|
|||
fclose(demofp);
|
||||
demofp = NULL;
|
||||
|
||||
Printf(PRINT_HIGH, "Demo recording has stopped.\n");
|
||||
PrintFmt(PRINT_HIGH, "Demo recording has stopped.\n");
|
||||
reset();
|
||||
return true;
|
||||
}
|
||||
|
|
@ -707,7 +707,7 @@ bool NetDemo::stopPlaying()
|
|||
demofp = NULL;
|
||||
}
|
||||
|
||||
Printf(PRINT_HIGH, "Demo has ended.\n");
|
||||
PrintFmt(PRINT_HIGH, "Demo has ended.\n");
|
||||
reset();
|
||||
gameaction = ga_fullconsole;
|
||||
gamestate = GS_FULLCONSOLE;
|
||||
|
|
@ -1480,7 +1480,7 @@ void NetDemo::writeSnapshotData(std::vector<byte>& buf)
|
|||
arc << ACS_WorldVars[i];
|
||||
ACSWorldGlobalArray worldarr = ACS_WorldArrays[i];
|
||||
arc << worldarr.size();
|
||||
for (const auto [key, val] : worldarr)
|
||||
for (const auto& [key, val] : worldarr)
|
||||
{
|
||||
arc << key;
|
||||
arc << val;
|
||||
|
|
@ -1493,7 +1493,7 @@ void NetDemo::writeSnapshotData(std::vector<byte>& buf)
|
|||
arc << ACS_GlobalVars[i];
|
||||
ACSWorldGlobalArray globalarr = ACS_GlobalArrays[i];
|
||||
arc << globalarr.size();
|
||||
for (const auto [key, val] : globalarr)
|
||||
for (const auto& [key, val] : globalarr)
|
||||
{
|
||||
arc << key;
|
||||
arc << val;
|
||||
|
|
|
|||
|
|
@ -96,8 +96,8 @@ static struct DownloadState
|
|||
*/
|
||||
void CL_DownloadInit()
|
||||
{
|
||||
Printf("CL_DownloadInit: Init HTTP subsystem (libcurl %d.%d.%d)\n",
|
||||
LIBCURL_VERSION_MAJOR, LIBCURL_VERSION_MINOR, LIBCURL_VERSION_PATCH);
|
||||
PrintFmt("CL_DownloadInit: Init HTTP subsystem (libcurl {}.{}.{})\n",
|
||||
LIBCURL_VERSION_MAJOR, LIBCURL_VERSION_MINOR, LIBCURL_VERSION_PATCH);
|
||||
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
|
||||
|
|
@ -142,7 +142,7 @@ bool CL_StartDownload(const Websites& urls, const OWantFile& filename, unsigned
|
|||
{
|
||||
if (::dlstate.state != STATE_READY)
|
||||
{
|
||||
Printf(PRINT_WARNING, "Can't start download when download state is not ready.\n");
|
||||
PrintFmt(PRINT_WARNING, "Can't start download when download state is not ready.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -170,24 +170,24 @@ bool CL_StartDownload(const Websites& urls, const OWantFile& filename, unsigned
|
|||
|
||||
if (checkurls.empty())
|
||||
{
|
||||
Printf(PRINT_WARNING, "No sites were provided for download.\n");
|
||||
PrintFmt(PRINT_WARNING, "No sites were provided for download.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (W_IsFilenameCommercialWAD(filename.getBasename()))
|
||||
{
|
||||
Printf(PRINT_WARNING, "%s is a commercial WAD file and cannot be downloaded by Odamex.\n"
|
||||
"A copy can be obtained through purchasing DOOM + DOOM II from Steam or GOG.\n",
|
||||
filename.getBasename());
|
||||
PrintFmt(PRINT_WARNING, "{} is a commercial WAD file and cannot be downloaded by Odamex.\n"
|
||||
"A copy can be obtained through purchasing DOOM + DOOM II from Steam or GOG.\n",
|
||||
filename.getBasename());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (W_IsFilehashCommercialWAD(filename.getWantedMD5()))
|
||||
{
|
||||
const fileIdentifier_t* id = W_GameInfo(filename.getWantedMD5());
|
||||
Printf(PRINT_WARNING, "%s is a renamed commercial wad file containing %s.\n"
|
||||
"A copy of %s can be obtained through purchasing DOOM + DOOM II from Steam or GOG.\n",
|
||||
filename.getBasename(), id->mNiceName, id->mFilename);
|
||||
PrintFmt(PRINT_WARNING, "{} is a renamed commercial wad file containing {}.\n"
|
||||
"A copy of {} can be obtained through purchasing DOOM + DOOM II from Steam or GOG.\n",
|
||||
filename.getBasename(), id->mNiceName, id->mFilename);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -229,7 +229,7 @@ static void CheckDone(const OTransferInfo& info)
|
|||
::dlstate.state = STATE_DOWNLOADING;
|
||||
::dlstate.url = info.url;
|
||||
|
||||
Printf("Found file at %s.\n", info.url);
|
||||
PrintFmt("Found file at {}.\n", info.url);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -248,9 +248,9 @@ static void CheckError(const char* msg)
|
|||
// Three strikes and you're out.
|
||||
if (::dlstate.checkfails >= 3)
|
||||
{
|
||||
Printf(PRINT_WARNING, "Could not find %s at %s (%s)...\n",
|
||||
::dlstate.checkfilename,
|
||||
::dlstate.checkurls.at(::dlstate.checkurlidx), msg);
|
||||
PrintFmt(PRINT_WARNING, "Could not find {} at {} ({})...\n",
|
||||
::dlstate.checkfilename,
|
||||
::dlstate.checkurls.at(::dlstate.checkurlidx), msg);
|
||||
|
||||
// Check the next base URL.
|
||||
::dlstate.checkfails = 0;
|
||||
|
|
@ -258,8 +258,8 @@ static void CheckError(const char* msg)
|
|||
if (::dlstate.checkurlidx >= ::dlstate.checkurls.size())
|
||||
{
|
||||
// No more base URL's to check - our luck has run out.
|
||||
Printf(PRINT_WARNING, "Download failed, no sites have %s for download.\n",
|
||||
::dlstate.checkfilename);
|
||||
PrintFmt(PRINT_WARNING, "Download failed, no sites have {} for download.\n",
|
||||
::dlstate.checkfilename);
|
||||
::dlstate.Ready();
|
||||
}
|
||||
}
|
||||
|
|
@ -303,7 +303,7 @@ static void TickCheck()
|
|||
}
|
||||
|
||||
::dlstate.state = STATE_CHECKING;
|
||||
Printf("Checking for file at %s...\n", fullurl);
|
||||
PrintFmt("Checking for file at {}...\n", fullurl);
|
||||
}
|
||||
|
||||
// Tick the checker - the done/error callbacks mutate the state appropriately,
|
||||
|
|
@ -350,7 +350,7 @@ static void TransferDone(const OTransferInfo& info)
|
|||
{
|
||||
std::string bytes;
|
||||
StrFormatBytes(bytes, info.speed);
|
||||
Printf("Download completed at %s/s.\n", bytes);
|
||||
PrintFmt("Download completed at {}/s.\n", bytes);
|
||||
|
||||
if (::dlstate.flags & DL_RECONNECT)
|
||||
CL_Reconnect();
|
||||
|
|
@ -358,7 +358,7 @@ static void TransferDone(const OTransferInfo& info)
|
|||
|
||||
static void TransferError(const char* msg)
|
||||
{
|
||||
Printf(PRINT_WARNING, "Download error (%s).\n", msg);
|
||||
PrintFmt(PRINT_WARNING, "Download error ({}).\n", msg);
|
||||
}
|
||||
|
||||
static void TickDownload()
|
||||
|
|
@ -392,7 +392,7 @@ static void TickDownload()
|
|||
break;
|
||||
|
||||
// Otherwise, set the destination to the empty string and try again.
|
||||
Printf(PRINT_WARNING, "Could not save to %s (%s)\n", dest, strerror(err));
|
||||
PrintFmt(PRINT_WARNING, "Could not save to {} ({})\n", dest, strerror(err));
|
||||
dest = "";
|
||||
}
|
||||
|
||||
|
|
@ -415,7 +415,7 @@ static void TickDownload()
|
|||
}
|
||||
|
||||
::dlstate.state = STATE_DOWNLOADING;
|
||||
Printf("Downloading %s...\n", ::dlstate.url);
|
||||
PrintFmt("Downloading {}...\n", ::dlstate.url);
|
||||
}
|
||||
|
||||
if (!::dlstate.transfer->tick())
|
||||
|
|
@ -429,8 +429,8 @@ static void TickDownload()
|
|||
if (::dlstate.checkurlidx >= ::dlstate.checkurls.size())
|
||||
{
|
||||
// No more base URL's to check - our luck has run out.
|
||||
Printf(PRINT_WARNING, "Download failed, no sites have %s for download.\n",
|
||||
::dlstate.checkfilename);
|
||||
PrintFmt(PRINT_WARNING, "Download failed, no sites have {} for download.\n",
|
||||
::dlstate.checkfilename);
|
||||
::dlstate.Ready();
|
||||
}
|
||||
}
|
||||
|
|
@ -505,12 +505,12 @@ EXTERN_CVAR(cl_downloadsites)
|
|||
|
||||
static void DownloadHelp()
|
||||
{
|
||||
Printf("download - Downloads a WAD file\n\n"
|
||||
"Usage:\n"
|
||||
" ] download get <FILENAME>\n"
|
||||
" Downloads the file FILENAME from your configured download sites.\n"
|
||||
" ] download stop\n"
|
||||
" Stop an in-progress download.");
|
||||
PrintFmt("download - Downloads a WAD file\n\n"
|
||||
"Usage:\n"
|
||||
" ] download get <FILENAME>\n"
|
||||
" Downloads the file FILENAME from your configured download sites.\n"
|
||||
" ] download stop\n"
|
||||
" Stop an in-progress download.");
|
||||
}
|
||||
|
||||
BEGIN_COMMAND(download)
|
||||
|
|
@ -538,7 +538,7 @@ BEGIN_COMMAND(download)
|
|||
if (stricmp(argv[1], "stop") == 0)
|
||||
{
|
||||
if (CL_StopDownload())
|
||||
Printf(PRINT_WARNING, "Download cancelled.\n");
|
||||
PrintFmt(PRINT_WARNING, "Download cancelled.\n");
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,10 +65,7 @@
|
|||
#include "g_spawninv.h"
|
||||
#include "g_gametype.h"
|
||||
#include "p_horde.h"
|
||||
|
||||
#ifdef _XBOX
|
||||
#include "i_xbox.h"
|
||||
#endif
|
||||
#include "g_musinfo.h"
|
||||
|
||||
#include <math.h> // for pow()
|
||||
|
||||
|
|
@ -183,6 +180,13 @@ CVAR_FUNC_IMPL(cl_mouselook)
|
|||
R_InitSkyMap ();
|
||||
}
|
||||
|
||||
CVAR_FUNC_IMPL(joy_freelook)
|
||||
{
|
||||
// [RV] - Center view, Update Skies
|
||||
AddCommandString("centerview");
|
||||
R_InitSkyMap();
|
||||
}
|
||||
|
||||
char demoname[256];
|
||||
|
||||
extern bool simulated_connection;
|
||||
|
|
@ -290,8 +294,8 @@ BEGIN_COMMAND (turnspeeds)
|
|||
{
|
||||
if (argc == 1)
|
||||
{
|
||||
Printf (PRINT_HIGH, "Current turn speeds: %d %d %d\n",
|
||||
angleturn[0], angleturn[1], angleturn[2]);
|
||||
PrintFmt(PRINT_HIGH, "Current turn speeds: {} {} {}\n",
|
||||
angleturn[0], angleturn[1], angleturn[2]);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -335,8 +339,8 @@ BEGIN_COMMAND (togglerun)
|
|||
{
|
||||
cl_run.Set(!cl_run.value());
|
||||
|
||||
Printf(PRINT_HIGH, "Always run %s\n",
|
||||
cl_run.value() ? "on" : "off");
|
||||
PrintFmt(PRINT_HIGH, "Always run {}\n",
|
||||
cl_run.value() ? "on" : "off");
|
||||
}
|
||||
END_COMMAND (togglerun)
|
||||
|
||||
|
|
@ -826,7 +830,7 @@ int outrate;
|
|||
|
||||
BEGIN_COMMAND(netstat)
|
||||
{
|
||||
Printf (PRINT_HIGH, "in = %d out = %d \n", netin, netout);
|
||||
PrintFmt(PRINT_HIGH, "in = {} out = {} \n", netin, netout);
|
||||
}
|
||||
END_COMMAND(netstat)
|
||||
|
||||
|
|
@ -1058,8 +1062,8 @@ void G_Ticker (void)
|
|||
MSG_WriteMarker(&net_buffer, clc_disconnect);
|
||||
NET_SendPacket(net_buffer, serveraddr);
|
||||
|
||||
Printf(PRINT_WARNING,
|
||||
"Got unknown challenge %d while connecting, disconnecting.\n", type);
|
||||
PrintFmt(PRINT_WARNING,
|
||||
"Got unknown challenge {} while connecting, disconnecting.\n", type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1557,7 +1561,7 @@ void G_DoLoadGame (void)
|
|||
FILE *stdfile = fopen (savename.c_str(), "rb");
|
||||
if (stdfile == NULL)
|
||||
{
|
||||
Printf (PRINT_HIGH, "Could not read savegame '%s'\n", savename);
|
||||
PrintFmt(PRINT_HIGH, "Could not read savegame '{}'\n", savename);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1565,13 +1569,13 @@ void G_DoLoadGame (void)
|
|||
size_t readlen = fread (text, 16, 1, stdfile);
|
||||
if (readlen < 1)
|
||||
{
|
||||
Printf (PRINT_HIGH, "Failed to read savegame '%s'\n", savename);
|
||||
PrintFmt(PRINT_HIGH, "Failed to read savegame '{}'\n", savename);
|
||||
fclose(stdfile);
|
||||
return;
|
||||
}
|
||||
if (strncmp (text, SAVESIG, 16))
|
||||
{
|
||||
Printf (PRINT_HIGH, "Savegame '%s' is from a different version\n", savename);
|
||||
PrintFmt(PRINT_HIGH, "Savegame '{}' is from a different version\n", savename);
|
||||
|
||||
fclose(stdfile);
|
||||
|
||||
|
|
@ -1580,7 +1584,7 @@ void G_DoLoadGame (void)
|
|||
readlen = fread (text, 8, 1, stdfile);
|
||||
if (readlen < 1)
|
||||
{
|
||||
Printf (PRINT_HIGH, "Failed to read savegame '%s'\n", savename);
|
||||
PrintFmt(PRINT_HIGH, "Failed to read savegame '{}'\n", savename);
|
||||
fclose(stdfile);
|
||||
return;
|
||||
}
|
||||
|
|
@ -1591,9 +1595,9 @@ void G_DoLoadGame (void)
|
|||
FLZOFile savefile (stdfile, FFile::EReading);
|
||||
|
||||
if (!savefile.IsOpen ())
|
||||
I_Error ("Savegame '{}' is corrupt\n", savename);
|
||||
I_Error("Savegame '{}' is corrupt\n", savename);
|
||||
|
||||
Printf (PRINT_HIGH, "Loading savegame '%s'...\n", savename);
|
||||
PrintFmt(PRINT_HIGH, "Loading savegame '{}'...\n", savename);
|
||||
|
||||
CL_QuitNetGame(NQ_SILENT);
|
||||
|
||||
|
|
@ -1625,6 +1629,7 @@ void G_DoLoadGame (void)
|
|||
|
||||
arc >> level.time;
|
||||
|
||||
P_SerializeMusInfo(arc);
|
||||
|
||||
for (i = 0; i < NUM_WORLDVARS; i++)
|
||||
{
|
||||
|
|
@ -1683,11 +1688,7 @@ void G_SaveGame (int slot, std::string_view description)
|
|||
*/
|
||||
void G_BuildSaveName(std::string &name, int slot)
|
||||
{
|
||||
#ifdef _XBOX
|
||||
std::string path = xbox_GetSavePath(name, slot);
|
||||
#else
|
||||
std::string path = M_GetUserFileName(name);
|
||||
#endif
|
||||
name = fmt::sprintf("%s" PATHSEP "odasv%d.ods", path, slot);
|
||||
}
|
||||
|
||||
|
|
@ -1707,11 +1708,7 @@ void G_DoSaveGame()
|
|||
return;
|
||||
}
|
||||
|
||||
#ifdef _XBOX
|
||||
xbox_WriteSaveMeta(name.substr(0, name.rfind(PATHSEPCHAR)), description.c_str());
|
||||
#endif
|
||||
|
||||
Printf (PRINT_HIGH, "Saving game to '%s'...\n", name);
|
||||
PrintFmt(PRINT_HIGH, "Saving game to '{}'...\n", name);
|
||||
|
||||
fwrite (description.c_str(), SAVESTRINGSIZE, 1, stdfile);
|
||||
fwrite (SAVESIG, 16, 1, stdfile);
|
||||
|
|
@ -1735,13 +1732,14 @@ void G_DoSaveGame()
|
|||
P_SerializeHorde(arc);
|
||||
|
||||
arc << level.time;
|
||||
P_SerializeMusInfo(arc);
|
||||
|
||||
for (int i = 0; i < NUM_WORLDVARS; i++)
|
||||
{
|
||||
arc << ACS_WorldVars[i];
|
||||
ACSWorldGlobalArray worldarr = ACS_WorldArrays[i];
|
||||
arc << worldarr.size();
|
||||
for (const auto [key, val] : worldarr)
|
||||
for (const auto& [key, val] : worldarr)
|
||||
{
|
||||
arc << key;
|
||||
arc << val;
|
||||
|
|
@ -1753,20 +1751,19 @@ void G_DoSaveGame()
|
|||
arc << ACS_GlobalVars[i];
|
||||
ACSWorldGlobalArray globalarr = ACS_GlobalArrays[i];
|
||||
arc << globalarr.size();
|
||||
for (const auto [key, val] : globalarr)
|
||||
for (const auto& [key, val] : globalarr)
|
||||
{
|
||||
arc << key;
|
||||
arc << val;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
arc << (BYTE)0x1d; // consistancy marker
|
||||
|
||||
gameaction = ga_nothing;
|
||||
savedescription[0] = 0;
|
||||
|
||||
Printf (PRINT_HIGH, "%s\n", GStrings(GGSAVED));
|
||||
PrintFmt(PRINT_HIGH, "{}\n", GStrings(GGSAVED));
|
||||
arc.Close ();
|
||||
|
||||
if (level.info->snapshot != NULL)
|
||||
|
|
@ -1850,12 +1847,12 @@ BEGIN_COMMAND(playdemo)
|
|||
}
|
||||
else
|
||||
{
|
||||
Printf(PRINT_WARNING, "Cannot play demo because WAD didn't load\n");
|
||||
Printf(PRINT_WARNING, "Use the 'wad' command\n");
|
||||
PrintFmt(PRINT_WARNING, "Cannot play demo because WAD didn't load\n");
|
||||
PrintFmt(PRINT_WARNING, "Use the 'wad' command\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
Printf(PRINT_HIGH, "Usage: playdemo lumpname or file\n");
|
||||
PrintFmt(PRINT_HIGH, "Usage: playdemo lumpname or file\n");
|
||||
}
|
||||
END_COMMAND(playdemo)
|
||||
|
||||
|
|
@ -1868,7 +1865,7 @@ BEGIN_COMMAND(streamdemo)
|
|||
}
|
||||
else
|
||||
{
|
||||
Printf(PRINT_HIGH, "Usage: streamdemo lumpname or file\n");
|
||||
PrintFmt(PRINT_HIGH, "Usage: streamdemo lumpname or file\n");
|
||||
}
|
||||
}
|
||||
END_COMMAND(streamdemo)
|
||||
|
|
@ -1904,7 +1901,7 @@ void G_DoPlayDemo(bool justStreamInput)
|
|||
std::string found = M_FindUserFileName(::defdemoname, ".lmp");
|
||||
if (found.empty())
|
||||
{
|
||||
Printf(PRINT_WARNING, "Could not find demo %s\n", ::defdemoname);
|
||||
PrintFmt(PRINT_WARNING, "Could not find demo {}\n", ::defdemoname);
|
||||
gameaction = ga_fullconsole;
|
||||
return;
|
||||
}
|
||||
|
|
@ -1921,7 +1918,7 @@ void G_DoPlayDemo(bool justStreamInput)
|
|||
if (bytelen)
|
||||
Z_Free(demobuffer);
|
||||
|
||||
Printf(PRINT_WARNING, "DOOM Demo file too short\n");
|
||||
PrintFmt(PRINT_WARNING, "DOOM Demo file too short\n");
|
||||
gameaction = ga_fullconsole;
|
||||
return;
|
||||
}
|
||||
|
|
@ -1935,7 +1932,7 @@ void G_DoPlayDemo(bool justStreamInput)
|
|||
demo_p[0] == DOOM_1_9p_DEMO ||
|
||||
demo_p[0] == DOOM_1_9_1_DEMO)
|
||||
{
|
||||
Printf(PRINT_HIGH, "Playing DOOM demo %s\n", defdemoname);
|
||||
PrintFmt(PRINT_HIGH, "Playing DOOM demo {}\n", defdemoname);
|
||||
|
||||
demostartgametic = gametic;
|
||||
demoversion = *demo_p++ == DOOM_1_9_1_DEMO ? LMP_DOOM_1_9_1 : LMP_DOOM_1_9;
|
||||
|
|
@ -1976,7 +1973,7 @@ void G_DoPlayDemo(bool justStreamInput)
|
|||
if (!validplayer(con))
|
||||
{
|
||||
Z_Free(demobuffer);
|
||||
Printf(PRINT_HIGH, "DOOM Demo: invalid console player %d of %lu\n", who + 1, players.size());
|
||||
PrintFmt(PRINT_HIGH, "DOOM Demo: invalid console player {} of {}\n", who + 1, players.size());
|
||||
gameaction = ga_fullconsole;
|
||||
return;
|
||||
}
|
||||
|
|
@ -2048,7 +2045,7 @@ void G_DoPlayDemo(bool justStreamInput)
|
|||
}
|
||||
else
|
||||
{
|
||||
Printf(PRINT_WARNING, "Unsupported demo format. If you are trying to play an Odamex " \
|
||||
PrintFmt(PRINT_WARNING, "Unsupported demo format. If you are trying to play an Odamex " \
|
||||
"netdemo, please use the netplay command\n");
|
||||
gameaction = ga_nothing;
|
||||
}
|
||||
|
|
@ -2129,9 +2126,13 @@ bool G_CheckDemoStatus (void)
|
|||
AActor *mo = idplayer(1).mo;
|
||||
|
||||
if (mo)
|
||||
Printf(PRINT_HIGH, "demotest:%x %x %x %x\n", mo->angle, mo->x, mo->y, mo->z);
|
||||
PrintFmt(PRINT_HIGH, "demotest:{:x} {:x} {:x} {:x}\n",
|
||||
static_cast<uint32_t>(mo->angle),
|
||||
static_cast<uint32_t>(mo->x),
|
||||
static_cast<uint32_t>(mo->y),
|
||||
static_cast<uint32_t>(mo->z));
|
||||
else
|
||||
Printf(PRINT_WARNING, "demotest:no player\n");
|
||||
PrintFmt(PRINT_WARNING, "demotest:no player\n");
|
||||
|
||||
demotest = false;
|
||||
|
||||
|
|
@ -2149,15 +2150,15 @@ bool G_CheckDemoStatus (void)
|
|||
int realtics = endtime * TICRATE / 1000;
|
||||
float fps = float(gametic * TICRATE) / realtics;
|
||||
|
||||
Printf(PRINT_HIGH, "timed %i gametics in %i realtics (%.1f fps)\n",
|
||||
gametic, realtics, fps);
|
||||
PrintFmt(PRINT_HIGH, "timed {} gametics in {} realtics ({:.1f} fps)\n",
|
||||
gametic, realtics, fps);
|
||||
|
||||
// exit the application
|
||||
CL_QuitCommand();
|
||||
return false;
|
||||
}
|
||||
else
|
||||
Printf (PRINT_HIGH, "Demo ended.\n");
|
||||
PrintFmt(PRINT_HIGH, "Demo ended.\n");
|
||||
|
||||
demoplayback = false;
|
||||
gameaction = ga_fullconsole;
|
||||
|
|
|
|||
|
|
@ -113,11 +113,11 @@ BEGIN_COMMAND (wad) // denis - changes wads
|
|||
// [Russell] print out some useful info
|
||||
if (argc == 1)
|
||||
{
|
||||
Printf(PRINT_HIGH, "Usage: wad pwad [...] [deh/bex [...]]\n");
|
||||
Printf(PRINT_HIGH, " wad iwad [pwad [...]] [deh/bex [...]]\n");
|
||||
Printf(PRINT_HIGH, "\n");
|
||||
Printf(PRINT_HIGH, "Load a wad file on the fly, pwads/dehs/bexs require extension\n");
|
||||
Printf(PRINT_HIGH, "eg: wad doom\n");
|
||||
PrintFmt(PRINT_HIGH, "Usage: wad pwad [...] [deh/bex [...]]\n");
|
||||
PrintFmt(PRINT_HIGH, " wad iwad [pwad [...]] [deh/bex [...]]\n");
|
||||
PrintFmt(PRINT_HIGH, "\n");
|
||||
PrintFmt(PRINT_HIGH, "Load a wad file on the fly, pwads/dehs/bexs require extension\n");
|
||||
PrintFmt(PRINT_HIGH, "eg: wad doom\n");
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
@ -179,8 +179,6 @@ void G_DoNewGame (void)
|
|||
|
||||
void G_InitNew (const char *mapname)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
// [RH] Remove all particles
|
||||
R_ClearParticles ();
|
||||
|
||||
|
|
@ -230,38 +228,38 @@ void G_InitNew (const char *mapname)
|
|||
{
|
||||
if (wantFast)
|
||||
{
|
||||
for (i = 0; i < NUMSTATES; i++)
|
||||
for (auto& [_, state] : states)
|
||||
{
|
||||
if (states[i].flags & STATEF_SKILL5FAST &&
|
||||
(states[i].tics != 1 || demoplayback))
|
||||
states[i].tics >>= 1; // don't change 1->0 since it causes cycles
|
||||
if (state.flags & STATEF_SKILL5FAST &&
|
||||
(state.tics != 1 || demoplayback))
|
||||
state.tics >>= 1; // don't change 1->0 since it causes cycles
|
||||
}
|
||||
|
||||
for (i = 0; i < NUMMOBJTYPES; ++i)
|
||||
for (auto& [_, minfo] : mobjinfo)
|
||||
{
|
||||
if (mobjinfo[i].altspeed != NO_ALTSPEED)
|
||||
if (minfo.altspeed != NO_ALTSPEED)
|
||||
{
|
||||
int swap = mobjinfo[i].speed;
|
||||
mobjinfo[i].speed = mobjinfo[i].altspeed;
|
||||
mobjinfo[i].altspeed = swap;
|
||||
int swap = minfo.speed;
|
||||
minfo.speed = minfo.altspeed;
|
||||
minfo.altspeed = swap;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < NUMSTATES; i++)
|
||||
for (auto& [_, state] : states)
|
||||
{
|
||||
if (states[i].flags & STATEF_SKILL5FAST)
|
||||
states[i].tics <<= 1; // don't change 1->0 since it causes cycles
|
||||
if (state.flags & STATEF_SKILL5FAST)
|
||||
state.tics <<= 1; // don't change 1->0 since it causes cycles
|
||||
}
|
||||
|
||||
for (i = 0; i < NUMMOBJTYPES; ++i)
|
||||
for (auto& [_, minfo] : mobjinfo)
|
||||
{
|
||||
if (mobjinfo[i].altspeed != NO_ALTSPEED)
|
||||
if (minfo.altspeed != NO_ALTSPEED)
|
||||
{
|
||||
int swap = mobjinfo[i].altspeed;
|
||||
mobjinfo[i].altspeed = mobjinfo[i].speed;
|
||||
mobjinfo[i].speed = swap;
|
||||
int swap = minfo.altspeed;
|
||||
minfo.altspeed = minfo.speed;
|
||||
minfo.speed = swap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -774,7 +772,7 @@ void G_WorldDone()
|
|||
clusters.findByCluster(levels.findByName(::level.secretmap).cluster) :
|
||||
clusters.findByCluster(levels.findByName(::level.nextmap).cluster);
|
||||
|
||||
if (nextcluster.cluster != level.cluster && sv_gametype == GM_COOP) {
|
||||
if (nextcluster.cluster != level.cluster && sv_gametype == GM_COOP && options.text != "-") {
|
||||
// Only start the finale if the next level's cluster is different
|
||||
// than the current one and we're not in deathmatch.
|
||||
if (!nextcluster.entertext.empty())
|
||||
|
|
|
|||
|
|
@ -70,16 +70,11 @@
|
|||
#include "cl_replay.h"
|
||||
|
||||
#include <bitset>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
|
||||
#include "server.pb.h"
|
||||
|
||||
#ifdef _XBOX
|
||||
#include "i_xbox.h"
|
||||
#endif
|
||||
|
||||
#if _MSC_VER == 1310
|
||||
#pragma optimize("",off)
|
||||
#endif
|
||||
|
|
@ -125,9 +120,6 @@ static int packetseq[256];
|
|||
// denis - unique session key provided by the server
|
||||
std::string digest;
|
||||
|
||||
// denis - clientside compressor, used for decompression
|
||||
huffman_client compressor;
|
||||
|
||||
std::string server_host = ""; // hostname of server
|
||||
|
||||
// [SL] 2011-06-27 - Class to record and playback network recordings
|
||||
|
|
@ -301,8 +293,8 @@ void M_Ticker(void);
|
|||
|
||||
size_t P_NumPlayersInGame();
|
||||
void G_PlayerReborn (player_t &player);
|
||||
void P_KillMobj (AActor *source, AActor *target, AActor *inflictor, bool joinkill);
|
||||
void P_SetPsprite (player_t *player, int position, statenum_t stnum);
|
||||
void P_KillMobj (AActor *source, AActor *target, const AActor *inflictor, bool joinkill);
|
||||
void P_SetPsprite (player_t *player, int position, int32_t stnum);
|
||||
void P_ExplodeMissile (AActor* mo);
|
||||
void P_CalcHeight (player_t *player);
|
||||
bool P_CheckMissileSpawn (AActor* th);
|
||||
|
|
@ -363,7 +355,7 @@ void CL_ResyncWorldIndex()
|
|||
|
||||
void Host_EndGame(const char *msg)
|
||||
{
|
||||
Printf("%s", msg);
|
||||
PrintFmt("{}", msg);
|
||||
CL_QuitNetGame(NQ_SILENT);
|
||||
}
|
||||
|
||||
|
|
@ -436,18 +428,18 @@ void CL_QuitNetGame2(const netQuitReason_e reason, const char* file, const int l
|
|||
default: // Also NQ_SILENT
|
||||
break;
|
||||
case NQ_DISCONNECT:
|
||||
Printf("Disconnected from server\n");
|
||||
PrintFmt("Disconnected from server\n");
|
||||
break;
|
||||
case NQ_ABORT:
|
||||
Printf("Connection attempt aborted\n");
|
||||
PrintFmt("Connection attempt aborted\n");
|
||||
break;
|
||||
case NQ_PROTO:
|
||||
Printf("Disconnected from server: Unrecoverable protocol error\n");
|
||||
PrintFmt("Disconnected from server: Unrecoverable protocol error\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (::debug_disconnect)
|
||||
Printf(" (%s:%d)\n", file, line);
|
||||
PrintFmt(" ({}:{})\n", file, line);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -593,6 +585,8 @@ void CL_SpyCycle(Iterator begin, Iterator end)
|
|||
ST_ForceRefresh();
|
||||
}
|
||||
|
||||
P_FriendlyEffects(); // Mark any new friendly monsters with an effect
|
||||
|
||||
return;
|
||||
}
|
||||
} while (it != sentinal);
|
||||
|
|
@ -683,10 +677,10 @@ void CL_RunTics()
|
|||
// debugging output
|
||||
extern unsigned char prndindex;
|
||||
if (!(players.empty()) && players.begin()->mo)
|
||||
Printf("level.time %d, prndindex %d, %d %d %d\n",
|
||||
level.time, prndindex, players.begin()->mo->x, players.begin()->mo->y, players.begin()->mo->z);
|
||||
PrintFmt("level.time {}, prndindex {}, {} {} {}\n",
|
||||
level.time, prndindex, players.begin()->mo->x, players.begin()->mo->y, players.begin()->mo->z);
|
||||
else
|
||||
Printf("level.time %d, prndindex %d\n", level.time, prndindex);
|
||||
PrintFmt("level.time %d, prndindex %d\n", level.time, prndindex);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -722,12 +716,12 @@ BEGIN_COMMAND (connect)
|
|||
{
|
||||
if (argc == 1)
|
||||
{
|
||||
Printf("Usage: connect ip[:port] [password]\n");
|
||||
Printf("\n");
|
||||
Printf("Connect to a server, with optional port number");
|
||||
Printf(" and/or password\n");
|
||||
Printf("eg: connect 127.0.0.1\n");
|
||||
Printf("eg: connect 192.168.0.1:12345 secretpass\n");
|
||||
PrintFmt("Usage: connect ip[:port] [password]\n");
|
||||
PrintFmt("\n");
|
||||
PrintFmt("Connect to a server, with optional port number");
|
||||
PrintFmt(" and/or password\n");
|
||||
PrintFmt("eg: connect 127.0.0.1\n");
|
||||
PrintFmt("eg: connect 192.168.0.1:12345 secretpass\n");
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
@ -762,7 +756,7 @@ BEGIN_COMMAND (connect)
|
|||
}
|
||||
else
|
||||
{
|
||||
Printf("Could not resolve host %s\n", target);
|
||||
PrintFmt("Could not resolve host {}\n", target);
|
||||
memset(&serveraddr, 0, sizeof(serveraddr));
|
||||
}
|
||||
}
|
||||
|
|
@ -796,11 +790,11 @@ BEGIN_COMMAND (players)
|
|||
}
|
||||
|
||||
// Print them, ordered by player id.
|
||||
Printf("PLAYERS IN GAME:\n");
|
||||
PrintFmt("PLAYERS IN GAME:\n");
|
||||
for (const auto& [id, name] : mplayers) {
|
||||
Printf("%3d. %s\n", id, name);
|
||||
PrintFmt("{:>3d}. {}\n", id, name);
|
||||
}
|
||||
Printf("%lu %s\n", mplayers.size(), mplayers.size() == 1 ? "PLAYER" : "PLAYERS");
|
||||
PrintFmt("{} {}\n", mplayers.size(), mplayers.size() == 1 ? "PLAYER" : "PLAYERS");
|
||||
}
|
||||
END_COMMAND (players)
|
||||
|
||||
|
|
@ -854,7 +848,7 @@ BEGIN_COMMAND (kill)
|
|||
if (sv_allowcheats || G_IsCoopGame())
|
||||
MSG_WriteMarker(&net_buffer, clc_kill);
|
||||
else
|
||||
Printf ("You must run the server with '+set sv_allowcheats 1' or disable sv_keepkeys to enable this command.\n");
|
||||
PrintFmt("You must run the server with '+set sv_allowcheats 1' or disable sv_keepkeys to enable this command.\n");
|
||||
}
|
||||
END_COMMAND (kill)
|
||||
|
||||
|
|
@ -887,7 +881,7 @@ BEGIN_COMMAND (serverinfo)
|
|||
std::sort(server_cvars.begin(), server_cvars.end());
|
||||
|
||||
// Heading
|
||||
Printf ("\n%*s - Value\n", static_cast<int>(MaxFieldLength), "Name");
|
||||
PrintFmt("\n{1:>{0}} - Value\n", MaxFieldLength, "Name");
|
||||
|
||||
// Data
|
||||
for (const auto& varname : server_cvars)
|
||||
|
|
@ -895,13 +889,13 @@ BEGIN_COMMAND (serverinfo)
|
|||
cvar_t *dummy;
|
||||
Cvar = cvar_t::FindCVar(varname.c_str(), &dummy);
|
||||
|
||||
Printf( "%*s - %s\n",
|
||||
static_cast<int>(MaxFieldLength),
|
||||
Cvar->name(),
|
||||
Cvar->str());
|
||||
PrintFmt("{1:>{0}} - {2}\n",
|
||||
MaxFieldLength,
|
||||
Cvar->name(),
|
||||
Cvar->str());
|
||||
}
|
||||
|
||||
Printf ("\n");
|
||||
PrintFmt("\n");
|
||||
}
|
||||
END_COMMAND (serverinfo)
|
||||
|
||||
|
|
@ -954,16 +948,16 @@ END_COMMAND (rcon_logout)
|
|||
BEGIN_COMMAND (playerteam)
|
||||
{
|
||||
if (G_IsTeamGame())
|
||||
Printf("Your are in the %s team.\n", V_GetTeamColor(consoleplayer().userinfo.team));
|
||||
PrintFmt("Your are in the {} team.\n", V_GetTeamColor(consoleplayer().userinfo.team));
|
||||
else
|
||||
Printf("You need to play a team-based gamemode in order to use this command.\n");
|
||||
PrintFmt("You need to play a team-based gamemode in order to use this command.\n");
|
||||
}
|
||||
END_COMMAND (playerteam)
|
||||
|
||||
BEGIN_COMMAND (changeteams)
|
||||
{
|
||||
int iTeam = (int)consoleplayer().userinfo.team;
|
||||
iTeam = ++iTeam % sv_teamsinplay.asInt();
|
||||
iTeam = (iTeam + 1) % sv_teamsinplay.asInt();
|
||||
cl_team.Set(GetTeamInfo((team_t)iTeam)->ColorStringUpper.c_str());
|
||||
}
|
||||
END_COMMAND (changeteams)
|
||||
|
|
@ -998,17 +992,17 @@ END_COMMAND(ready)
|
|||
|
||||
static void NetCmdHelp()
|
||||
{
|
||||
Printf(PRINT_HIGH,
|
||||
"netcmd - Send an arbitrary string command to a server\n\n"
|
||||
"Common commands:\n"
|
||||
" ] netcmd help\n"
|
||||
" Check to see if the server has any server-specific netcmd's.\n\n"
|
||||
" ] netcmd motd\n"
|
||||
" Ask the server for the MOTD.\n\n"
|
||||
" ] netcmd ready\n"
|
||||
" Set yourself as ready or unready.\n\n"
|
||||
" ] netcmd vote <\"yes\"|\"no\">\n"
|
||||
" Vote \"yes\" or \"no\" in an ongoing vote.\n");
|
||||
PrintFmt(PRINT_HIGH,
|
||||
"netcmd - Send an arbitrary string command to a server\n\n"
|
||||
"Common commands:\n"
|
||||
" ] netcmd help\n"
|
||||
" Check to see if the server has any server-specific netcmd's.\n\n"
|
||||
" ] netcmd motd\n"
|
||||
" Ask the server for the MOTD.\n\n"
|
||||
" ] netcmd ready\n"
|
||||
" Set yourself as ready or unready.\n\n"
|
||||
" ] netcmd vote <\"yes\"|\"no\">\n"
|
||||
" Vote \"yes\" or \"no\" in an ongoing vote.\n");
|
||||
}
|
||||
|
||||
BEGIN_COMMAND(netcmd)
|
||||
|
|
@ -1080,12 +1074,12 @@ BEGIN_COMMAND (spy)
|
|||
{
|
||||
if (argc <= 1) {
|
||||
if (spyplayername.length() > 0) {
|
||||
Printf(PRINT_HIGH, "Unfollowing player '%s'.\n", spyplayername);
|
||||
PrintFmt(PRINT_HIGH, "Unfollowing player '{}'.\n", spyplayername);
|
||||
|
||||
// revert to not spying:
|
||||
displayplayer_id = consoleplayer_id;
|
||||
} else {
|
||||
Printf(PRINT_HIGH, "Expecting player name. Try 'players' to list all player names.\n");
|
||||
PrintFmt(PRINT_HIGH, "Expecting player name. Try 'players' to list all player names.\n");
|
||||
}
|
||||
|
||||
// clear last player name:
|
||||
|
|
@ -1094,8 +1088,8 @@ BEGIN_COMMAND (spy)
|
|||
// remember player name in case of disconnect/reconnect e.g. level change:
|
||||
spyplayername = argv[1];
|
||||
|
||||
Printf(PRINT_HIGH, "Following player '%s'. Use 'spy' with no player name to unfollow.\n",
|
||||
spyplayername);
|
||||
PrintFmt(PRINT_HIGH, "Following player '{}'. Use 'spy' with no player name to unfollow.\n",
|
||||
spyplayername);
|
||||
}
|
||||
|
||||
CL_CheckDisplayPlayer();
|
||||
|
|
@ -1164,7 +1158,7 @@ void CL_NetDemoPlay(const std::string& filename)
|
|||
found = M_GetNetDemoFileName(filename, cl_netdemodir);
|
||||
if (found.empty())
|
||||
{
|
||||
Printf(PRINT_WARNING, "Could not find demo %s.\n", filename);
|
||||
PrintFmt(PRINT_WARNING, "Could not find demo {}.\n", filename);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -1189,14 +1183,14 @@ BEGIN_COMMAND(netrecord)
|
|||
{
|
||||
if (netdemo.isRecording())
|
||||
{
|
||||
Printf(PRINT_HIGH, "Already recording a netdemo. Please stop recording before "\
|
||||
"beginning a new netdemo recording.\n");
|
||||
PrintFmt(PRINT_HIGH, "Already recording a netdemo. Please stop recording before "\
|
||||
"beginning a new netdemo recording.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!connected || simulated_connection)
|
||||
{
|
||||
Printf(PRINT_HIGH, "You must be connected to a server to record a netdemo.\n");
|
||||
PrintFmt(PRINT_HIGH, "You must be connected to a server to record a netdemo.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1217,13 +1211,13 @@ BEGIN_COMMAND(netpause)
|
|||
{
|
||||
netdemo.resume();
|
||||
paused = false;
|
||||
Printf(PRINT_HIGH, "Demo resumed.\n");
|
||||
PrintFmt(PRINT_HIGH, "Demo resumed.\n");
|
||||
}
|
||||
else if (netdemo.isPlaying())
|
||||
{
|
||||
netdemo.pause();
|
||||
paused = true;
|
||||
Printf(PRINT_HIGH, "Demo paused.\n");
|
||||
PrintFmt(PRINT_HIGH, "Demo paused.\n");
|
||||
}
|
||||
}
|
||||
END_COMMAND(netpause)
|
||||
|
|
@ -1232,7 +1226,7 @@ BEGIN_COMMAND(netplay)
|
|||
{
|
||||
if(argc <= 1)
|
||||
{
|
||||
Printf(PRINT_HIGH, "Usage: netplay <demoname>\n");
|
||||
PrintFmt(PRINT_HIGH, "Usage: netplay <demoname>\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1258,15 +1252,15 @@ BEGIN_COMMAND(netdemostats)
|
|||
int curtime = netdemo.calculateTimeElapsed();
|
||||
int totaltime = netdemo.calculateTotalTime();
|
||||
|
||||
Printf(PRINT_HIGH, "\n%s\n", netdemo.getFileName());
|
||||
Printf(PRINT_HIGH, "============================================\n");
|
||||
Printf(PRINT_HIGH, "Total time: %i seconds\n", totaltime);
|
||||
Printf(PRINT_HIGH, "Current position: %i seconds (%i%%)\n",
|
||||
PrintFmt(PRINT_HIGH, "\n{}\n", netdemo.getFileName());
|
||||
PrintFmt(PRINT_HIGH, "============================================\n");
|
||||
PrintFmt(PRINT_HIGH, "Total time: {} seconds\n", totaltime);
|
||||
PrintFmt(PRINT_HIGH, "Current position: {} seconds ({}%)\n",
|
||||
curtime, curtime * 100 / totaltime);
|
||||
Printf(PRINT_HIGH, "Number of maps: %lu\n", maptimes.size());
|
||||
PrintFmt(PRINT_HIGH, "Number of maps: {}\n", maptimes.size());
|
||||
for (size_t i = 0; i < maptimes.size(); i++)
|
||||
{
|
||||
Printf(PRINT_HIGH, "> %02lu Starting time: %i seconds\n",
|
||||
PrintFmt(PRINT_HIGH, "> {:02d} Starting time: {} seconds\n",
|
||||
i + 1, maptimes[i]);
|
||||
}
|
||||
}
|
||||
|
|
@ -1414,6 +1408,8 @@ void CL_SpectatePlayer(player_t& player, bool spectate)
|
|||
{
|
||||
R_ForceViewWindowResize(); // toggline spectator mode affects status bar visibility
|
||||
|
||||
P_FriendlyEffects(); // Mark any new friendly monsters with an effect
|
||||
|
||||
if (player.spectator)
|
||||
{
|
||||
player.playerstate = PST_LIVE; // Resurrect dead spectators
|
||||
|
|
@ -1460,7 +1456,7 @@ void CL_RequestConnectInfo(void)
|
|||
{
|
||||
connecttimeout = 140;
|
||||
|
||||
Printf(PRINT_HIGH, "Connecting to %s...\n", NET_AdrToString(serveraddr));
|
||||
PrintFmt(PRINT_HIGH, "Connecting to {}...\n", NET_AdrToString(serveraddr));
|
||||
|
||||
SZ_Clear(&net_buffer);
|
||||
MSG_WriteLong(&net_buffer, LAUNCHER_CHALLENGE);
|
||||
|
|
@ -1483,9 +1479,9 @@ void CL_QuitAndTryDownload(const OWantFile& missing_file)
|
|||
|
||||
if (missing_file.getBasename().empty())
|
||||
{
|
||||
Printf(PRINT_WARNING,
|
||||
"Tried to download an empty file. This is probably a bug "
|
||||
"in the client where an empty file is considered missing.\n");
|
||||
PrintFmt(PRINT_WARNING,
|
||||
"Tried to download an empty file. This is probably a bug "
|
||||
"in the client where an empty file is considered missing.\n");
|
||||
CL_QuitNetGame(NQ_DISCONNECT);
|
||||
return;
|
||||
}
|
||||
|
|
@ -1493,10 +1489,10 @@ void CL_QuitAndTryDownload(const OWantFile& missing_file)
|
|||
if (!cl_serverdownload)
|
||||
{
|
||||
// Downloading is disabled client-side
|
||||
Printf(PRINT_WARNING,
|
||||
"Unable to find \"%s\". Downloading is disabled on your client. Go to "
|
||||
"Options > Network Options to enable downloading.\n",
|
||||
missing_file.getBasename());
|
||||
PrintFmt(PRINT_WARNING,
|
||||
"Unable to find \"{}\". Downloading is disabled on your client. Go to "
|
||||
"Options > Network Options to enable downloading.\n",
|
||||
missing_file.getBasename());
|
||||
CL_QuitNetGame(NQ_DISCONNECT);
|
||||
return;
|
||||
}
|
||||
|
|
@ -1504,9 +1500,9 @@ void CL_QuitAndTryDownload(const OWantFile& missing_file)
|
|||
if (netdemo.isPlaying())
|
||||
{
|
||||
// Playing a netdemo and unable to download from the server
|
||||
Printf(PRINT_WARNING,
|
||||
"Unable to find \"%s\". Cannot download while playing a netdemo.\n",
|
||||
missing_file.getBasename());
|
||||
PrintFmt(PRINT_WARNING,
|
||||
"Unable to find \"{}\". Cannot download while playing a netdemo.\n",
|
||||
missing_file.getBasename());
|
||||
CL_QuitNetGame(NQ_DISCONNECT);
|
||||
return;
|
||||
}
|
||||
|
|
@ -1514,9 +1510,9 @@ void CL_QuitAndTryDownload(const OWantFile& missing_file)
|
|||
if (sv_downloadsites.str().empty() && cl_downloadsites.str().empty())
|
||||
{
|
||||
// Nobody has any download sites configured.
|
||||
Printf("Unable to find \"%s\". Both your client and the server have no "
|
||||
"download sites configured.\n",
|
||||
missing_file.getBasename());
|
||||
PrintFmt("Unable to find \"{}\". Both your client and the server have no "
|
||||
"download sites configured.\n",
|
||||
missing_file.getBasename());
|
||||
CL_QuitNetGame(NQ_DISCONNECT);
|
||||
return;
|
||||
}
|
||||
|
|
@ -1536,8 +1532,8 @@ void CL_QuitAndTryDownload(const OWantFile& missing_file)
|
|||
downloadsites.insert(downloadsites.end(), clientsites.begin(), clientsites.end());
|
||||
|
||||
// Disconnect from the server before we start the download.
|
||||
Printf(PRINT_HIGH, "Need to download \"%s\", disconnecting from server...\n",
|
||||
missing_file.getBasename());
|
||||
PrintFmt(PRINT_HIGH, "Need to download \"{}\", disconnecting from server...\n",
|
||||
missing_file.getBasename());
|
||||
CL_QuitNetGame(NQ_SILENT);
|
||||
|
||||
// Start the download.
|
||||
|
|
@ -1566,8 +1562,8 @@ bool CL_PrepareConnect()
|
|||
std::string server_map = MSG_ReadString();
|
||||
byte server_wads = MSG_ReadByte();
|
||||
|
||||
Printf("Found server at %s.\n\n", NET_AdrToString(::serveraddr));
|
||||
Printf("> Hostname: %s\n", server_host);
|
||||
PrintFmt("Found server at {}.\n\n", NET_AdrToString(::serveraddr));
|
||||
PrintFmt("> Hostname: {}\n", server_host);
|
||||
|
||||
std::vector<std::string> newwadnames;
|
||||
newwadnames.reserve(server_wads);
|
||||
|
|
@ -1599,15 +1595,15 @@ bool CL_PrepareConnect()
|
|||
OMD5Hash::makeFromHexStr(hash, hashStr);
|
||||
if (!OWantFile::makeWithHash(file, newwadnames.at(i), OFILE_WAD, hash))
|
||||
{
|
||||
Printf(PRINT_WARNING,
|
||||
"Could not construct wanted file \"%s\" that server requested.\n",
|
||||
newwadnames.at(i));
|
||||
PrintFmt(PRINT_WARNING,
|
||||
"Could not construct wanted file \"{}\" that server requested.\n",
|
||||
newwadnames.at(i));
|
||||
CL_QuitNetGame(NQ_ABORT);
|
||||
return false;
|
||||
}
|
||||
|
||||
Printf("> %s\n %s\n", file.getBasename(),
|
||||
file.getWantedMD5().getHexStr());
|
||||
PrintFmt("> {}\n {}\n", file.getBasename(),
|
||||
file.getWantedMD5().getHexStr());
|
||||
}
|
||||
|
||||
// Download website - needed for HTTP downloading to work.
|
||||
|
|
@ -1627,7 +1623,7 @@ bool CL_PrepareConnect()
|
|||
}
|
||||
}
|
||||
|
||||
Printf("> Map: %s\n", server_map);
|
||||
PrintFmt("> Map: {}\n", server_map);
|
||||
|
||||
version = MSG_ReadShort();
|
||||
if(version > VERSION)
|
||||
|
|
@ -1672,12 +1668,12 @@ bool CL_PrepareConnect()
|
|||
|
||||
int major, minor, patch;
|
||||
BREAKVER(gameversion, major, minor, patch);
|
||||
Printf(PRINT_HIGH, "> Server Version %i.%i.%i\n", major, minor, patch);
|
||||
PrintFmt(PRINT_HIGH, "> Server Version {}.{}.{}\n", major, minor, patch);
|
||||
|
||||
std::string msg = VersionMessage(::gameversion, GAMEVER, NULL);
|
||||
if (!msg.empty())
|
||||
{
|
||||
Printf(PRINT_WARNING, "%s", msg);
|
||||
PrintFmt(PRINT_WARNING, "{}", msg);
|
||||
CL_QuitNetGame(NQ_ABORT);
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1686,7 +1682,7 @@ bool CL_PrepareConnect()
|
|||
{
|
||||
// [AM] Not worth sorting out what version it actually is.
|
||||
std::string msg = VersionMessage(MAKEVER(0, 3, 0), GAMEVER, NULL);
|
||||
Printf(PRINT_WARNING, "%s", msg);
|
||||
PrintFmt(PRINT_WARNING, "{}", msg);
|
||||
CL_QuitNetGame(NQ_ABORT);
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1702,22 +1698,22 @@ bool CL_PrepareConnect()
|
|||
std::string filename = MSG_ReadString();
|
||||
if (!OWantFile::make(file, filename, OFILE_DEH))
|
||||
{
|
||||
Printf(PRINT_WARNING,
|
||||
"Could not construct wanted file \"%s\" that server requested.\n",
|
||||
filename);
|
||||
PrintFmt(PRINT_WARNING,
|
||||
"Could not construct wanted file \"{}\" that server requested.\n",
|
||||
filename);
|
||||
CL_QuitNetGame(NQ_ABORT);
|
||||
return false;
|
||||
}
|
||||
|
||||
Printf("> %s\n", file.getBasename());
|
||||
PrintFmt("> {}\n", file.getBasename());
|
||||
}
|
||||
|
||||
// TODO: Allow deh/bex file downloads
|
||||
Printf("\n");
|
||||
PrintFmt("\n");
|
||||
bool ok = D_DoomWadReboot(newwadfiles, newpatchfiles);
|
||||
if (!ok && missingfiles.empty())
|
||||
{
|
||||
Printf(PRINT_WARNING, "Could not load required set of WAD files.\n");
|
||||
PrintFmt(PRINT_WARNING, "Could not load required set of WAD files.\n");
|
||||
CL_QuitNetGame(NQ_ABORT);
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1725,8 +1721,8 @@ bool CL_PrepareConnect()
|
|||
{
|
||||
if (::missingCommercialIWAD)
|
||||
{
|
||||
Printf(PRINT_WARNING,
|
||||
"Server requires commercial IWAD that was not found.\n");
|
||||
PrintFmt(PRINT_WARNING,
|
||||
"Server requires commercial IWAD that was not found.\n");
|
||||
CL_QuitNetGame(NQ_ABORT);
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1767,9 +1763,7 @@ bool CL_Connect()
|
|||
MSG_WriteMarker(&net_buffer, clc_ack);
|
||||
MSG_WriteLong(&net_buffer, 0);
|
||||
NET_SendPacket(::net_buffer, ::serveraddr);
|
||||
Printf("Requesting server state...\n");
|
||||
|
||||
compressor.reset();
|
||||
PrintFmt("Requesting server state...\n");
|
||||
|
||||
connected = true;
|
||||
multiplayer = true;
|
||||
|
|
@ -1780,7 +1774,7 @@ bool CL_Connect()
|
|||
byte flags = MSG_ReadByte();
|
||||
if (flags & SVF_UNUSED_MASK)
|
||||
{
|
||||
Printf(PRINT_WARNING, "Protocol flag bits (%u) were not understood.", flags);
|
||||
PrintFmt(PRINT_WARNING, "Protocol flag bits ({}) were not understood.", flags);
|
||||
CL_QuitNetGame(NQ_PROTO);
|
||||
}
|
||||
else if (flags & SVF_COMPRESSED)
|
||||
|
|
@ -1816,7 +1810,7 @@ void CL_InitNetwork (void)
|
|||
if (v)
|
||||
{
|
||||
localport = atoi (v);
|
||||
Printf (PRINT_HIGH, "using alternate port %i\n", localport);
|
||||
PrintFmt(PRINT_HIGH, "using alternate port {}\n", localport);
|
||||
}
|
||||
else
|
||||
localport = CLIENTPORT;
|
||||
|
|
@ -1863,7 +1857,7 @@ void CL_TryToConnect(DWORD server_token)
|
|||
{
|
||||
connecttimeout = 140; // 140 tics = 4 seconds
|
||||
|
||||
Printf("Joining server...\n");
|
||||
PrintFmt("Joining server...\n");
|
||||
|
||||
SZ_Clear(&net_buffer);
|
||||
MSG_WriteLong(&net_buffer, PROTO_CHALLENGE); // send challenge
|
||||
|
|
@ -1969,7 +1963,7 @@ bool CL_ReadPacketHeader()
|
|||
byte flags = MSG_ReadByte();
|
||||
if (flags & SVF_UNUSED_MASK)
|
||||
{
|
||||
Printf(PRINT_WARNING, "Protocol flag bits (%u) were not understood.", flags);
|
||||
PrintFmt(PRINT_WARNING, "Protocol flag bits ({}) were not understood.", flags);
|
||||
CL_QuitNetGame(NQ_PROTO);
|
||||
}
|
||||
else if (flags & SVF_COMPRESSED)
|
||||
|
|
@ -2039,7 +2033,7 @@ void CL_ParseCommands()
|
|||
|
||||
if (!protos.empty())
|
||||
{
|
||||
Printf(PRINT_WARNING, "CL_ParseCommands: %s\n", err);
|
||||
PrintFmt(PRINT_WARNING, "CL_ParseCommands: {}\n", err);
|
||||
|
||||
for (Protos::const_iterator it = protos.begin(); it != protos.end(); ++it)
|
||||
{
|
||||
|
|
@ -2047,13 +2041,13 @@ void CL_ParseCommands()
|
|||
ptrdiff_t idx = it - protos.begin() + 1;
|
||||
std::string svc = SVCName(it->header);
|
||||
size_t siz = it->size;
|
||||
Printf(PRINT_WARNING, "%c %2zd [%s] %zub\n", latest, idx, svc,
|
||||
siz);
|
||||
PrintFmt(PRINT_WARNING, "{:c} {:>2d} [{}] {}b\n", latest, idx, svc,
|
||||
siz);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Printf(PRINT_WARNING, "CL_ParseCommands: %s\n", err);
|
||||
PrintFmt(PRINT_WARNING, "CL_ParseCommands: {}\n", err);
|
||||
}
|
||||
|
||||
CL_QuitNetGame(NQ_PROTO);
|
||||
|
|
@ -2062,8 +2056,8 @@ void CL_ParseCommands()
|
|||
// Measure length of each message, so we can keep track of bandwidth.
|
||||
if (::net_message.BytesRead() < byteStart)
|
||||
{
|
||||
Printf("CL_ParseCommands: end byte (%lu) < start byte (%lu)\n",
|
||||
::net_message.BytesRead(), byteStart);
|
||||
PrintFmt("CL_ParseCommands: end byte ({}) < start byte ({})\n",
|
||||
::net_message.BytesRead(), byteStart);
|
||||
}
|
||||
|
||||
::netgraph.addTrafficIn(::net_message.BytesRead() - byteStart);
|
||||
|
|
@ -2173,8 +2167,18 @@ void CL_SendSummonCheat(const char* summon)
|
|||
MSG_WriteString(&net_buffer, summon);
|
||||
}
|
||||
|
||||
//
|
||||
// CL_SendSummonFriendCheat
|
||||
//
|
||||
void CL_SendSummonFriendCheat(const char* summon)
|
||||
{
|
||||
MSG_WriteMarker(&net_buffer, clc_cheat);
|
||||
MSG_WriteByte(&net_buffer, 3);
|
||||
MSG_WriteString(&net_buffer, summon);
|
||||
}
|
||||
|
||||
void PickupMessage (AActor *toucher, const char *message)
|
||||
|
||||
void PickupMessage (const AActor *toucher, const char *message)
|
||||
{
|
||||
// Some maps have multiple items stacked on top of each other.
|
||||
// It looks odd to display pickup messages for all of them.
|
||||
|
|
@ -2186,7 +2190,7 @@ void PickupMessage (AActor *toucher, const char *message)
|
|||
{
|
||||
lastmessagetic = gametic;
|
||||
lastmessage = message;
|
||||
Printf (PRINT_PICKUP, "%s\n", message);
|
||||
PrintFmt(PRINT_PICKUP, "{}\n", message);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2195,7 +2199,7 @@ void PickupMessage (AActor *toucher, const char *message)
|
|||
//
|
||||
// This is used for displaying weaponstay messages, it is inevitably a hack
|
||||
// because weaponstay is a hack
|
||||
void WeaponPickupMessage (AActor *toucher, weapontype_t &Weapon)
|
||||
void WeaponPickupMessage (const AActor *toucher, const weapontype_t &Weapon)
|
||||
{
|
||||
switch (Weapon)
|
||||
{
|
||||
|
|
@ -2359,8 +2363,8 @@ void CL_SimulatePlayers()
|
|||
if (dist > 2 * FRACUNIT)
|
||||
{
|
||||
#ifdef _SNAPSHOT_DEBUG_
|
||||
Printf(PRINT_HIGH, "Snapshot %i, Correcting extrapolation error of %i\n",
|
||||
world_index, dist >> FRACBITS);
|
||||
PrintFmt(PRINT_HIGH, "Snapshot {}, Correcting extrapolation error of {}\n",
|
||||
world_index, dist >> FRACBITS);
|
||||
#endif // _SNAPSHOT_DEBUG_
|
||||
|
||||
static constexpr fixed_t correction_amount = FRACUNIT * 0.80f;
|
||||
|
|
@ -2431,7 +2435,7 @@ void CL_SimulateWorld()
|
|||
else
|
||||
reason = "invalid world_index";
|
||||
|
||||
Printf(PRINT_HIGH, "Gametic %i, world_index %i, Resynching world index (%s).\n",
|
||||
PrintFmt(PRINT_HIGH, "Gametic {}, world_index {}, Resynching world index ({}).\n",
|
||||
gametic, world_index, reason);
|
||||
#endif // _WORLD_INDEX_DEBUG_
|
||||
|
||||
|
|
@ -2443,7 +2447,7 @@ void CL_SimulateWorld()
|
|||
world_index = last_svgametic;
|
||||
|
||||
#ifdef _WORLD_INDEX_DEBUG_
|
||||
Printf(PRINT_HIGH, "Gametic %i, simulating world_index %i\n",
|
||||
PrintFmt(PRINT_HIGH, "Gametic {}, simulating world_index {}\n",
|
||||
gametic, world_index);
|
||||
#endif // _WORLD_INDEX_DEBUG_
|
||||
|
||||
|
|
@ -2459,8 +2463,8 @@ void CL_SimulateWorld()
|
|||
|
||||
#ifdef _WORLD_INDEX_DEBUG_
|
||||
if (drift_correction != 0)
|
||||
Printf(PRINT_HIGH, "Gametic %i, increasing world index by %i.\n",
|
||||
gametic, drift_correction);
|
||||
PrintFmt(PRINT_HIGH, "Gametic {}, increasing world index by {}.\n",
|
||||
gametic, drift_correction);
|
||||
#endif // _WORLD_INDEX_DEBUG_
|
||||
|
||||
world_index = world_index + 1 + drift_correction;
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@ bool CL_Connect();
|
|||
void CL_SendCheat(int cheats);
|
||||
void CL_SendGiveCheat(const char* item);
|
||||
void CL_SendSummonCheat(const char* summon);
|
||||
void CL_SendSummonFriendCheat(const char* summon);
|
||||
|
||||
void CL_DisplayTics();
|
||||
void CL_RunTics();
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@
|
|||
|
||||
#include "odamex.h"
|
||||
|
||||
#include <map>
|
||||
#include <sstream>
|
||||
|
||||
#include "c_maplist.h"
|
||||
|
|
@ -384,11 +383,11 @@ void CMD_MaplistCallback(const maplist_qrows_t &result) {
|
|||
const auto& [map, lastmap, _, wads] = *entry;
|
||||
char flag = ' ';
|
||||
if (show_this_map && index == this_index) {
|
||||
flag = '*';
|
||||
flag = '>';
|
||||
} else if (index == next_index) {
|
||||
flag = '+';
|
||||
}
|
||||
PrintFmt(PRINT_HIGH, "{}{}. {} {}{}\n", flag, index + 1,
|
||||
PrintFmt(PRINT_HIGH, " {}{}. {} {}{}\n", flag, index + 1,
|
||||
JoinStrings(wads, " "), map,
|
||||
lastmap.empty() ? "" : fmt::format(" lastmap={}", lastmap));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,8 +22,6 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "c_maplist.h"
|
||||
|
||||
// Callbacks for deffered queries
|
||||
|
|
|
|||
|
|
@ -158,6 +158,8 @@ void P_SpawnPlayer(player_t& player, mapthing2_t* mthing)
|
|||
else if (playerstate == PST_REBORN)
|
||||
level.behavior->StartTypedScripts(SCRIPT_Respawn, player.mo);
|
||||
}
|
||||
|
||||
P_FriendlyEffects(); // Mark any new friendly monsters with an effect
|
||||
}
|
||||
|
||||
std::vector<AActor*> spawnfountains;
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@
|
|||
#include "infomap.h"
|
||||
#include "cl_replay.h"
|
||||
#include "r_interp.h"
|
||||
#include "m_doomobjcontainer.h"
|
||||
|
||||
// Extern data from other files.
|
||||
|
||||
|
|
@ -84,6 +85,8 @@ EXTERN_CVAR(hud_revealsecrets)
|
|||
EXTERN_CVAR(mute_enemies)
|
||||
EXTERN_CVAR(mute_spectators)
|
||||
EXTERN_CVAR(show_messages)
|
||||
EXTERN_CVAR(co_novileghosts)
|
||||
EXTERN_CVAR(sv_sharekeys)
|
||||
|
||||
extern std::string digest;
|
||||
extern bool forcenetdemosplit;
|
||||
|
|
@ -108,7 +111,7 @@ void G_PlayerReborn(player_t& p); // [Toke - todo] clean this function
|
|||
void P_DestroyButtonThinkers();
|
||||
void P_ExplodeMissile(AActor* mo);
|
||||
void P_PlayerLeavesGame(player_s* player);
|
||||
void P_SetPsprite(player_t* player, int position, statenum_t stnum);
|
||||
void P_SetPsprite(player_t* player, int position, int32_t stnum);
|
||||
void P_SetButtonTexture(line_t* line, short texture);
|
||||
|
||||
/**
|
||||
|
|
@ -200,7 +203,7 @@ static void CL_Disconnect(const odaproto::svc::Disconnect* msg)
|
|||
buffer = fmt::sprintf("Disconnected from server\n");
|
||||
}
|
||||
|
||||
Printf("%s", msg->message());
|
||||
PrintFmt("{}", msg->message());
|
||||
CL_QuitNetGame(NQ_SILENT);
|
||||
}
|
||||
|
||||
|
|
@ -212,7 +215,7 @@ static void CL_PlayerInfo(const odaproto::svc::PlayerInfo* msg)
|
|||
player_t& p = consoleplayer();
|
||||
|
||||
uint32_t weaponowned = msg->player().weaponowned();
|
||||
UnpackBoolArray(p.weaponowned, NUMWEAPONS, weaponowned);
|
||||
UnpackBoolArray(p.weaponowned.data(), NUMWEAPONS, weaponowned);
|
||||
|
||||
uint32_t cards = msg->player().cards();
|
||||
UnpackBoolArray(p.cards, NUMCARDS, cards);
|
||||
|
|
@ -504,7 +507,7 @@ static void CL_SpawnMobj(const odaproto::svc::SpawnMobj* msg)
|
|||
mobjtype_t type = static_cast<mobjtype_t>(msg->current().type());
|
||||
statenum_t state = static_cast<statenum_t>(msg->current().statenum());
|
||||
|
||||
if (type < MT_PLAYER || type >= NUMMOBJTYPES)
|
||||
if (!mobjinfo.contains(type))
|
||||
return;
|
||||
|
||||
P_ClearId(netid);
|
||||
|
|
@ -584,10 +587,12 @@ static void CL_SpawnMobj(const odaproto::svc::SpawnMobj* msg)
|
|||
(mo->target->oflags & hordeBossModMask))
|
||||
{
|
||||
mo->oflags |= MFO_FULLBRIGHT;
|
||||
mo->effects = FX_YELLOWFOUNTAIN;
|
||||
mo->effects |= FX_YELLOWFOUNTAIN;
|
||||
mo->translation = translationref_t(&::bosstable[0]);
|
||||
}
|
||||
|
||||
P_FriendlyEffects(mo);
|
||||
|
||||
AActor* tracer = NULL;
|
||||
if (bflags & baseline_t::TRACER)
|
||||
tracer = P_FindThingById(msg->current().tracerid());
|
||||
|
|
@ -627,7 +632,7 @@ static void CL_SpawnMobj(const odaproto::svc::SpawnMobj* msg)
|
|||
mo->tics = 1;
|
||||
}
|
||||
|
||||
if (state >= S_NULL && state < NUMSTATES)
|
||||
if(state >= S_NULL && states.contains(state))
|
||||
{
|
||||
P_SetMobjState(mo, state);
|
||||
}
|
||||
|
|
@ -674,12 +679,17 @@ static void CL_SpawnMobj(const odaproto::svc::SpawnMobj* msg)
|
|||
mo->flags = msg->current().flags();
|
||||
}
|
||||
|
||||
if (msg->spawn_flags() & SVC_SM_FLAGS2)
|
||||
{
|
||||
mo->flags2 = msg->current().flags2();
|
||||
}
|
||||
|
||||
if (msg->spawn_flags() & SVC_SM_OFLAGS)
|
||||
{
|
||||
mo->oflags = msg->current().oflags();
|
||||
|
||||
// [AM] HACK! Assume that any monster with a flag is a boss.
|
||||
if (mo->oflags)
|
||||
if (mo->oflags & hordeBossModMask)
|
||||
{
|
||||
mo->effects = FX_YELLOWFOUNTAIN;
|
||||
mo->translation = translationref_t(&::bosstable[0]);
|
||||
|
|
@ -695,7 +705,7 @@ static void CL_SpawnMobj(const odaproto::svc::SpawnMobj* msg)
|
|||
tics = -1;
|
||||
|
||||
// already spawned as gibs?
|
||||
if (!mo || mo->state - states == S_GIBS)
|
||||
if (!mo || mo->state == &states[S_GIBS])
|
||||
return;
|
||||
|
||||
if ((frame & FF_FRAMEMASK) >= sprites[mo->sprite].numframes)
|
||||
|
|
@ -787,9 +797,9 @@ static void CL_LoadMap(const odaproto::svc::LoadMap* msg)
|
|||
OWantFile file;
|
||||
if (!OWantFile::makeWithHash(file, name, OFILE_WAD, hash))
|
||||
{
|
||||
Printf(PRINT_WARNING,
|
||||
"Could not construct wanted file \"%s\" that server requested.\n",
|
||||
name);
|
||||
PrintFmt(PRINT_WARNING,
|
||||
"Could not construct wanted file \"{}\" that server requested.\n",
|
||||
name);
|
||||
CL_QuitNetGame(NQ_DISCONNECT);
|
||||
return;
|
||||
}
|
||||
|
|
@ -810,9 +820,9 @@ static void CL_LoadMap(const odaproto::svc::LoadMap* msg)
|
|||
OWantFile file;
|
||||
if (!OWantFile::makeWithHash(file, name, OFILE_DEH, hash))
|
||||
{
|
||||
Printf(PRINT_WARNING,
|
||||
"Could not construct wanted patch \"%s\" that server requested.\n",
|
||||
name);
|
||||
PrintFmt(PRINT_WARNING,
|
||||
"Could not construct wanted patch \"{}\" that server requested.\n",
|
||||
name);
|
||||
CL_QuitNetGame(NQ_DISCONNECT);
|
||||
return;
|
||||
}
|
||||
|
|
@ -830,7 +840,7 @@ static void CL_LoadMap(const odaproto::svc::LoadMap* msg)
|
|||
{
|
||||
if (::missingCommercialIWAD)
|
||||
{
|
||||
Printf(PRINT_WARNING, "Server requires commercial IWAD that was not found.\n");
|
||||
PrintFmt(PRINT_WARNING, "Server requires commercial IWAD that was not found.\n");
|
||||
CL_QuitNetGame(NQ_DISCONNECT);
|
||||
return;
|
||||
}
|
||||
|
|
@ -958,7 +968,7 @@ static void CL_UserInfo(const odaproto::svc::UserInfo* msg)
|
|||
|
||||
p->userinfo.gender = static_cast<gender_t>(msg->gender());
|
||||
if (p->userinfo.gender < 0 || p->userinfo.gender >= NUMGENDER)
|
||||
p->userinfo.gender = GENDER_NEUTER;
|
||||
p->userinfo.gender = GENDER_OTHER;
|
||||
|
||||
p->userinfo.color[0] = 255;
|
||||
p->userinfo.color[1] = msg->color().r();
|
||||
|
|
@ -1138,8 +1148,15 @@ static void CL_SpawnPlayer(const odaproto::svc::SpawnPlayer* msg)
|
|||
|
||||
// give all cards in death match mode
|
||||
if (!G_IsCoopGame())
|
||||
{
|
||||
for (size_t i = 0; i < NUMCARDS; i++)
|
||||
p->cards[i] = true;
|
||||
}
|
||||
else if (sv_sharekeys)
|
||||
{
|
||||
const uint32_t cards = msg->cards();
|
||||
UnpackBoolArray(p->cards, NUMCARDS, cards);
|
||||
}
|
||||
|
||||
if (p->id == consoleplayer_id)
|
||||
{
|
||||
|
|
@ -1305,6 +1322,48 @@ static void CL_KillMobj(const odaproto::svc::KillMobj* msg)
|
|||
P_KillMobj(source, target, inflictor, joinkill);
|
||||
}
|
||||
|
||||
//
|
||||
// CL_RaiseMobj
|
||||
//
|
||||
static void CL_RaiseMobj(const odaproto::svc::RaiseMobj* msg)
|
||||
{
|
||||
uint32_t srcid = msg->source_netid();
|
||||
uint32_t cpsid = msg->corpse().netid();
|
||||
|
||||
AActor* source = P_FindThingById(srcid);
|
||||
AActor* corpsehit = P_FindThingById(cpsid);
|
||||
|
||||
if (!corpsehit)
|
||||
return;
|
||||
|
||||
corpsehit->x = msg->corpse().pos().x();
|
||||
corpsehit->y = msg->corpse().pos().y();
|
||||
corpsehit->z = msg->corpse().pos().z();
|
||||
corpsehit->angle = msg->corpse().angle();
|
||||
corpsehit->momx = msg->corpse().mom().x();
|
||||
corpsehit->momy = msg->corpse().mom().y();
|
||||
corpsehit->momz = msg->corpse().mom().z();
|
||||
|
||||
mobjinfo_t* info = corpsehit->info;
|
||||
|
||||
P_SetMobjState(corpsehit, info->raisestate);
|
||||
|
||||
// [Nes] - Classic demo compatability: Ghost monster bug.
|
||||
if (co_novileghosts)
|
||||
{
|
||||
corpsehit->height = P_ThingInfoHeight(info); // [RH] Use real mobj height
|
||||
corpsehit->radius = info->radius; // [RH] Use real radius
|
||||
}
|
||||
else
|
||||
{
|
||||
corpsehit->height <<= 2;
|
||||
}
|
||||
|
||||
corpsehit->flags = info->flags;
|
||||
corpsehit->health = info->spawnhealth;
|
||||
corpsehit->target = AActor::AActorPtr();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
///// CL_Fire* called when someone uses a weapon /////////
|
||||
///////////////////////////////////////////////////////////
|
||||
|
|
@ -1320,7 +1379,7 @@ static void CL_FireWeapon(const odaproto::svc::FireWeapon* msg)
|
|||
weapontype_t firedweap = static_cast<weapontype_t>(msg->readyweapon());
|
||||
if (firedweap < 0 || firedweap > wp_nochange)
|
||||
{
|
||||
Printf("CL_FireWeapon: unknown weapon %d\n", firedweap);
|
||||
PrintFmt("CL_FireWeapon: unknown weapon {}\n", firedweap);
|
||||
return;
|
||||
}
|
||||
int servertic = msg->servertic();
|
||||
|
|
@ -1387,13 +1446,13 @@ static void CL_Print(const odaproto::svc::Print* msg)
|
|||
|
||||
// TODO : Clientchat moved, remove that but PRINT_SERVERCHAT
|
||||
if (level == PRINT_CHAT)
|
||||
Printf(level, "%c*%s", TEXTCOLOR_ESCAPE, str);
|
||||
PrintFmt(level, "{:c}*{}", TEXTCOLOR_ESCAPE, str);
|
||||
else if (level == PRINT_TEAMCHAT)
|
||||
Printf(level, "%c!%s", TEXTCOLOR_ESCAPE, str);
|
||||
PrintFmt(level, "{:c}!{}", TEXTCOLOR_ESCAPE, str);
|
||||
else if (level == PRINT_SERVERCHAT)
|
||||
Printf(level, "%s%s", TEXTCOLOR_YELLOW, str);
|
||||
PrintFmt(level, "{:s}{}", TEXTCOLOR_YELLOW, str);
|
||||
else
|
||||
Printf(level, "%s", str);
|
||||
PrintFmt(level, "{}", str);
|
||||
|
||||
if (show_messages)
|
||||
{
|
||||
|
|
@ -1814,9 +1873,9 @@ static void CL_Say(const odaproto::svc::Say* msg)
|
|||
if (message_visibility == 0)
|
||||
{
|
||||
if (strnicmp(message, "/me ", 4) == 0)
|
||||
Printf(publicmsg, "* %s %s\n", name, &message[4]);
|
||||
PrintFmt(publicmsg, "* {} {}\n", name, &message[4]);
|
||||
else
|
||||
Printf(publicmsg, "%s: %s\n", name, message);
|
||||
PrintFmt(publicmsg, "{}: {}\n", name, message);
|
||||
|
||||
if (show_messages && !filtermessage)
|
||||
{
|
||||
|
|
@ -1827,9 +1886,9 @@ static void CL_Say(const odaproto::svc::Say* msg)
|
|||
else if (message_visibility == 1)
|
||||
{
|
||||
if (strnicmp(message, "/me ", 4) == 0)
|
||||
Printf(publicteammsg, "* %s %s\n", name, &message[4]);
|
||||
PrintFmt(publicteammsg, "* {} {}\n", name, &message[4]);
|
||||
else
|
||||
Printf(publicteammsg, "%s: %s\n", name, message);
|
||||
PrintFmt(publicteammsg, "{}: {}\n", name, message);
|
||||
|
||||
if (show_messages && cl_chatsounds && !filtermessage)
|
||||
S_Sound(CHAN_INTERFACE, "misc/teamchat", 1, ATTN_NONE);
|
||||
|
|
@ -2006,10 +2065,8 @@ static void CL_SecretEvent(const odaproto::svc::SecretEvent* msg)
|
|||
if (!::hud_revealsecrets || ::hud_revealsecrets > 2)
|
||||
return;
|
||||
|
||||
std::string buf;
|
||||
buf = fmt::sprintf("%s%s %sfound a secret!\n", TEXTCOLOR_YELLOW,
|
||||
player.userinfo.netname, TEXTCOLOR_NORMAL);
|
||||
Printf("%s", buf);
|
||||
PrintFmt("{}{} {}found a secret!\n", TEXTCOLOR_YELLOW,
|
||||
player.userinfo.netname, TEXTCOLOR_NORMAL);
|
||||
|
||||
if (::hud_revealsecrets == 1)
|
||||
S_Sound(CHAN_INTERFACE, "misc/secret", 1, ATTN_NONE);
|
||||
|
|
@ -2090,7 +2147,7 @@ static void CL_ServerGametic(const odaproto::svc::ServerGametic* msg)
|
|||
::last_svgametic = newtic;
|
||||
|
||||
#ifdef _WORLD_INDEX_DEBUG_
|
||||
Printf(PRINT_HIGH, "Gametic %i, received world index %i\n", gametic, last_svgametic);
|
||||
PrintFmt(PRINT_HIGH, "Gametic {}, received world index {}\n", gametic, last_svgametic);
|
||||
#endif // _WORLD_INDEX_DEBUG_
|
||||
}
|
||||
|
||||
|
|
@ -2162,8 +2219,8 @@ static void CL_PlayerState(const odaproto::svc::PlayerState* msg)
|
|||
{
|
||||
if (i < msg->player().psprites_size())
|
||||
{
|
||||
unsigned int state = msg->player().psprites().Get(i).statenum();
|
||||
if (state >= NUMSTATES)
|
||||
const int32_t state = msg->player().psprites().Get(i).statenum();
|
||||
if (!states.contains(state))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
|
@ -2296,11 +2353,11 @@ static void CL_PlayerQueuePos(const odaproto::svc::PlayerQueuePos* msg)
|
|||
{
|
||||
if (queuePos > 0 && player.QueuePosition == 0)
|
||||
{
|
||||
Printf(PRINT_HIGH, "Position in line to play: %u\n", queuePos);
|
||||
PrintFmt(PRINT_HIGH, "Position in line to play: {}\n", queuePos);
|
||||
}
|
||||
else if (player.spectator && queuePos == 0 && player.QueuePosition > 0)
|
||||
{
|
||||
Printf(PRINT_HIGH, "You have been removed from the queue.\n");
|
||||
PrintFmt(PRINT_HIGH, "You have been removed from the queue.\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2396,6 +2453,7 @@ static void CL_SectorProperties(const odaproto::svc::SectorProperties* msg)
|
|||
sector->base_ceiling_yoffs = msg->sector().base_ceiling_yoffs();
|
||||
sector->base_floor_angle = msg->sector().base_floor_angle();
|
||||
sector->base_floor_yoffs = msg->sector().base_floor_yoffs();
|
||||
break;
|
||||
case SPC_Special:
|
||||
sector->special = msg->sector().special();
|
||||
default:
|
||||
|
|
@ -2449,7 +2507,7 @@ static void CL_SetMobjState(const odaproto::svc::MobjState* msg)
|
|||
AActor* mo = P_FindThingById(msg->netid());
|
||||
int s = msg->mostate();
|
||||
|
||||
if (mo == NULL || s < 0 || s >= NUMSTATES)
|
||||
if (mo == NULL || !states.contains(s))
|
||||
return;
|
||||
|
||||
P_SetMobjState(mo, static_cast<statenum_t>(s));
|
||||
|
|
@ -2574,7 +2632,7 @@ static void CL_ExecuteACSSpecial(const odaproto::svc::ExecuteACSSpecial* msg)
|
|||
break;
|
||||
|
||||
default:
|
||||
Printf(PRINT_HIGH, "Invalid ACS special: %d", special);
|
||||
PrintFmt(PRINT_HIGH, "Invalid ACS special: {}", special);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -3008,6 +3066,7 @@ parseError_e CL_ParseCommand()
|
|||
SV_MSG(svc_spawnplayer, CL_SpawnPlayer, odaproto::svc::SpawnPlayer);
|
||||
SV_MSG(svc_damageplayer, CL_DamagePlayer, odaproto::svc::DamagePlayer);
|
||||
SV_MSG(svc_killmobj, CL_KillMobj, odaproto::svc::KillMobj);
|
||||
SV_MSG(svc_raisemobj, CL_RaiseMobj, odaproto::svc::RaiseMobj);
|
||||
SV_MSG(svc_fireweapon, CL_FireWeapon, odaproto::svc::FireWeapon);
|
||||
SV_MSG(svc_updatesector, CL_UpdateSector, odaproto::svc::UpdateSector);
|
||||
SV_MSG(svc_print, CL_Print, odaproto::svc::Print);
|
||||
|
|
@ -3062,3 +3121,5 @@ parseError_e CL_ParseCommand()
|
|||
RecordProto(static_cast<svc_t>(cmd), msg);
|
||||
return PERR_OK;
|
||||
}
|
||||
|
||||
VERSION_CONTROL (cl_parse_cpp, "$Id$")
|
||||
|
|
|
|||
|
|
@ -32,8 +32,6 @@
|
|||
|
||||
#include "p_snapshot.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
EXTERN_CVAR (cl_prednudge)
|
||||
EXTERN_CVAR (cl_predictsectors)
|
||||
|
||||
|
|
|
|||
|
|
@ -182,7 +182,7 @@ void ClientReplay::itemReplay()
|
|||
continue;
|
||||
}
|
||||
|
||||
std::string weaponname = P_MobjToName(mo->type);
|
||||
std::string weaponname = P_MobjToName(static_cast<mobjtype_t>(mo->type));
|
||||
weapontype_t weapontype = P_NameToWeapon(weaponname);
|
||||
bool weaponSwitch = P_CheckSwitchWeapon(&player, weapontype);
|
||||
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@
|
|||
#include "d_player.h"
|
||||
#include "m_fixed.h"
|
||||
#include "r_defs.h"
|
||||
#include <map>
|
||||
|
||||
class ClientReplay
|
||||
{
|
||||
|
|
|
|||
|
|
@ -41,34 +41,35 @@ void D_WriteUserInfoStrings(int i, byte **stream, bool compact) {}
|
|||
void D_ReadUserInfoStrings(int i, byte **stream, bool update) {}
|
||||
|
||||
void SV_SpawnMobj(AActor *mobj) {}
|
||||
void SV_TouchSpecial(AActor *special, player_t *player) {}
|
||||
void SV_TouchSpecial(const AActor *special, player_t *player) {}
|
||||
ItemEquipVal SV_FlagTouch (player_t &player, team_t f, bool firstgrab) { return IEV_NotEquipped; }
|
||||
void SV_SocketTouch (player_t &player, team_t f) {}
|
||||
void SV_SendKillMobj(AActor *source, AActor *target, AActor *inflictor, bool joinkill) {}
|
||||
void SV_SendDamagePlayer(player_t *player, AActor* inflictor, int healthDamage, int armorDamage) {}
|
||||
void SV_SendDamageMobj(AActor *target, int pain) {}
|
||||
void SV_SendKillMobj(const AActor *source, const AActor *target, const AActor *inflictor, bool joinkill) {}
|
||||
void SV_SendRaiseMobj(const AActor* source, const AActor* corpse) { }
|
||||
void SV_SendDamagePlayer(player_t *player, const AActor* inflictor, int healthDamage, int armorDamage) {}
|
||||
void SV_SendDamageMobj(const AActor *target, int pain) {}
|
||||
void SV_CTFEvent(team_t f, flag_score_t event, player_t &who) {}
|
||||
void SV_UpdateFrags(player_t &player) {}
|
||||
void SV_ActorTarget(AActor *actor) {}
|
||||
void SV_SendDestroyActor(AActor *mo) {}
|
||||
void SV_ExplodeMissile(AActor *mo) {}
|
||||
void SV_ActorTarget(const AActor *actor) {}
|
||||
void SV_SendDestroyActor(const AActor *mo) {}
|
||||
void SV_ExplodeMissile(const AActor *mo) {}
|
||||
void SV_SendPlayerInfo(player_t &player) {}
|
||||
void SV_PreservePlayer(player_t &player) {}
|
||||
void SV_BroadcastSector(int sectornum) {}
|
||||
void SV_UpdateMobj(AActor* mo) {}
|
||||
void SV_UpdateMobjState(AActor* mo) {}
|
||||
void SV_UpdateMobj(const AActor* mo) {}
|
||||
void SV_UpdateMobjState(const AActor* mo) {}
|
||||
|
||||
void CTF_RememberFlagPos(mapthing2_t *mthing) {}
|
||||
void CTF_SpawnFlag(team_t f) {}
|
||||
bool SV_AwarenessUpdate(player_t &pl, AActor* mo) { return true; }
|
||||
void SV_SendPackets(void) {}
|
||||
void SV_SendExecuteLineSpecial(byte special, line_t* line, AActor* activator, int arg0,
|
||||
void SV_SendExecuteLineSpecial(byte special, const line_t* line, const AActor* activator, int arg0,
|
||||
int arg1, int arg2, int arg3, int arg4)
|
||||
{
|
||||
}
|
||||
|
||||
void SV_UpdateMonsterRespawnCount() {}
|
||||
void SV_Sound(AActor* mo, byte channel, const char* name, byte attenuation) {}
|
||||
void SV_Sound(const AActor* mo, byte channel, const char* name, byte attenuation) {}
|
||||
|
||||
|
||||
CVAR_FUNC_IMPL(sv_sharekeys) {}
|
||||
|
|
|
|||
|
|
@ -35,6 +35,10 @@
|
|||
#include "i_net.h"
|
||||
#include "i_system.h"
|
||||
|
||||
#include "s_sound.h"
|
||||
#include "c_cvars.h"
|
||||
EXTERN_CVAR(snd_votesfx)
|
||||
|
||||
//////// VOTING STATE ////////
|
||||
|
||||
// Return a singleton reference for the class.
|
||||
|
|
@ -43,7 +47,14 @@ VoteState& VoteState::instance() {
|
|||
return singleton;
|
||||
}
|
||||
|
||||
void VoteState::set(const vote_state_t &vote_state) {
|
||||
void VoteState::set(const vote_state_t& vote_state)
|
||||
{
|
||||
// capture previous state BEFORE overwriting
|
||||
const bool was_visible = this->visible;
|
||||
const auto prev_result = this->result;
|
||||
const auto prev_votestring = this->votestring;
|
||||
|
||||
// overwrite with new state
|
||||
this->visible = true;
|
||||
this->result = vote_state.result;
|
||||
this->votestring = vote_state.votestring;
|
||||
|
|
@ -54,6 +65,34 @@ void VoteState::set(const vote_state_t &vote_state) {
|
|||
this->no = vote_state.no;
|
||||
this->no_needed = vote_state.no_needed;
|
||||
this->abs = vote_state.abs;
|
||||
|
||||
// [RV] Play "start" when the vote first appears or the prompt changed
|
||||
const bool votestring_changed = (prev_votestring != vote_state.votestring);
|
||||
if (!was_visible || votestring_changed)
|
||||
{
|
||||
if (snd_votesfx)
|
||||
S_Sound(CHAN_INTERFACE, "ui/vote/start", 1.0f, ATTN_NONE);
|
||||
}
|
||||
|
||||
// [RV] Play "pass/fail" exactly once when result becomes decided
|
||||
if (prev_result == VOTE_UNDEC && vote_state.result != VOTE_UNDEC)
|
||||
{
|
||||
switch (vote_state.result)
|
||||
{
|
||||
case VOTE_YES:
|
||||
if (snd_votesfx)
|
||||
S_Sound(CHAN_INTERFACE, "ui/vote/pass", 1.0f, ATTN_NONE);
|
||||
break;
|
||||
case VOTE_NO:
|
||||
case VOTE_INTERRUPT:
|
||||
case VOTE_ABANDON:
|
||||
if (snd_votesfx)
|
||||
S_Sound(CHAN_INTERFACE, "ui/vote/fail", 1.0f, ATTN_NONE);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool VoteState::get(vote_state_t &vote_state) {
|
||||
|
|
@ -93,7 +132,7 @@ bool VoteState::get(vote_state_t &vote_state) {
|
|||
//////// CALLBACKS & ERRBACKS ////////
|
||||
|
||||
void CMD_MapVoteErrback(const std::string &error) {
|
||||
Printf(PRINT_HIGH, "callvote failed: %s\n", error);
|
||||
PrintFmt(PRINT_HIGH, "callvote failed: {}\n", error);
|
||||
}
|
||||
|
||||
void CMD_MapVoteCallback(const maplist_qrows_t &result) {
|
||||
|
|
@ -118,7 +157,7 @@ void CMD_MapVoteCallback(const maplist_qrows_t &result) {
|
|||
}
|
||||
|
||||
void CMD_RandmapVoteErrback(const std::string &error) {
|
||||
Printf(PRINT_HIGH, "callvote failed: %s\n", error);
|
||||
PrintFmt(PRINT_HIGH, "callvote failed: {}\n", error);
|
||||
}
|
||||
|
||||
void CMD_RandmapVoteCallback(const maplist_qrows_t &result) {
|
||||
|
|
@ -145,7 +184,7 @@ void CMD_RandmapVoteCallback(const maplist_qrows_t &result) {
|
|||
BEGIN_COMMAND(callvote) {
|
||||
// Dumb question, but are we even connected to a server?
|
||||
if (!connected) {
|
||||
Printf(PRINT_HIGH, "callvote failed: You are not connected to a server.\n");
|
||||
PrintFmt(PRINT_HIGH, "callvote failed: You are not connected to a server.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -169,7 +208,7 @@ BEGIN_COMMAND(callvote) {
|
|||
|
||||
if (votecmd == VOTE_NONE) {
|
||||
// We passed an argument but it wasn't a valid vote type.
|
||||
Printf(PRINT_HIGH, "callvote failed: Invalid vote \"%s\".\n", votecmd_s);
|
||||
PrintFmt(PRINT_HIGH, "callvote failed: Invalid vote \"{}\".\n", votecmd_s);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -203,7 +242,7 @@ BEGIN_COMMAND(callvote) {
|
|||
case VOTE_MAP:
|
||||
// If we have no arguments, ask for more.
|
||||
if (arguments.empty()) {
|
||||
Printf(PRINT_HIGH, "callvote failed: \"map\" callvote needs a maplist index or unambiguous map name.\n");
|
||||
PrintFmt(PRINT_HIGH, "callvote failed: \"map\" callvote needs a maplist index or unambiguous map name.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -241,7 +280,7 @@ BEGIN_COMMAND(vote_yes)
|
|||
{
|
||||
if (!connected)
|
||||
{
|
||||
Printf(PRINT_HIGH, "vote failed: You are not connected to a server.\n");
|
||||
PrintFmt(PRINT_HIGH, "vote failed: You are not connected to a server.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -249,6 +288,9 @@ BEGIN_COMMAND(vote_yes)
|
|||
MSG_WriteString(&net_buffer, "vote");
|
||||
MSG_WriteByte(&net_buffer, 1);
|
||||
MSG_WriteString(&net_buffer, "yes");
|
||||
|
||||
if (snd_votesfx)
|
||||
S_Sound(CHAN_INTERFACE, "ui/vote/yes", 1.0f, ATTN_NONE);
|
||||
}
|
||||
END_COMMAND(vote_yes)
|
||||
|
||||
|
|
@ -259,7 +301,7 @@ BEGIN_COMMAND(vote_no)
|
|||
{
|
||||
if (!connected)
|
||||
{
|
||||
Printf(PRINT_HIGH, "vote failed: You are not connected to a server.\n");
|
||||
PrintFmt(PRINT_HIGH, "vote failed: You are not connected to a server.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -267,5 +309,8 @@ BEGIN_COMMAND(vote_no)
|
|||
MSG_WriteString(&net_buffer, "vote");
|
||||
MSG_WriteByte(&net_buffer, 1);
|
||||
MSG_WriteString(&net_buffer, "no");
|
||||
|
||||
if (snd_votesfx)
|
||||
S_Sound(CHAN_INTERFACE, "ui/vote/no", 1.0f, ATTN_NONE);
|
||||
}
|
||||
END_COMMAND(vote_no)
|
||||
|
|
|
|||
|
|
@ -84,15 +84,10 @@
|
|||
#include "g_horde.h"
|
||||
#include "w_ident.h"
|
||||
#include "gui_boot.h"
|
||||
#include "g_musinfo.h"
|
||||
#include "g_episode.h"
|
||||
|
||||
#ifdef GEKKO
|
||||
#include "i_wii.h"
|
||||
#endif
|
||||
|
||||
#ifdef _XBOX
|
||||
#include "i_xbox.h"
|
||||
#endif
|
||||
extern size_t got_heapsize;
|
||||
|
||||
void D_CheckNetGame();
|
||||
void D_ProcessEvents();
|
||||
|
|
@ -154,9 +149,9 @@ void D_SetPlatform(void)
|
|||
#ifdef GCONSOLE
|
||||
#ifdef _XBOX
|
||||
platform = PF_XBOX;
|
||||
#elif GEKKO
|
||||
#elif defined(GEKKO)
|
||||
platform = PF_WII;
|
||||
#elif __SWITCH__
|
||||
#elif defined(__SWITCH__)
|
||||
platform = PF_SWITCH;
|
||||
#else
|
||||
platform = PF_UNKNOWN;
|
||||
|
|
@ -364,7 +359,7 @@ void D_DoomLoop()
|
|||
}
|
||||
catch (CRecoverableError &error)
|
||||
{
|
||||
Printf(PRINT_ERROR, "\nERROR: %s\n", error.GetMsg());
|
||||
PrintFmt(PRINT_ERROR, "\nERROR: {}\n", error.GetMsg());
|
||||
|
||||
// [AM] In case an error is caused by a console command.
|
||||
C_ClearCommand();
|
||||
|
|
@ -595,6 +590,77 @@ bool HashOk(std::string &required, std::string &available)
|
|||
|
||||
void CL_NetDemoPlay(const std::string &filename);
|
||||
|
||||
EXTERN_CVAR(co_boomphys)
|
||||
EXTERN_CVAR(co_zdoomphys)
|
||||
EXTERN_CVAR(co_mbfphys)
|
||||
EXTERN_CVAR(co_zdoomammo)
|
||||
EXTERN_CVAR(co_novileghosts)
|
||||
EXTERN_CVAR(co_removesoullimit)
|
||||
EXTERN_CVAR(co_allowdropoff)
|
||||
EXTERN_CVAR(r_clipmaskedspecial)
|
||||
EXTERN_CVAR(r_thingsectorlight)
|
||||
|
||||
void G_ReadCOMPLVL()
|
||||
{
|
||||
if (!serverside)
|
||||
return;
|
||||
|
||||
int lumpnum = W_CheckNumForName("COMPLVL");
|
||||
if (lumpnum != -1)
|
||||
{
|
||||
char* complvl = static_cast<char*>(W_CacheLumpNum(lumpnum, PU_STATIC));
|
||||
|
||||
co_zdoomphys.Set(0.0f);
|
||||
co_zdoomammo.Set(0.0f);
|
||||
|
||||
if (iequals("vanilla", complvl))
|
||||
{
|
||||
co_boomphys.Set(0.0f);
|
||||
co_mbfphys.Set(0.0f);
|
||||
co_novileghosts.Set(0.0f);
|
||||
co_allowdropoff.Set(0.0f);
|
||||
co_removesoullimit.Set(0.0f);
|
||||
r_clipmaskedspecial.Set(0.0f);
|
||||
r_thingsectorlight.Set(0.0f);
|
||||
}
|
||||
else if (iequals("boom", complvl))
|
||||
{
|
||||
co_boomphys.Set(1.0f);
|
||||
co_mbfphys.Set(0.0f);
|
||||
co_novileghosts.Set(1.0f);
|
||||
co_allowdropoff.Set(1.0f);
|
||||
co_removesoullimit.Set(1.0f);
|
||||
r_clipmaskedspecial.Set(0.0f);
|
||||
r_thingsectorlight.Set(0.0f);
|
||||
}
|
||||
else if (iequals("mbf", complvl))
|
||||
{
|
||||
co_boomphys.Set(1.0f);
|
||||
co_mbfphys.Set(1.0f);
|
||||
co_novileghosts.Set(1.0f);
|
||||
co_allowdropoff.Set(1.0f);
|
||||
co_removesoullimit.Set(1.0f);
|
||||
r_clipmaskedspecial.Set(0.0f);
|
||||
r_thingsectorlight.Set(1.0f);
|
||||
}
|
||||
else if (iequals("mbf21", complvl))
|
||||
{
|
||||
co_boomphys.Set(1.0f);
|
||||
co_mbfphys.Set(1.0f);
|
||||
co_novileghosts.Set(1.0f);
|
||||
co_allowdropoff.Set(1.0f);
|
||||
co_removesoullimit.Set(1.0f);
|
||||
r_clipmaskedspecial.Set(1.0f);
|
||||
r_thingsectorlight.Set(0.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
DPrintFmt("Unrecognized COMPLVL value: {}", complvl);
|
||||
}
|
||||
|
||||
Z_Free(complvl);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// D_Init
|
||||
|
|
@ -616,18 +682,14 @@ void D_Init()
|
|||
// start the Zone memory manager
|
||||
Z_Init();
|
||||
if (first_time)
|
||||
Printf("Z_Init: Using native allocator with OZone bookkeeping.\n");
|
||||
PrintFmt("Z_Init: Using native allocator with OZone bookkeeping.\n");
|
||||
|
||||
// Load palette and set up colormaps
|
||||
V_Init();
|
||||
|
||||
// if (first_time)
|
||||
// Printf(PRINT_HIGH, "Res_InitTextureManager: Init image resource management.\n");
|
||||
// Res_InitTextureManager();
|
||||
|
||||
// init the renderer
|
||||
if (first_time)
|
||||
Printf(PRINT_HIGH, "R_Init: Init DOOM refresh daemon.\n");
|
||||
PrintFmt(PRINT_HIGH, "R_Init: Init DOOM refresh daemon.\n");
|
||||
R_Init();
|
||||
|
||||
// V_LoadFonts();
|
||||
|
|
@ -642,31 +704,30 @@ void D_Init()
|
|||
G_ParseMusInfo();
|
||||
S_ParseSndInfo();
|
||||
G_ParseHordeDefs();
|
||||
G_ReadCOMPLVL();
|
||||
|
||||
// init the menu subsystem
|
||||
if (first_time)
|
||||
Printf(PRINT_HIGH, "M_Init: Init miscellaneous info.\n");
|
||||
PrintFmt(PRINT_HIGH, "M_Init: Init miscellaneous info.\n");
|
||||
M_Init();
|
||||
|
||||
if (first_time)
|
||||
Printf(PRINT_HIGH, "P_Init: Init Playloop state.\n");
|
||||
PrintFmt(PRINT_HIGH, "P_Init: Init Playloop state.\n");
|
||||
P_InitEffects();
|
||||
P_Init();
|
||||
|
||||
// init sound and music
|
||||
if (first_time)
|
||||
{
|
||||
Printf (PRINT_HIGH, "S_Init: Setting up sound.\n");
|
||||
Printf (PRINT_HIGH, "S_Init: default sfx volume is %g\n", (float)snd_sfxvolume);
|
||||
Printf (PRINT_HIGH, "S_Init: default music volume is %g\n", (float)snd_musicvolume);
|
||||
PrintFmt(PRINT_HIGH, "S_Init: Setting up sound.\n");
|
||||
PrintFmt(PRINT_HIGH, "S_Init: default sfx volume is {:g}\n", snd_sfxvolume.value());
|
||||
PrintFmt(PRINT_HIGH, "S_Init: default music volume is {:g}\n", snd_musicvolume.value());
|
||||
}
|
||||
S_Init(snd_sfxvolume, snd_musicvolume);
|
||||
|
||||
// R_InitViewBorder();
|
||||
|
||||
// init the status bar
|
||||
if (first_time)
|
||||
Printf(PRINT_HIGH, "ST_Init: Init status bar.\n");
|
||||
PrintFmt(PRINT_HIGH, "ST_Init: Init status bar.\n");
|
||||
ST_Init();
|
||||
|
||||
first_time = false;
|
||||
|
|
@ -696,6 +757,7 @@ void STACK_ARGS D_Shutdown()
|
|||
// stop sound effects and music
|
||||
S_Stop();
|
||||
S_Deinit();
|
||||
S_ClearSoundLumps();
|
||||
|
||||
// shutdown automap
|
||||
AM_Stop();
|
||||
|
|
@ -738,7 +800,6 @@ void STACK_ARGS D_Shutdown()
|
|||
|
||||
|
||||
void C_DoCommand(std::string_view cmd, uint32_t key);
|
||||
void D_Init_DEHEXTRA_Frames(void);
|
||||
|
||||
//
|
||||
// D_DoomMain
|
||||
|
|
@ -757,10 +818,7 @@ void D_DoomMain()
|
|||
|
||||
W_SetupFileIdentifiers();
|
||||
|
||||
// [RH] Initialize items. Still only used for the give command. :-(
|
||||
InitItems();
|
||||
// Initialize all extra frames
|
||||
D_Init_DEHEXTRA_Frames();
|
||||
D_InitializeDoomObjectTables();
|
||||
|
||||
M_FindResponseFile(); // [ML] 23/1/07 - Add Response file support back in
|
||||
|
||||
|
|
@ -851,15 +909,17 @@ void D_DoomMain()
|
|||
D_AddWadCommandLineFiles(newwadfiles);
|
||||
D_AddDehCommandLineFiles(newpatchfiles);
|
||||
|
||||
// do the deh processing
|
||||
D_LoadResourceFiles(newwadfiles, newpatchfiles);
|
||||
|
||||
Printf(PRINT_HIGH, "I_Init: Init hardware.\n");
|
||||
PrintFmt(PRINT_HIGH, "I_Init: Init hardware.\n");
|
||||
atterm(I_ShutdownHardware);
|
||||
I_Init();
|
||||
I_InitInput();
|
||||
|
||||
// [SL] Call init routines that need to be reinitialized every time WAD changes
|
||||
atterm(D_Shutdown);
|
||||
// initialize
|
||||
D_Init();
|
||||
|
||||
atterm(I_Endoom);
|
||||
|
|
@ -868,17 +928,17 @@ void D_DoomMain()
|
|||
cvar_t::EnableCallbacks();
|
||||
|
||||
// [RH] User-configurable startup strings. Because BOOM does.
|
||||
if (GStrings(STARTUP1)[0]) Printf(PRINT_HIGH, "%s\n", GStrings(STARTUP1));
|
||||
if (GStrings(STARTUP2)[0]) Printf(PRINT_HIGH, "%s\n", GStrings(STARTUP2));
|
||||
if (GStrings(STARTUP3)[0]) Printf(PRINT_HIGH, "%s\n", GStrings(STARTUP3));
|
||||
if (GStrings(STARTUP4)[0]) Printf(PRINT_HIGH, "%s\n", GStrings(STARTUP4));
|
||||
if (GStrings(STARTUP5)[0]) Printf(PRINT_HIGH, "%s\n", GStrings(STARTUP5));
|
||||
if (GStrings(STARTUP1)[0]) PrintFmt(PRINT_HIGH, "{}\n", GStrings(STARTUP1));
|
||||
if (GStrings(STARTUP2)[0]) PrintFmt(PRINT_HIGH, "{}\n", GStrings(STARTUP2));
|
||||
if (GStrings(STARTUP3)[0]) PrintFmt(PRINT_HIGH, "{}\n", GStrings(STARTUP3));
|
||||
if (GStrings(STARTUP4)[0]) PrintFmt(PRINT_HIGH, "{}\n", GStrings(STARTUP4));
|
||||
if (GStrings(STARTUP5)[0]) PrintFmt(PRINT_HIGH, "{}\n", GStrings(STARTUP5));
|
||||
|
||||
// developer mode
|
||||
devparm = Args.CheckParm("-devparm");
|
||||
|
||||
if (devparm)
|
||||
Printf(PRINT_HIGH, "%s", GStrings(D_DEVSTR)); // D_DEVSTR
|
||||
PrintFmt(PRINT_HIGH, "{}", GStrings(D_DEVSTR)); // D_DEVSTR
|
||||
|
||||
// set the default value for vid_ticker based on the presence of -devparm
|
||||
if (devparm)
|
||||
|
|
@ -946,7 +1006,7 @@ void D_DoomMain()
|
|||
CL_DownloadInit();
|
||||
atterm(CL_DownloadShutdown);
|
||||
|
||||
Printf(PRINT_HIGH, "D_CheckNetGame: Checking network game status.\n");
|
||||
PrintFmt(PRINT_HIGH, "D_CheckNetGame: Checking network game status.\n");
|
||||
D_CheckNetGame();
|
||||
|
||||
// [RH] Lock any cvars that should be locked now that we're
|
||||
|
|
@ -972,7 +1032,7 @@ void D_DoomMain()
|
|||
p = Args.CheckParm("+playdemo");
|
||||
if (p && p < Args.NumArgs() - 1)
|
||||
{
|
||||
Printf(PRINT_HIGH, "Playdemo parameter found on command line.\n");
|
||||
PrintFmt(PRINT_HIGH, "Playdemo parameter found on command line.\n");
|
||||
singledemo = true;
|
||||
|
||||
extern std::string defdemoname;
|
||||
|
|
|
|||
|
|
@ -69,16 +69,16 @@ CVAR_FUNC_IMPL(cl_name)
|
|||
var.Set(newname.c_str());
|
||||
}
|
||||
|
||||
|
||||
|
||||
gender_t D_GenderByName (const char *gender)
|
||||
{
|
||||
if (!stricmp (gender, "female"))
|
||||
return GENDER_FEMALE;
|
||||
else if (!stricmp (gender, "cyborg"))
|
||||
return GENDER_NEUTER;
|
||||
else
|
||||
else if (!stricmp (gender, "male"))
|
||||
return GENDER_MALE;
|
||||
else if (!stricmp (gender, "cyborg"))
|
||||
return GENDER_CYBORG;
|
||||
else
|
||||
return GENDER_OTHER;
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
|||
|
|
@ -558,11 +558,11 @@ void HU_Drawer()
|
|||
mousegraph.draw(hud_mousegraph);
|
||||
|
||||
if (idmypos && gamestate == GS_LEVEL)
|
||||
Printf (PRINT_HIGH, "ang=%d;x,y,z=(%d,%d,%d)\n",
|
||||
displayplayer().camera->angle/FRACUNIT,
|
||||
displayplayer().camera->x/FRACUNIT,
|
||||
displayplayer().camera->y/FRACUNIT,
|
||||
displayplayer().camera->z/FRACUNIT);
|
||||
PrintFmt(PRINT_HIGH, "ang={};x,y,z=({},{},{})\n",
|
||||
displayplayer().camera->angle/FRACUNIT,
|
||||
displayplayer().camera->x/FRACUNIT,
|
||||
displayplayer().camera->y/FRACUNIT,
|
||||
displayplayer().camera->z/FRACUNIT);
|
||||
|
||||
// Draw Netdemo info
|
||||
hud::drawNetdemo();
|
||||
|
|
@ -666,7 +666,7 @@ BEGIN_COMMAND (say_to)
|
|||
player_t &player = nameplayer(argv[1]);
|
||||
if (!validplayer(player))
|
||||
{
|
||||
Printf(PRINT_HIGH, "%s isn't the name of anybody on the server.\n", argv[1]);
|
||||
PrintFmt(PRINT_HIGH, "{} isn't the name of anybody on the server.\n", argv[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -2159,7 +2159,7 @@ void HU_ConsoleScores(player_t *player)
|
|||
}
|
||||
}
|
||||
|
||||
Printf(PRINT_HIGH, "\n");
|
||||
PrintFmt(PRINT_HIGH, "\n");
|
||||
|
||||
C_ToggleConsole();
|
||||
}
|
||||
|
|
@ -2169,7 +2169,7 @@ BEGIN_COMMAND (displayscores)
|
|||
if (multiplayer)
|
||||
HU_ConsoleScores(&consoleplayer());
|
||||
else
|
||||
Printf(PRINT_HIGH, "This command is only used for multiplayer games.");
|
||||
PrintFmt(PRINT_HIGH, "This command is only used for multiplayer games.");
|
||||
}
|
||||
END_COMMAND (displayscores)
|
||||
|
||||
|
|
|
|||
|
|
@ -55,10 +55,6 @@
|
|||
#include "g_skill.h"
|
||||
#include "m_fileio.h"
|
||||
|
||||
#ifdef _XBOX
|
||||
#include "i_xbox.h"
|
||||
#endif
|
||||
|
||||
EXTERN_CVAR(g_resetinvonexit)
|
||||
|
||||
// temp for screenblocks (0-9)
|
||||
|
|
@ -1276,7 +1272,7 @@ void M_QuitDOOM(int choice)
|
|||
|
||||
void M_DrawSlider(int x, int y, float leftval, float rightval, float cur, float step);
|
||||
|
||||
static const char *genders[3] = { "male", "female", "cyborg" };
|
||||
static const char *genders[4] = { "male", "female", "cyborg", "other" };
|
||||
// Acts 19 quiz the order must match d_netinf.h
|
||||
static const char *colorpresets[11] = { "custom", "blue", "indigo", "green", "brown", "red", "gold", "jungle green", "purple", "white", "black" };
|
||||
static state_t *PlayerState;
|
||||
|
|
@ -1540,7 +1536,7 @@ static void M_PlayerSetupDrawer()
|
|||
}
|
||||
}
|
||||
{
|
||||
const int spritenum = states[mobjinfo[MT_PLAYER].spawnstate].sprite;
|
||||
const int32_t spritenum = states[mobjinfo[MT_PLAYER].spawnstate].sprite;
|
||||
const spriteframe_t* sprframe = &sprites[spritenum].spriteframes[PlayerState->frame & FF_FRAMEMASK];
|
||||
|
||||
// [Nes] Color of player preview uses the unused translation table (player 0), instead
|
||||
|
|
@ -1628,7 +1624,7 @@ void M_ChangeTeam (int choice) // [Toke - Teams]
|
|||
int iTeam = (int)team;
|
||||
if (choice)
|
||||
{
|
||||
iTeam = ++iTeam % NUMTEAMS;
|
||||
iTeam = (iTeam + 1) % NUMTEAMS;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1643,12 +1639,13 @@ void M_ChangeTeam (int choice) // [Toke - Teams]
|
|||
|
||||
static void M_ChangeGender (int choice)
|
||||
{
|
||||
static constexpr int MAX_GENDER = ARRAY_LENGTH(genders) - 1;
|
||||
int gender = D_GenderByName(cl_gender.cstring());
|
||||
|
||||
if (!choice)
|
||||
gender = (gender == 0) ? 2 : gender - 1;
|
||||
gender = (gender == 0) ? MAX_GENDER : gender - 1;
|
||||
else
|
||||
gender = (gender == 2) ? 0 : gender + 1;
|
||||
gender = (gender == MAX_GENDER) ? 0 : gender + 1;
|
||||
|
||||
cl_gender = genders[gender];
|
||||
}
|
||||
|
|
@ -1683,13 +1680,14 @@ static void M_ChangeAutoAim (int choice)
|
|||
|
||||
static void M_ChangeColorPreset (int choice)
|
||||
{
|
||||
static constexpr int MAX_PRESET = ARRAY_LENGTH(colorpresets) - 1;
|
||||
int colorpreset = D_ColorPreset(cl_colorpreset.cstring());
|
||||
argb_t customcolor = V_GetColorFromString(cl_customcolor);
|
||||
|
||||
if (!choice)
|
||||
colorpreset = (colorpreset == 0) ? 10 : colorpreset - 1;
|
||||
colorpreset = (colorpreset == 0) ? MAX_PRESET : colorpreset - 1;
|
||||
else
|
||||
colorpreset = (colorpreset == 10) ? 0 : colorpreset + 1;
|
||||
colorpreset = (colorpreset == MAX_PRESET) ? 0 : colorpreset + 1;
|
||||
|
||||
cl_colorpreset = colorpresets[colorpreset];
|
||||
|
||||
|
|
@ -2369,7 +2367,7 @@ size_t M_FindCvarInMenu(cvar_t &cvar, menuitem_t *menu, size_t length)
|
|||
}
|
||||
}
|
||||
|
||||
return MAXINT; // indicate not found
|
||||
return limits::MAXINT; // indicate not found
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ void STACK_ARGS M_SaveDefaults(std::string filename)
|
|||
|
||||
fclose(f);
|
||||
|
||||
Printf(PRINT_HIGH, "Configuration saved to %s.\n", configfile);
|
||||
PrintFmt(PRINT_HIGH, "Configuration saved to {}.\n", configfile);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -214,7 +214,7 @@ void M_LoadDefaults(void)
|
|||
}
|
||||
|
||||
if (updated)
|
||||
Printf("%s: Updating old defaults.\n", __FUNCTION__);
|
||||
PrintFmt("{}: Updating old defaults.\n", __FUNCTION__);
|
||||
|
||||
AddCommandString("alias ? help");
|
||||
|
||||
|
|
|
|||
|
|
@ -125,6 +125,7 @@ EXTERN_CVAR(hud_extendedinfo)
|
|||
|
||||
// [Ralphis - Menu] Compatibility Menu
|
||||
EXTERN_CVAR (co_allowdropoff)
|
||||
EXTERN_CVAR (co_pursuit)
|
||||
EXTERN_CVAR (co_realactorheight)
|
||||
EXTERN_CVAR (co_zdoomphys)
|
||||
EXTERN_CVAR (co_zdoomsound)
|
||||
|
|
@ -135,6 +136,14 @@ EXTERN_CVAR (co_fineautoaim)
|
|||
EXTERN_CVAR (co_nosilentspawns)
|
||||
EXTERN_CVAR (co_boomphys) // [ML] Roll-up of various compat options
|
||||
EXTERN_CVAR (co_mbfphys)
|
||||
EXTERN_CVAR (co_helpfriends)
|
||||
EXTERN_CVAR (co_monsterbacking)
|
||||
EXTERN_CVAR (co_monsterfriction)
|
||||
EXTERN_CVAR (co_avoidhazards)
|
||||
EXTERN_CVAR (co_monstersclimbsteep)
|
||||
EXTERN_CVAR (co_staylift)
|
||||
EXTERN_CVAR (co_friend_ledgejumping)
|
||||
EXTERN_CVAR (co_friend_distance)
|
||||
EXTERN_CVAR (co_removesoullimit)
|
||||
EXTERN_CVAR (co_blockmapfix)
|
||||
EXTERN_CVAR (co_globalsound)
|
||||
|
|
@ -167,6 +176,7 @@ EXTERN_CVAR (snd_gamesfx)
|
|||
EXTERN_CVAR (snd_voxtype)
|
||||
EXTERN_CVAR (cl_connectalert)
|
||||
EXTERN_CVAR (cl_disconnectalert)
|
||||
EXTERN_CVAR (snd_votesfx)
|
||||
|
||||
// Joystick menu -- Hyper_Eye
|
||||
void JoystickSetup (void);
|
||||
|
|
@ -183,11 +193,6 @@ EXTERN_CVAR (joy_freelook)
|
|||
EXTERN_CVAR (joy_deadzone)
|
||||
|
||||
// Network Options
|
||||
EXTERN_CVAR (cl_interp)
|
||||
EXTERN_CVAR (cl_prednudge)
|
||||
EXTERN_CVAR (cl_predictpickup)
|
||||
EXTERN_CVAR (cl_predictsectors)
|
||||
EXTERN_CVAR (cl_predictweapons)
|
||||
EXTERN_CVAR (cl_serverdownload)
|
||||
|
||||
// Demo Options
|
||||
|
|
@ -335,7 +340,7 @@ menu_t OptionMenu = {
|
|||
*=======================================*/
|
||||
|
||||
static menuitem_t ControlsItems[] = {
|
||||
#ifdef _XBOX
|
||||
#ifdef GCONSOLE
|
||||
{ whitetext,"A to change, START to clear", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} },
|
||||
#else
|
||||
{ whitetext,"ENTER to change, BACKSPACE to clear", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} },
|
||||
|
|
@ -516,14 +521,6 @@ static menuitem_t JoystickItems[] =
|
|||
{ slider , "Turn Sensitivity" , {&joy_sensitivity}, {1.0}, {30.0}, {1.0}, {NULL} },
|
||||
{ slider , "Alt. Turn Sensitivity" , {&joy_fastsensitivity}, {1.0}, {30.0}, {1.0}, {NULL} },
|
||||
{ slider , "Joystick Deadzone" , {&joy_deadzone}, {0.0}, {0.75}, {0.05}, {NULL} },
|
||||
#ifdef SDL12
|
||||
{ redtext , " " , {NULL}, {0.0}, {0.0}, {0.0}, {NULL} },
|
||||
{ whitetext , "Press ENTER to change" , {NULL}, {0.0}, {0.0}, {0.0}, {NULL} },
|
||||
{ joyaxis , "Walk Analog Axis" , {&joy_forwardaxis}, {0.0}, {0.0}, {0.0}, {NULL} },
|
||||
{ joyaxis , "Strafe Analog Axis" , {&joy_strafeaxis}, {0.0}, {0.0}, {0.0}, {NULL} },
|
||||
{ joyaxis , "Turn Analog Axis" , {&joy_turnaxis}, {0.0}, {0.0}, {0.0}, {NULL} },
|
||||
{ joyaxis , "Look Analog Axis" , {&joy_lookaxis}, {0.0}, {0.0}, {0.0}, {NULL} },
|
||||
#endif
|
||||
};
|
||||
|
||||
menu_t JoystickMenu = {
|
||||
|
|
@ -646,7 +643,8 @@ static menuitem_t SoundItems[] = {
|
|||
{ discrete , "Player Connect Alert" , {&cl_connectalert}, {2.0}, {0.0}, {0.0}, {OnOff} },
|
||||
{ discrete , "Player Disconnect Alert" , {&cl_disconnectalert}, {2.0}, {0.0}, {0.0}, {OnOff} },
|
||||
{ discrete , "Chat sounds" , {&cl_chatsounds}, {3.0}, {0.0}, {0.0}, {ChatSndType}},
|
||||
};
|
||||
{discrete , "Voting Sounds" , {&snd_votesfx}, {2.0}, {0.0}, {0.0}, {OnOff}},
|
||||
};
|
||||
|
||||
menu_t AdvMidiMenu = {
|
||||
"M_SOUND",
|
||||
|
|
@ -703,7 +701,16 @@ static menuitem_t CompatItems[] ={
|
|||
{svdiscrete, "BOOM actor/sector/line checks", {&co_boomphys}, {2.0}, {0.0}, {0.0}, {OnOff}},
|
||||
{svdiscrete, "MBF movement and collision", {&co_mbfphys}, {2.0}, {0.0}, {0.0}, {OnOff}},
|
||||
{svdiscrete, "ZDOOM 1.23 physics", {&co_zdoomphys}, {2.0}, {0.0}, {0.0}, {OnOff}},
|
||||
{svdiscrete, "ZDOOM 1.23 ammo checks", {&co_zdoomammo}, {2.0}, {0.0}, {0.0}, {OnOff}},
|
||||
{svdiscrete, "ZDOOM 1.23 ammo checks", {&co_zdoomammo}, {2.0}, {0.0}, {0.0}, {OnOff}},
|
||||
{svdiscrete, "MBF Monster target selection",{&co_pursuit}, {2.0}, {0.0}, {0.0}, {OnOff}},
|
||||
{svdiscrete, "Monsters help friends (MBF)",{&co_helpfriends}, {2.0}, {0.0}, {0.0}, {OnOff}},
|
||||
{svdiscrete, "Monsters strafe (MBF)",{&co_monsterbacking}, {2.0}, {0.0}, {0.0}, {OnOff}},
|
||||
{svdiscrete, "Monster wind/friction (MBF)",{&co_monsterfriction}, {2.0}, {0.0}, {0.0}, {OnOff}},
|
||||
{svdiscrete, "Monsters avoid crushers (MBF)",{&co_avoidhazards}, {2.0}, {0.0}, {0.0}, {OnOff}},
|
||||
{svdiscrete, "Monsters climb (MBF)",{&co_monstersclimbsteep}, {2.0}, {0.0}, {0.0}, {OnOff}},
|
||||
{svdiscrete, "Monsters stay on lifts (MBF)",{&co_staylift}, {2.0}, {0.0}, {0.0}, {OnOff}},
|
||||
{svdiscrete, "Friends can drop off (MBF)",{&co_friend_ledgejumping}, {2.0}, {0.0}, {0.0}, {OnOff}},
|
||||
{slider, "Friend distance (MBF)", {&co_friend_distance}, {0.0}, {2048.0}, {64.0}, {NULL}},
|
||||
{redtext, " ", {NULL}, {0.0}, {0.0}, {0.0}, {NULL}},
|
||||
{yellowtext, "Sound", {NULL}, {0.0}, {0.0}, {0.0}, {NULL}},
|
||||
{svdiscrete, "Fix silent west spawns", {&co_nosilentspawns}, {2.0}, {0.0}, {0.0}, {OnOff}},
|
||||
|
|
@ -729,21 +736,9 @@ menu_t CompatMenu = {
|
|||
*
|
||||
*=======================================*/
|
||||
|
||||
static value_t PredictSectors[] = {
|
||||
{ 0.0, "None" },
|
||||
{ 1.0, "All" },
|
||||
{ 2.0, "Only Mine" }
|
||||
};
|
||||
|
||||
static menuitem_t NetworkItems[] = {
|
||||
{ redtext, " ", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} },
|
||||
{ yellowtext, "Adjust Network Settings", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} },
|
||||
{ slider, "Interpolation time", {&cl_interp}, {0.0}, {4.0}, {1.0}, {NULL} },
|
||||
{ slider, "Smooth collisions", {&cl_prednudge}, {1.0}, {0.1}, {-0.1}, {NULL} },
|
||||
{ discrete, "Predict weapon pickups", {&cl_predictpickup},{2.0}, {0.0}, {0.0}, {OnOff} },
|
||||
{ discrete, "Predict sector actions", {&cl_predictsectors},{3.0}, {0.0}, {0.0}, {PredictSectors} },
|
||||
{ discrete, "Predict weapon effects", {&cl_predictweapons},{2.0}, {0.0}, {0.0}, {OnOff} },
|
||||
{ redtext, " ", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} },
|
||||
{ yellowtext, "Wad Download Settings", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} },
|
||||
{ discrete, "Download From Internet", {&cl_serverdownload}, {2.0}, {0.0}, {0.0}, {OnOff} },
|
||||
|
||||
{ redtext, " ", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} },
|
||||
|
|
@ -857,6 +852,7 @@ EXTERN_CVAR (r_painintensity)
|
|||
EXTERN_CVAR (cl_movebob)
|
||||
EXTERN_CVAR (cl_centerbobonfire)
|
||||
EXTERN_CVAR (cl_showspawns)
|
||||
EXTERN_CVAR (cl_showfriends)
|
||||
EXTERN_CVAR (hud_show_scoreboard_ondeath)
|
||||
EXTERN_CVAR (hud_demobar)
|
||||
EXTERN_CVAR(hud_targetnames)
|
||||
|
|
@ -932,6 +928,7 @@ static menuitem_t VideoItems[] = {
|
|||
{ discrete, "Linear Skies", {&r_linearsky}, {2.0}, {0.0}, {0.0}, {OnOff} },
|
||||
{ discrete, "Invuln changes skies", {&r_skypalette}, {2.0}, {0.0}, {0.0}, {OnOff} },
|
||||
{ discrete, "Use softer invuln effect", {&r_softinvulneffect}, {2.0}, {0.0}, {0.0}, {OnOff} },
|
||||
{ discrete, "Heart effect on friendlies", {&cl_showfriends}, {2.0}, {0.0}, {0.0}, {OnOff} },
|
||||
{ discrete, "Screen wipe style", {&r_wipetype}, {4.0}, {0.0}, {0.0}, {Wipes} },
|
||||
{ discrete, "Multiplayer Intermissions",{&wi_oldintermission}, {2.0}, {0.0}, {0.0}, {DoomOrOdamex} },
|
||||
{ discrete, "Show loading disk icon", {&r_loadicon}, {2.0}, {0.0}, {0.0}, {OnOff} },
|
||||
|
|
@ -1226,7 +1223,7 @@ void M_RestoreVideoMode()
|
|||
|
||||
static value_t Depths[22];
|
||||
|
||||
#ifdef _XBOX
|
||||
#ifdef GCONSOLE
|
||||
static const char VMEnterText[] = "Press A to set mode";
|
||||
static const char VMTestText[] = "Press X to test mode for 5 seconds";
|
||||
#else
|
||||
|
|
@ -1507,12 +1504,12 @@ void M_ChangeMessages (void)
|
|||
{
|
||||
if (show_messages)
|
||||
{
|
||||
Printf (128, "%s\n", GStrings(MSGOFF));
|
||||
PrintFmt(128, "{}\n", GStrings(MSGOFF));
|
||||
show_messages.Set (0.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
Printf (128, "%s\n", GStrings(MSGON));
|
||||
PrintFmt(128, "{}\n", GStrings(MSGON));
|
||||
show_messages.Set (1.0f);
|
||||
}
|
||||
}
|
||||
|
|
@ -1964,17 +1961,17 @@ void M_OptResponder (event_t *ev)
|
|||
// to make sure we get the one that is intended -- Hyper_Eye
|
||||
if( (ev->data3 > (SHRT_MAX / 2)) || (ev->data3 < (SHRT_MIN / 2)) )
|
||||
{
|
||||
if( (ev->data2 == (int)joy_forwardaxis) &&
|
||||
joy_forwardaxis.name() != item->a.cvar->name() )
|
||||
if ((ev->data2 == joy_forwardaxis.asInt()) &&
|
||||
joy_forwardaxis.name() != item->a.cvar->name())
|
||||
joy_forwardaxis.Set(item->a.cvar->value());
|
||||
else if( (ev->data2 == (int)joy_strafeaxis) &&
|
||||
joy_strafeaxis.name() != item->a.cvar->name() )
|
||||
else if ((ev->data2 == joy_strafeaxis.asInt()) &&
|
||||
joy_strafeaxis.name() != item->a.cvar->name())
|
||||
joy_strafeaxis.Set(item->a.cvar->value());
|
||||
else if( (ev->data2 == (int)joy_turnaxis) &&
|
||||
joy_turnaxis.name() != item->a.cvar->name() )
|
||||
else if ((ev->data2 == joy_turnaxis.asInt()) &&
|
||||
joy_turnaxis.name() != item->a.cvar->name())
|
||||
joy_turnaxis.Set(item->a.cvar->value());
|
||||
else if( (ev->data2 == (int)joy_lookaxis) &&
|
||||
joy_lookaxis.name() != item->a.cvar->name() )
|
||||
else if ((ev->data2 == joy_lookaxis.asInt()) &&
|
||||
joy_lookaxis.name() != item->a.cvar->name())
|
||||
joy_lookaxis.Set(item->a.cvar->value());
|
||||
|
||||
item->a.cvar->Set(ev->data2);
|
||||
|
|
@ -2490,7 +2487,7 @@ void M_OptResponder (event_t *ev)
|
|||
}
|
||||
else
|
||||
{
|
||||
#ifdef _XBOX
|
||||
#ifdef GCONSOLE
|
||||
if (ev->data3 == 't' || ev->data1 == OKEY_JOY3)
|
||||
#else
|
||||
if (ev->data3 == 't')
|
||||
|
|
|
|||
|
|
@ -465,11 +465,11 @@ bool OTransfer::tick()
|
|||
return false;
|
||||
}
|
||||
|
||||
Printf("Saved to fallback location \"%s\".\n", fallback);
|
||||
PrintFmt("Saved to fallback location \"{}\".\n", fallback);
|
||||
}
|
||||
else
|
||||
{
|
||||
Printf("Saved to location \"%s\".\n", m_filename);
|
||||
PrintFmt("Saved to location \"{}\".\n", m_filename);
|
||||
}
|
||||
|
||||
m_shouldCheckAgain = false;
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@ const fixed_t NEARCLIP = 2*FRACUNIT;
|
|||
|
||||
drawseg_t* ds_p;
|
||||
drawseg_t* drawsegs;
|
||||
drawseg_t* firstdrawseg;
|
||||
unsigned maxdrawsegs;
|
||||
|
||||
// CPhipps -
|
||||
|
|
@ -93,8 +94,10 @@ void R_ReallocDrawSegs(void)
|
|||
if (ds_p == drawsegs+maxdrawsegs) // killough 1/98 -- fix 2s line HOM
|
||||
{
|
||||
unsigned pos = ds_p - drawsegs; // jff 8/9/98 fix from ZDOOM1.14a
|
||||
unsigned firstofs = firstdrawseg - drawsegs;
|
||||
unsigned newmax = maxdrawsegs ? maxdrawsegs*2 : 128; // killough
|
||||
drawsegs = (drawseg_t*)M_Realloc(drawsegs, newmax*sizeof(*drawsegs));
|
||||
firstdrawseg = drawsegs + firstofs;
|
||||
ds_p = drawsegs + pos; // jff 8/9/98 fix from ZDOOM1.14a
|
||||
maxdrawsegs = newmax;
|
||||
DPrintFmt("MaxDrawSegs increased to {}\n", maxdrawsegs);
|
||||
|
|
@ -106,6 +109,11 @@ void R_ReallocDrawSegs(void)
|
|||
//
|
||||
void R_ClearDrawSegs(void)
|
||||
{
|
||||
if (drawsegs == NULL)
|
||||
{
|
||||
maxdrawsegs = 256;
|
||||
firstdrawseg = drawsegs = (drawseg_t*)Malloc(maxdrawsegs * sizeof(drawseg_t));
|
||||
}
|
||||
ds_p = drawsegs;
|
||||
}
|
||||
|
||||
|
|
@ -687,7 +695,8 @@ void R_Subsector (int num)
|
|||
frontsector->ceiling_yoffs + frontsector->base_ceiling_yoffs,
|
||||
frontsector->ceiling_xscale,
|
||||
frontsector->ceiling_yscale,
|
||||
frontsector->ceiling_angle + frontsector->base_ceiling_angle
|
||||
frontsector->ceiling_angle + frontsector->base_ceiling_angle,
|
||||
frontsector->Skybox
|
||||
) : NULL;
|
||||
|
||||
// killough 3/7/98: Add (x,y) offsets to flats, add deep water check
|
||||
|
|
@ -706,7 +715,8 @@ void R_Subsector (int num)
|
|||
frontsector->floor_yoffs + frontsector->base_floor_yoffs,
|
||||
frontsector->floor_xscale,
|
||||
frontsector->floor_yscale,
|
||||
frontsector->floor_angle + frontsector->base_floor_angle
|
||||
frontsector->floor_angle + frontsector->base_floor_angle,
|
||||
frontsector->Skybox
|
||||
) : NULL;
|
||||
|
||||
// [RH] set foggy flag
|
||||
|
|
|
|||
|
|
@ -229,7 +229,7 @@ static void R_BuildFontTranslation(int color_num, argb_t start_color, argb_t end
|
|||
|
||||
palindex_t* dest = (palindex_t*)Ranges + color_num * 256;
|
||||
|
||||
if (gamemode == retail_chex)
|
||||
if (IsChexMission(gamemission))
|
||||
{
|
||||
for (int index = 0; index < chexstart_index; index++)
|
||||
dest[index] = index;
|
||||
|
|
@ -258,7 +258,7 @@ static void R_BuildFontTranslation(int color_num, argb_t start_color, argb_t end
|
|||
int b_diff = end_color.getb() - start_color.getb();
|
||||
int hacxtrack;
|
||||
|
||||
if (gamemode == retail_chex)
|
||||
if (IsChexMission(gamemission))
|
||||
{
|
||||
for (palindex_t index = chexstart_index; index <= chexend_index; index++)
|
||||
{
|
||||
|
|
@ -399,6 +399,18 @@ void R_InitTranslationTables()
|
|||
::bosstable[i] = V_BestColor(V_GetDefaultPalette()->basecolors, mul);
|
||||
}
|
||||
|
||||
// Friend translation is a pink tint.
|
||||
const argb_t ptop(0xff, 0x70, 0xB9);
|
||||
for (size_t i = 0; i < ARRAY_LENGTH(::friendtable); i++)
|
||||
{
|
||||
const argb_t bot = V_GetDefaultPalette()->basecolors[i];
|
||||
const argb_t mul(SoftLight(bot.getr(), ptop.getr()),
|
||||
SoftLight(bot.getg(), ptop.getg()),
|
||||
SoftLight(bot.getb(), ptop.getb()));
|
||||
|
||||
::friendtable[i] = V_BestColor(V_GetDefaultPalette()->basecolors, mul);
|
||||
}
|
||||
|
||||
translationtablesmem = new byte[256*(MAXPLAYERS+3+22)+255]; // denis - fixme - magic numbers?
|
||||
|
||||
// [Toke - fix13]
|
||||
|
|
@ -618,7 +630,7 @@ static forceinline void R_FillColumnGeneric(PIXEL_T* dest, const drawcolumn_t& d
|
|||
#ifdef RANGECHECK
|
||||
if (drawcolumn.x < 0 || drawcolumn.x >= viewwidth || drawcolumn.yl < 0 || drawcolumn.yh >= viewheight)
|
||||
{
|
||||
Printf (PRINT_HIGH, "R_FillColumn: %i to %i at %i\n", drawcolumn.yl, drawcolumn.yh, drawcolumn.x);
|
||||
PrintFmt(PRINT_HIGH, "R_FillColumn: {} to {} at {}\n", drawcolumn.yl, drawcolumn.yh, drawcolumn.x);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -657,7 +669,7 @@ static forceinline void R_DrawColumnGeneric(PIXEL_T* dest, const drawcolumn_t& d
|
|||
#ifdef RANGECHECK
|
||||
if (drawcolumn.x < 0 || drawcolumn.x >= viewwidth || drawcolumn.yl < 0 || drawcolumn.yh >= viewheight)
|
||||
{
|
||||
Printf (PRINT_HIGH, "R_DrawColumn: %i to %i at %i\n", drawcolumn.yl, drawcolumn.yh, drawcolumn.x);
|
||||
PrintFmt(PRINT_HIGH, "R_DrawColumn: {} to {} at {}\n", drawcolumn.yl, drawcolumn.yh, drawcolumn.x);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -765,7 +777,7 @@ static forceinline void R_FillSpanGeneric(PIXEL_T* dest, const drawspan_t& draws
|
|||
if (drawspan.x2 < drawspan.x1 || drawspan.x1 < 0 || drawspan.x2 >= viewwidth ||
|
||||
drawspan.y >= viewheight || drawspan.y < 0)
|
||||
{
|
||||
Printf(PRINT_HIGH, "R_FillSpan: %i to %i at %i", drawspan.x1, drawspan.x2, drawspan.y);
|
||||
PrintFmt(PRINT_HIGH, "R_FillSpan: {} to {} at {}", drawspan.x1, drawspan.x2, drawspan.y);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -798,7 +810,7 @@ static forceinline void R_DrawLevelSpanGeneric(PIXEL_T* dest, const drawspan_t&
|
|||
if (drawspan.x2 < drawspan.x1 || drawspan.x1 < 0 || drawspan.x2 >= viewwidth ||
|
||||
drawspan.y >= viewheight || drawspan.y < 0)
|
||||
{
|
||||
Printf(PRINT_HIGH, "R_DrawLevelSpan: %i to %i at %i", drawspan.x1, drawspan.x2, drawspan.y);
|
||||
PrintFmt(PRINT_HIGH, "R_DrawLevelSpan: {} to {} at {}", drawspan.x1, drawspan.x2, drawspan.y);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -851,7 +863,7 @@ static forceinline void R_DrawSlopedSpanGeneric(PIXEL_T* dest, const drawspan_t&
|
|||
if (drawspan.x2 < drawspan.x1 || drawspan.x1 < 0 || drawspan.x2 >= viewwidth ||
|
||||
drawspan.y >= viewheight || drawspan.y < 0)
|
||||
{
|
||||
Printf(PRINT_HIGH, "R_DrawSlopedSpan: %i to %i at %i", drawspan.x1, drawspan.x2, drawspan.y);
|
||||
PrintFmt(PRINT_HIGH, "R_DrawSlopedSpan: {} to {} at {}", drawspan.x1, drawspan.x2, drawspan.y);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -1761,7 +1773,7 @@ static std::string get_optimization_name_list(const bool includeNone)
|
|||
|
||||
static void print_optimizations()
|
||||
{
|
||||
Printf(PRINT_HIGH, "r_optimize detected \"%s\"\n", get_optimization_name_list(false));
|
||||
PrintFmt(PRINT_HIGH, "r_optimize detected \"{}\"\n", get_optimization_name_list(false));
|
||||
}
|
||||
|
||||
static bool detect_optimizations()
|
||||
|
|
@ -1826,8 +1838,8 @@ CVAR_FUNC_IMPL(r_optimize)
|
|||
optimize_kind = optimizations_available.back();
|
||||
else
|
||||
{
|
||||
Printf(PRINT_HIGH, "Invalid value for r_optimize. Availible options are \"%s, detect\"\n",
|
||||
get_optimization_name_list(true));
|
||||
PrintFmt(PRINT_HIGH, "Invalid value for r_optimize. Availible options are \"{}, detect\"\n",
|
||||
get_optimization_name_list(true));
|
||||
|
||||
// Restore the original setting:
|
||||
var.Set(get_optimization_name(optimize_kind));
|
||||
|
|
@ -1839,7 +1851,7 @@ CVAR_FUNC_IMPL(r_optimize)
|
|||
{
|
||||
// update the cvar string
|
||||
// this will trigger the callback to run a second time
|
||||
Printf(PRINT_HIGH, "r_optimize set to \"%s\" based on availability\n", optimize_name);
|
||||
PrintFmt(PRINT_HIGH, "r_optimize set to \"{}\" based on availability\n", optimize_name);
|
||||
var.Set(optimize_name);
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ void R_DrawSpanD_SSE2 (void)
|
|||
if (dspan.x2 < dspan.x1 || dspan.x1 < 0 || dspan.x2 >= viewwidth ||
|
||||
dspan.y >= viewheight || dspan.y < 0)
|
||||
{
|
||||
Printf(PRINT_HIGH, "R_DrawLevelSpan: %i to %i at %i", dspan.x1, dspan.x2, dspan.y);
|
||||
PrintFmt(PRINT_HIGH, "R_DrawLevelSpan: {} to {} at {}", dspan.x1, dspan.x2, dspan.y);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -232,7 +232,7 @@ void OInterpolation::ticGameInterpolation()
|
|||
// Functions that assist with the interpolation of certain game objects
|
||||
void OInterpolation::interpolateCeilings(fixed_t amount)
|
||||
{
|
||||
for (const auto [old_value, secnum] : prev_ceilingheight)
|
||||
for (const auto& [old_value, secnum] : prev_ceilingheight)
|
||||
{
|
||||
sector_t* sector = §ors[secnum];
|
||||
|
||||
|
|
@ -265,7 +265,7 @@ void OInterpolation::interpolateCeilings(fixed_t amount)
|
|||
|
||||
void OInterpolation::interpolateFloors(fixed_t amount)
|
||||
{
|
||||
for (const auto [old_value, secnum] : prev_floorheight)
|
||||
for (const auto& [old_value, secnum] : prev_floorheight)
|
||||
{
|
||||
sector_t* sector = §ors[secnum];
|
||||
|
||||
|
|
@ -382,7 +382,7 @@ void OInterpolation::beginGameInterpolation(fixed_t amount)
|
|||
void OInterpolation::restoreCeilings(void)
|
||||
{
|
||||
// Ceiling heights
|
||||
for (const auto [height, secnum] : saved_ceilingheight)
|
||||
for (const auto& [height, secnum] : saved_ceilingheight)
|
||||
{
|
||||
sector_t* sector = §ors[secnum];
|
||||
P_SetCeilingHeight(sector, height);
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@
|
|||
|
||||
#include "m_fixed.h"
|
||||
#include "r_defs.h"
|
||||
#include <map>
|
||||
|
||||
typedef std::pair<fixed_t, unsigned int> fixed_uint_pair;
|
||||
typedef std::pair<std::pair<fixed_t, fixed_t>, unsigned int> fixed_fixed_uint_pair;
|
||||
|
|
|
|||
|
|
@ -638,6 +638,20 @@ subsector_t *R_PointInSubsector (fixed_t x, fixed_t y)
|
|||
return &subsectors[nodenum & ~NF_SUBSECTOR];
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// R_SetViewAngle
|
||||
//
|
||||
//
|
||||
|
||||
void R_SetViewAngle(angle_t ang)
|
||||
{
|
||||
viewangle = ang;
|
||||
|
||||
viewsin = finesine[ang >> ANGLETOFINESHIFT];
|
||||
viewcos = finecosine[ang >> ANGLETOFINESHIFT];
|
||||
}
|
||||
|
||||
//
|
||||
// R_ViewShear
|
||||
//
|
||||
|
|
@ -984,7 +998,7 @@ void R_RenderPlayerView(player_t* player)
|
|||
R_ClearClipSegs();
|
||||
R_ClearDrawSegs();
|
||||
R_ClearOpenings();
|
||||
R_ClearPlanes();
|
||||
R_ClearPlanes(true);
|
||||
R_ClearSprites();
|
||||
|
||||
R_ResetDrawFuncs();
|
||||
|
|
@ -1019,7 +1033,7 @@ void R_RenderPlayerView(player_t* player)
|
|||
R_RenderBSPNode(numnodes - 1); // The head node is the last node output.
|
||||
|
||||
R_DrawPlanes();
|
||||
|
||||
R_DrawSkyBoxes();
|
||||
R_DrawMasked();
|
||||
|
||||
// NOTE(jsd): Full-screen status color blending:
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@
|
|||
|
||||
#include "z_zone.h"
|
||||
#include "w_wad.h"
|
||||
#include "m_mempool.h"
|
||||
|
||||
#include "p_local.h"
|
||||
#include "r_local.h"
|
||||
|
|
@ -59,10 +60,12 @@ planefunction_t ceilingfunc;
|
|||
static constexpr float flatwidth = 64.0f;
|
||||
static constexpr float flatheight = 64.0f;
|
||||
|
||||
static visplane_t *visplanes[MAXVISPLANES]; // killough
|
||||
static visplane_t *visplanes[MAXVISPLANES + 1]; // killough
|
||||
static visplane_t *freetail; // killough
|
||||
static visplane_t **freehead = &freetail; // killough
|
||||
|
||||
static bool r_InSkyBox;
|
||||
|
||||
visplane_t *floorplane;
|
||||
visplane_t *ceilingplane;
|
||||
visplane_t *skyplane;
|
||||
|
|
@ -95,6 +98,7 @@ int *spanstart;
|
|||
extern fixed_t FocalLengthX, FocalLengthY;
|
||||
extern float xfoc, yfoc;
|
||||
extern float focratio, ifocratio;
|
||||
extern Pool<int> sprclip_pool;
|
||||
|
||||
int* planezlight;
|
||||
float plight, shade;
|
||||
|
|
@ -253,15 +257,18 @@ void R_MapLevelPlane(int y, int x1, int x2)
|
|||
// R_ClearPlanes
|
||||
// At begining of frame.
|
||||
//
|
||||
void R_ClearPlanes (void)
|
||||
void R_ClearPlanes(bool fullclear)
|
||||
{
|
||||
// opening / clipping determination
|
||||
memcpy(floorclip, floorclipinitial, viewwidth * sizeof(*floorclip));
|
||||
memcpy(ceilingclip, ceilingclipinitial, viewwidth * sizeof(*ceilingclip));
|
||||
|
||||
for (int i = 0; i < MAXVISPLANES; i++) // new code -- killough
|
||||
for (*freehead = visplanes[i], visplanes[i] = NULL; *freehead; )
|
||||
freehead = &(*freehead)->next;
|
||||
|
||||
if (fullclear)
|
||||
{
|
||||
// opening / clipping determination
|
||||
memcpy(floorclip, floorclipinitial, viewwidth * sizeof(*floorclip));
|
||||
memcpy(ceilingclip, ceilingclipinitial, viewwidth * sizeof(*ceilingclip));
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -292,31 +299,50 @@ static visplane_t *new_visplane(unsigned hash)
|
|||
//
|
||||
// killough 2/28/98: Add offsets
|
||||
//
|
||||
visplane_t *R_FindPlane (plane_t secplane, int picnum, int lightlevel,
|
||||
visplane_t *R_FindPlane (const plane_t &secplane, int picnum, int lightlevel,
|
||||
fixed_t xoffs, fixed_t yoffs,
|
||||
fixed_t xscale, fixed_t yscale, angle_t angle)
|
||||
fixed_t xscale, fixed_t yscale, angle_t angle,
|
||||
AActor::AActorPtr skybox)
|
||||
{
|
||||
visplane_t *check;
|
||||
unsigned hash; // killough
|
||||
bool isskybox;
|
||||
|
||||
if (R_IsSkyFlat(picnum) || picnum & PL_SKYFLAT) // killough 10/98
|
||||
lightlevel = 0; // most skies map together
|
||||
{
|
||||
lightlevel = 0; // most skies map together
|
||||
isskybox = (picnum == skyflatnum) && (skybox != NULL) && !r_InSkyBox;
|
||||
}
|
||||
else
|
||||
{
|
||||
isskybox = false;
|
||||
}
|
||||
|
||||
// New visplane algorithm uses hash table -- killough
|
||||
hash = visplane_hash (picnum, lightlevel, secplane);
|
||||
hash = isskybox ? MAXVISPLANES : visplane_hash(picnum, lightlevel, secplane);
|
||||
|
||||
for (check = visplanes[hash]; check; check = check->next) // killough
|
||||
if (P_IdenticalPlanes(&secplane, &check->secplane) &&
|
||||
picnum == check->picnum &&
|
||||
lightlevel == check->lightlevel &&
|
||||
xoffs == check->xoffs && // killough 2/28/98: Add offset checks
|
||||
yoffs == check->yoffs &&
|
||||
basecolormap == check->colormap && // [RH] Add colormap check
|
||||
xscale == check->xscale &&
|
||||
yscale == check->yscale &&
|
||||
angle == check->angle
|
||||
)
|
||||
return check;
|
||||
for (check = visplanes[hash]; check; check = check->next) // killough
|
||||
{
|
||||
if (isskybox)
|
||||
{
|
||||
if (skybox == check->skybox)
|
||||
{
|
||||
return check;
|
||||
}
|
||||
}
|
||||
else if (P_IdenticalPlanes(&secplane, &check->secplane) &&
|
||||
picnum == check->picnum &&
|
||||
lightlevel == check->lightlevel &&
|
||||
xoffs == check->xoffs && // killough 2/28/98: Add offset checks
|
||||
yoffs == check->yoffs &&
|
||||
basecolormap == check->colormap && // [RH] Add colormap check
|
||||
xscale == check->xscale &&
|
||||
yscale == check->yscale &&
|
||||
angle == check->angle)
|
||||
{
|
||||
return check;
|
||||
}
|
||||
}
|
||||
|
||||
check = new_visplane (hash); // killough
|
||||
|
||||
|
|
@ -329,6 +355,7 @@ visplane_t *R_FindPlane (plane_t secplane, int picnum, int lightlevel,
|
|||
check->yscale = yscale;
|
||||
check->angle = angle;
|
||||
check->colormap = basecolormap; // [RH] Save colormap
|
||||
check->skybox = skybox;
|
||||
check->minx = viewwidth; // Was SCREENWIDTH -- killough 11/98
|
||||
check->maxx = -1;
|
||||
|
||||
|
|
@ -382,7 +409,16 @@ visplane_t* R_CheckPlane(visplane_t* pl, int start, int stop)
|
|||
else
|
||||
{
|
||||
// make a new visplane
|
||||
unsigned hash = visplane_hash (pl->picnum, pl->lightlevel, pl->secplane);
|
||||
unsigned hash;
|
||||
|
||||
if (pl->picnum == skyflatnum && pl->skybox != NULL && !r_InSkyBox)
|
||||
{
|
||||
hash = MAXVISPLANES;
|
||||
}
|
||||
else
|
||||
{
|
||||
hash = visplane_hash(pl->picnum, pl->lightlevel, pl->secplane);
|
||||
}
|
||||
visplane_t *new_pl = new_visplane (hash);
|
||||
|
||||
new_pl->secplane = pl->secplane;
|
||||
|
|
@ -394,6 +430,7 @@ visplane_t* R_CheckPlane(visplane_t* pl, int start, int stop)
|
|||
new_pl->yscale = pl->yscale;
|
||||
new_pl->angle = pl->angle;
|
||||
new_pl->colormap = pl->colormap; // [RH] Copy colormap
|
||||
new_pl->skybox = pl->skybox;
|
||||
pl = new_pl;
|
||||
pl->minx = start;
|
||||
pl->maxx = stop;
|
||||
|
|
@ -600,6 +637,7 @@ void R_DrawPlanes (void)
|
|||
{
|
||||
visplane_t *pl;
|
||||
int i;
|
||||
int vpcount;
|
||||
|
||||
R_ResetDrawFuncs();
|
||||
|
||||
|
|
@ -682,6 +720,124 @@ void R_DrawPlanes (void)
|
|||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// R_DrawSkyBoxes
|
||||
//
|
||||
// Draws any recorded sky boxes and then frees them.
|
||||
//
|
||||
// The process:
|
||||
// 1. Move the camera to coincide with the SkyViewpoint.
|
||||
// 2. Clear out the old planes. (They have already been drawn.)
|
||||
// 3. Clear a window out of the ClipSegs just large enough for the plane.
|
||||
// 4. Pretend the existing vissprites and drawsegs aren't there.
|
||||
// 5. Create a drawseg at 0 distance to clip sprites to the visplane. It
|
||||
// doesn't need to be associated with a line in the map, since there
|
||||
// will never be any sprites in front of it.
|
||||
// 6. Render the BSP, then planes, then masked stuff.
|
||||
// 7. Restore the previous vissprites and drawsegs.
|
||||
// 8. Repeat for any other sky boxes.
|
||||
// 9. Put the camera back where it was to begin with.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void R_DrawSkyBoxes()
|
||||
{
|
||||
if (visplanes[MAXVISPLANES] == NULL)
|
||||
return;
|
||||
|
||||
int savedextralight = extralight;
|
||||
fixed_t savedx = viewx;
|
||||
fixed_t savedy = viewy;
|
||||
fixed_t savedz = viewz;
|
||||
angle_t savedangle = viewangle;
|
||||
ptrdiff_t savedvissprite_p = vissprite_p - vissprites;
|
||||
ptrdiff_t savedds_p = ds_p - drawsegs;
|
||||
AActor* savedcamera = camera;
|
||||
|
||||
int i;
|
||||
visplane_t* pl;
|
||||
|
||||
// Don't draw sky boxes inside sky boxes.
|
||||
r_InSkyBox = true;
|
||||
|
||||
// Don't let gun flashes brighten the sky box
|
||||
extralight = 0;
|
||||
|
||||
for (pl = visplanes[MAXVISPLANES]; pl != NULL; pl = pl->next)
|
||||
{
|
||||
if (pl->maxx < pl->minx)
|
||||
continue;
|
||||
|
||||
AActor::AActorPtr sky = pl->skybox;
|
||||
|
||||
viewx = sky->x;
|
||||
viewy = sky->y;
|
||||
viewz = sky->z;
|
||||
camera = sky;
|
||||
R_SetViewAngle(savedangle + sky->angle);
|
||||
validcount++; // Make sure we see all sprites
|
||||
|
||||
R_ClearPlanes(false);
|
||||
R_ClearClipSegs();
|
||||
|
||||
// Set up ceiling/floor clip arrays for this visplane.
|
||||
for (i = pl->minx; i <= pl->maxx; i++)
|
||||
{
|
||||
if (pl->top[i] == (unsigned int)viewheight)
|
||||
{
|
||||
ceilingclip[i] = viewheight;
|
||||
floorclip[i] = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
ceilingclip[i] = pl->top[i];
|
||||
floorclip[i] = pl->bottom[i];
|
||||
}
|
||||
}
|
||||
|
||||
// Create a drawseg to clip sprites to the sky plane.
|
||||
R_ReallocDrawSegs();
|
||||
ds_p->x1 = 0;
|
||||
ds_p->x2 = viewwidth - 1;
|
||||
ds_p->silhouette = SIL_BOTH;
|
||||
ds_p->midposts = NULL;
|
||||
ds_p->curline = NULL;
|
||||
|
||||
// [RK] Allocate full width clip arrays.
|
||||
ds_p->sprbottomclip = sprclip_pool.alloc(viewwidth);
|
||||
ds_p->sprtopclip = sprclip_pool.alloc(viewwidth);
|
||||
|
||||
// [RK] Copy visplane clip values into the arrays.
|
||||
memcpy(ds_p->sprbottomclip, floorclip, viewwidth * sizeof(*ds_p->sprbottomclip));
|
||||
memcpy(ds_p->sprtopclip, ceilingclip, viewwidth * sizeof(*ds_p->sprtopclip));
|
||||
|
||||
firstvissprite = vissprite_p;
|
||||
firstdrawseg = ds_p++;
|
||||
|
||||
R_RenderBSPNode(numnodes - 1);
|
||||
R_DrawPlanes();
|
||||
R_DrawMasked();
|
||||
|
||||
firstvissprite = vissprites;
|
||||
vissprite_p = vissprites + savedvissprite_p;
|
||||
firstdrawseg = drawsegs;
|
||||
ds_p = drawsegs + savedds_p;
|
||||
}
|
||||
|
||||
camera = savedcamera;
|
||||
viewx = savedx;
|
||||
viewy = savedy;
|
||||
viewz = savedz;
|
||||
extralight = savedextralight;
|
||||
R_SetViewAngle(savedangle);
|
||||
|
||||
r_InSkyBox = false;
|
||||
|
||||
for (*freehead = visplanes[MAXVISPLANES], visplanes[MAXVISPLANES] = NULL; *freehead;)
|
||||
freehead = &(*freehead)->next;
|
||||
}
|
||||
|
||||
//
|
||||
// R_PlaneInitData
|
||||
//
|
||||
|
|
|
|||
|
|
@ -97,6 +97,7 @@ extern float yfoc;
|
|||
|
||||
static tallpost_t** masked_midposts;
|
||||
|
||||
EXTERN_CVAR(r_clipmaskedspecial)
|
||||
|
||||
//
|
||||
// R_TexScaleX
|
||||
|
|
@ -942,6 +943,9 @@ void R_StoreWallRange(int start, int stop)
|
|||
// killough 4/17/98: draw floors if different light levels
|
||||
|| backsector->floorlightsec != frontsector->floorlightsec
|
||||
|
||||
// [EB] check for special too for DSDA-compatibility on MBF21
|
||||
|| (r_clipmaskedspecial && backsector->special != frontsector->special)
|
||||
|
||||
// [RH] Add checks for colormaps
|
||||
|| backsector->colormap != frontsector->colormap
|
||||
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ extern fixed_t freelookviewheight;
|
|||
|
||||
EXTERN_CVAR(sv_freelook)
|
||||
EXTERN_CVAR(cl_mouselook)
|
||||
EXTERN_CVAR(joy_freelook)
|
||||
EXTERN_CVAR(r_skypalette)
|
||||
EXTERN_CVAR(r_linearsky)
|
||||
|
||||
|
|
@ -292,8 +293,10 @@ void R_InitSkyMap()
|
|||
|
||||
if (fskyheight <= (128 << FRACBITS))
|
||||
{
|
||||
defaultskytexturemid = 200/2*FRACUNIT;
|
||||
skystretch = (r_stretchsky == 1) || consoleplayer().spectator || (r_stretchsky == 2 && sv_freelook && cl_mouselook);
|
||||
defaultskytexturemid = 200 / 2 * FRACUNIT;
|
||||
skystretch = ((r_stretchsky != 0) && consoleplayer().spectator) ||
|
||||
(r_stretchsky == 1) ||
|
||||
(r_stretchsky == 2 && sv_freelook && (cl_mouselook || joy_freelook));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -68,11 +68,12 @@ fixed_t bobx;
|
|||
fixed_t boby;
|
||||
|
||||
#define MAX_SPRITE_FRAMES 29 // [RH] Macro-ized as in BOOM.
|
||||
#define SPRITE_NEEDS_INFO MAXINT
|
||||
#define SPRITE_NEEDS_INFO limits::MAXINT
|
||||
|
||||
EXTERN_CVAR (r_drawplayersprites)
|
||||
EXTERN_CVAR (r_softinvulneffect)
|
||||
EXTERN_CVAR (r_particles)
|
||||
EXTERN_CVAR (r_thingsectorlight);
|
||||
|
||||
//
|
||||
// INITIALIZATION FUNCTIONS
|
||||
|
|
@ -88,7 +89,7 @@ extern int NumParticles;
|
|||
extern int ActiveParticles;
|
||||
extern int InactiveParticles;
|
||||
extern particle_t *Particles;
|
||||
TArray<WORD> ParticlesInSubsec;
|
||||
std::vector<WORD> ParticlesInSubsec;
|
||||
|
||||
|
||||
|
||||
|
|
@ -106,7 +107,7 @@ int newvissprite;
|
|||
//
|
||||
void R_ClearSprites()
|
||||
{
|
||||
vissprite_p = vissprites;
|
||||
vissprite_p = firstvissprite;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -116,11 +117,13 @@ void R_ClearSprites()
|
|||
vissprite_t *R_NewVisSprite()
|
||||
{
|
||||
if (vissprite_p == lastvissprite) {
|
||||
int firstvisspritenum = firstvissprite - vissprites;
|
||||
int prevvisspritenum = vissprite_p - vissprites;
|
||||
|
||||
MaxVisSprites *= 2;
|
||||
vissprites = (vissprite_t *)M_Realloc (vissprites, MaxVisSprites * sizeof(vissprite_t));
|
||||
lastvissprite = &vissprites[MaxVisSprites];
|
||||
firstvissprite = &vissprites[firstvisspritenum];
|
||||
vissprite_p = &vissprites[prevvisspritenum];
|
||||
DPrintFmt("MaxVisSprites increased to {}\n", MaxVisSprites);
|
||||
}
|
||||
|
|
@ -324,8 +327,8 @@ void R_DrawVisSprite (vissprite_t *vis, int x1, int x2)
|
|||
#if 0
|
||||
if ((colfrac - vis->xiscale) >> FRACBITS != end)
|
||||
{
|
||||
Printf(PRINT_WARNING, "Bad vissprite bounds check! (pw:%d ex:%d act:%d)\n",
|
||||
patchWidth, end, colfrac >> FRACBITS);
|
||||
PrintFmt(PRINT_WARNING, "Bad vissprite bounds check! (pw:{} ex:{} act:{})\n",
|
||||
patchWidth, end, colfrac >> FRACBITS);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -451,7 +454,7 @@ static vissprite_t* R_GenerateVisSprite(const sector_t* sector, int fakeside,
|
|||
return vis;
|
||||
}
|
||||
|
||||
void R_DrawHitBox(AActor* thing)
|
||||
void R_DrawHitBox(const AActor* thing)
|
||||
{
|
||||
v3fixed_t vertices[8];
|
||||
static constexpr byte color = 0x80;
|
||||
|
|
@ -521,10 +524,8 @@ void R_DrawHitBox(AActor* thing)
|
|||
// R_ProjectSprite
|
||||
// Generates a vissprite for a thing if it might be visible.
|
||||
//
|
||||
void R_ProjectSprite(AActor *thing, int fakeside)
|
||||
void R_ProjectSprite(const AActor *thing, int fakeside)
|
||||
{
|
||||
spritedef_t* sprdef;
|
||||
spriteframe_t* sprframe;
|
||||
int lump;
|
||||
unsigned int rot;
|
||||
bool flip;
|
||||
|
|
@ -563,25 +564,27 @@ void R_ProjectSprite(AActor *thing, int fakeside)
|
|||
thingz = thing->z;
|
||||
}
|
||||
|
||||
auto it = sprites.find(thing->sprite);
|
||||
|
||||
#ifdef RANGECHECK
|
||||
if (static_cast<unsigned>(thing->sprite) >= static_cast<unsigned>(numsprites))
|
||||
if (it == sprites.end())
|
||||
{
|
||||
DPrintFmt("R_ProjectSprite: invalid sprite number {}\n", thing->sprite);
|
||||
DPrintFmt("R_ProjectSprite: thing ({}: {}): invalid sprite number {}\n on ", thing->type, thing->info->name, thing->sprite);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
sprdef = &sprites[thing->sprite];
|
||||
const spritedef_t* sprdef = &it->second;
|
||||
|
||||
#ifdef RANGECHECK
|
||||
if ( (thing->frame & FF_FRAMEMASK) >= sprdef->numframes )
|
||||
{
|
||||
DPrintFmt("R_ProjectSprite: invalid sprite frame {} : {}\n ", thing->sprite, thing->frame);
|
||||
DPrintFmt("R_ProjectSprite: thing ({}: {}): invalid sprite frame {} : {}\n ", thing->type, thing->info->name, thing->sprite, thing->frame);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
sprframe = &sprdef->spriteframes[thing->frame & FF_FRAMEMASK];
|
||||
const spriteframe_t* sprframe = &sprdef->spriteframes[thing->frame & FF_FRAMEMASK];
|
||||
|
||||
// decide which patch to use for sprite relative to player
|
||||
if (sprframe->rotate)
|
||||
|
|
@ -608,8 +611,15 @@ void R_ProjectSprite(AActor *thing, int fakeside)
|
|||
flip = sprframe->flip[0];
|
||||
}
|
||||
|
||||
if (lump == -1) {
|
||||
char frame = (thing->frame & FF_FRAMEMASK) + 'A';
|
||||
I_Error("Frame {} for sprite {} could not be found.", frame, sprnames[thing->sprite]);
|
||||
}
|
||||
|
||||
if (sprframe->width[rot] == SPRITE_NEEDS_INFO)
|
||||
{
|
||||
R_CacheSprite (sprdef); // [RH] speeds up game startup time
|
||||
}
|
||||
|
||||
sector_t* sector = thing->subsector->sector;
|
||||
fixed_t topoffs = sprframe->topoffset[rot];
|
||||
|
|
@ -680,7 +690,8 @@ void R_AddSprites (sector_t *sec, int lightlevel, int fakeside)
|
|||
// Well, now it will be done.
|
||||
sec->validcount = validcount;
|
||||
|
||||
int lightnum = (lightlevel >> LIGHTSEGSHIFT) + (foggy ? 0 : extralight);
|
||||
int lightnum = r_thingsectorlight ? lightlevel : sec->lightlevel;
|
||||
lightnum = (lightnum >> LIGHTSEGSHIFT) + (foggy ? 0 : extralight);
|
||||
|
||||
if (lightnum < 0)
|
||||
spritelights = scalelight[0];
|
||||
|
|
@ -690,7 +701,7 @@ void R_AddSprites (sector_t *sec, int lightlevel, int fakeside)
|
|||
spritelights = scalelight[lightnum];
|
||||
|
||||
// Handle all things in sector.
|
||||
for (AActor* thing = sec->thinglist; thing; thing = thing->snext)
|
||||
for (const AActor* thing = sec->thinglist; thing; thing = thing->snext)
|
||||
{
|
||||
R_ProjectSprite (thing, fakeside);
|
||||
}
|
||||
|
|
@ -702,65 +713,58 @@ void R_AddSprites (sector_t *sec, int lightlevel, int fakeside)
|
|||
//
|
||||
void R_DrawPSprite(pspdef_t* psp, unsigned flags)
|
||||
{
|
||||
fixed_t tx;
|
||||
int x1;
|
||||
int x2;
|
||||
spritedef_t* sprdef;
|
||||
spriteframe_t* sprframe;
|
||||
int lump;
|
||||
bool flip;
|
||||
vissprite_t* vis;
|
||||
vissprite_t avis;
|
||||
|
||||
// decide which patch to use
|
||||
auto it = sprites.find(psp->state->sprite);
|
||||
#ifdef RANGECHECK
|
||||
if ( (unsigned)psp->state->sprite >= (unsigned)numsprites) {
|
||||
if (it == sprites.end()) {
|
||||
DPrintFmt("R_DrawPSprite: invalid sprite number {}\n", psp->state->sprite);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
sprdef = &sprites[psp->state->sprite];
|
||||
const spritedef_t* sprdef = &it->second;
|
||||
#ifdef RANGECHECK
|
||||
if ( (psp->state->frame & FF_FRAMEMASK) >= sprdef->numframes) {
|
||||
DPrintFmt("R_DrawPSprite: invalid sprite frame {} : {}\n", psp->state->sprite, psp->state->frame);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
sprframe = &sprdef->spriteframes[ psp->state->frame & FF_FRAMEMASK ];
|
||||
const spriteframe_t* sprframe = &sprdef->spriteframes[ psp->state->frame & FF_FRAMEMASK ];
|
||||
|
||||
lump = sprframe->lump[0];
|
||||
flip = sprframe->flip[0];
|
||||
const int32_t lump = sprframe->lump[0];
|
||||
const bool flip = sprframe->flip[0];
|
||||
|
||||
if (sprframe->width[0] == SPRITE_NEEDS_INFO)
|
||||
R_CacheSprite (sprdef); // [RH] speeds up game startup time
|
||||
|
||||
// calculate edges of the shape
|
||||
tx = bobx - ((320 / 2) << FRACBITS);
|
||||
fixed_t tx = bobx - ((320 / 2) << FRACBITS);
|
||||
|
||||
tx -= sprframe->offset[0]; // [RH] Moved out of spriteoffset[]
|
||||
x1 = (centerxfrac + FixedMul (tx, pspritexscale)) >>FRACBITS;
|
||||
const int32_t x1 = (centerxfrac + FixedMul (tx, pspritexscale)) >>FRACBITS;
|
||||
|
||||
// off the right side
|
||||
if (x1 > viewwidth)
|
||||
return;
|
||||
|
||||
tx += sprframe->width[0]; // [RH] Moved out of spritewidth[]
|
||||
x2 = ((centerxfrac + FixedMul (tx, pspritexscale)) >>FRACBITS) - 1;
|
||||
const int32_t x2 = ((centerxfrac + FixedMul (tx, pspritexscale)) >>FRACBITS) - 1;
|
||||
|
||||
// off the left side
|
||||
if (x2 < 0)
|
||||
return;
|
||||
|
||||
// store information in a vissprite
|
||||
vis = &avis;
|
||||
vissprite_t* vis = &avis;
|
||||
vis->mobjflags = flags;
|
||||
vis->statusflags = camera->player && camera->player->mo ? camera->player->mo->statusflags : 0;
|
||||
|
||||
// [RH] +0x6000 helps it meet the screen bottom
|
||||
// at higher resolutions while still being in
|
||||
// the right spot at 320x200.
|
||||
// denis - bump to 0x9000
|
||||
#define WEAPONTWEAK (0x9000)
|
||||
// [RH] +0x6000 helps it meet the screen bottom
|
||||
// at higher resolutions while still being in
|
||||
// the right spot at 320x200.
|
||||
// denis - bump to 0x9000
|
||||
static constexpr fixed_t WEAPONTWEAK = 0x9000;
|
||||
|
||||
vis->texturemid = (BASEYCENTER << FRACBITS) + FRACUNIT / 2 -
|
||||
(boby + WEAPONTWEAK - sprframe->topoffset[0]); // [RH] Moved out of spritetopoffset[]
|
||||
|
|
@ -924,20 +928,22 @@ static int STACK_ARGS sv_compare(const void *arg1, const void *arg2)
|
|||
|
||||
void R_SortVisSprites()
|
||||
{
|
||||
vsprcount = vissprite_p - vissprites;
|
||||
vsprcount = vissprite_p - firstvissprite;
|
||||
|
||||
if (!vsprcount)
|
||||
return;
|
||||
|
||||
if (spritesorter_size < MaxVisSprites)
|
||||
{
|
||||
delete [] spritesorter;
|
||||
if (spritesorter != NULL)
|
||||
delete [] spritesorter;
|
||||
spritesorter = new vissprite_t*[MaxVisSprites];
|
||||
spritesorter_size = MaxVisSprites;
|
||||
}
|
||||
|
||||
for (int i = 0; i < vsprcount; i++)
|
||||
spritesorter[i] = vissprites + i;
|
||||
vissprite_t* spr = firstvissprite;
|
||||
for (int i = 0; i < vsprcount; i++, spr++)
|
||||
spritesorter[i] = spr;
|
||||
|
||||
qsort(spritesorter, vsprcount, sizeof(vissprite_t *), sv_compare);
|
||||
}
|
||||
|
|
@ -1021,7 +1027,7 @@ void R_DrawSprite (vissprite_t *spr)
|
|||
// (pointer check was originally nonportable
|
||||
// and buggy, by going past LEFT end of array):
|
||||
|
||||
for (ds = ds_p ; ds-- > drawsegs ; ) // new -- killough
|
||||
for (ds = ds_p ; ds-- > firstdrawseg ; ) // new -- killough
|
||||
{
|
||||
// determine if the drawseg obscures the sprite
|
||||
if (ds->x1 > spr->x2 || ds->x2 < spr->x1 ||
|
||||
|
|
@ -1038,8 +1044,8 @@ void R_DrawSprite (vissprite_t *spr)
|
|||
segscale2 = MIN<int>(ds->scale1, ds->scale2);
|
||||
|
||||
// check if the seg is in front of the sprite
|
||||
if (segscale1 < spr->yscale ||
|
||||
(segscale2 < spr->yscale && !R_PointOnSegSide(spr->gx, spr->gy, ds->curline)))
|
||||
if (!(!ds->curline) && (segscale1 < spr->yscale ||
|
||||
(segscale2 < spr->yscale && !R_PointOnSegSide(spr->gx, spr->gy, ds->curline))))
|
||||
{
|
||||
// masked mid texture?
|
||||
if (ds->midposts)
|
||||
|
|
@ -1084,8 +1090,10 @@ void R_DrawMasked (void)
|
|||
|
||||
R_SortVisSprites ();
|
||||
|
||||
while (vsprcount > 0)
|
||||
R_DrawSprite(spritesorter[--vsprcount]);
|
||||
for (int i = vsprcount; i > 0; i--)
|
||||
{
|
||||
R_DrawSprite(spritesorter[i-1]);
|
||||
}
|
||||
|
||||
// render any remaining masked mid textures
|
||||
|
||||
|
|
@ -1095,7 +1103,7 @@ void R_DrawMasked (void)
|
|||
|
||||
// for (ds=ds_p-1 ; ds >= drawsegs ; ds--) old buggy code
|
||||
|
||||
for (ds=ds_p ; ds-- > drawsegs ; ) // new -- killough
|
||||
for (ds=ds_p ; ds-- > firstdrawseg ; ) // new -- killough
|
||||
if (ds->midposts)
|
||||
R_RenderMaskedSegRange(ds, ds->x1, ds->x2);
|
||||
|
||||
|
|
@ -1136,12 +1144,8 @@ void R_ClearParticles (void)
|
|||
|
||||
void R_FindParticleSubsectors ()
|
||||
{
|
||||
if (ParticlesInSubsec.Size() < (size_t)numsubsectors)
|
||||
ParticlesInSubsec.Reserve(numsubsectors - ParticlesInSubsec.Size());
|
||||
|
||||
// fill the buffer with NO_PARTICLE
|
||||
for (int i = 0; i < numsubsectors; i++)
|
||||
ParticlesInSubsec[i] = NO_PARTICLE;
|
||||
ParticlesInSubsec.assign(numsubsectors, NO_PARTICLE);
|
||||
|
||||
if (!r_particles)
|
||||
return;
|
||||
|
|
@ -1164,24 +1168,44 @@ void R_ProjectParticle (particle_t *particle, const sector_t *sector, int fakesi
|
|||
fixed_t x = particle->x;
|
||||
fixed_t y = particle->y;
|
||||
fixed_t z = particle->z;
|
||||
fixed_t height = particle->size*(FRACUNIT/4);
|
||||
fixed_t width = particle->size*(FRACUNIT/4);
|
||||
fixed_t height = particle->size * (FRACUNIT / 4);
|
||||
fixed_t width = particle->size * (FRACUNIT / 4);
|
||||
fixed_t topoffs = height;
|
||||
fixed_t sideoffs = width >> 1;
|
||||
|
||||
if (particle->sprite != NO_PARTICLE)
|
||||
{
|
||||
patch_t* patch = W_CachePatch(particle->sprite);
|
||||
height = patch->height() << FRACBITS;
|
||||
width = patch->width() << FRACBITS;
|
||||
topoffs = patch->topoffset();
|
||||
sideoffs = patch->leftoffset();
|
||||
}
|
||||
|
||||
vissprite_t* vis = R_GenerateVisSprite(sector, fakeside, x, y, z, height, width, topoffs, sideoffs, false);
|
||||
|
||||
if (vis == NULL)
|
||||
return;
|
||||
|
||||
vis->translation = translationref_t();
|
||||
vis->startfrac = particle->color;
|
||||
vis->patch = NO_PARTICLE;
|
||||
vis->mobjflags = particle->trans;
|
||||
vis->translucency = 65535;
|
||||
vis->statusflags = 0;
|
||||
vis->mo = NULL;
|
||||
vis->spectator = false;
|
||||
|
||||
if (particle->sprite == NO_PARTICLE)
|
||||
{
|
||||
vis->startfrac = particle->color;
|
||||
vis->patch = NO_PARTICLE;
|
||||
vis->mobjflags = particle->trans;
|
||||
}
|
||||
else
|
||||
{
|
||||
vis->patch = particle->sprite;
|
||||
vis->translucency = (particle->trans + 1) << 8;
|
||||
vis->mobjflags = 0;
|
||||
}
|
||||
|
||||
// get light level
|
||||
if (fixedcolormap.isValid())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@
|
|||
#include "m_fileio.h"
|
||||
#include "gi.h"
|
||||
#include "oscanner.h"
|
||||
#include "g_musinfo.h"
|
||||
|
||||
#define NORM_PITCH 128
|
||||
#define NORM_PRIORITY 64
|
||||
|
|
@ -56,8 +57,8 @@ static constexpr fixed_t S_STEREO_SWING = 96 * FRACUNIT;
|
|||
struct channel_t
|
||||
{
|
||||
public:
|
||||
fixed_t* pt; // origin of sound
|
||||
fixed_t x, y; // origin if pt is NULL
|
||||
const fixed_t* pt; // origin of sound
|
||||
fixed_t x, y; // origin if pt is nullptr
|
||||
sfxinfo_t* sfxinfo; // sound information (if null, channel avail.)
|
||||
int handle; // handle of the sound being played
|
||||
int sound_id;
|
||||
|
|
@ -73,9 +74,9 @@ public:
|
|||
|
||||
void clear()
|
||||
{
|
||||
pt = NULL;
|
||||
pt = nullptr;
|
||||
x = y = 0;
|
||||
sfxinfo = NULL;
|
||||
sfxinfo = nullptr;
|
||||
handle = -1;
|
||||
sound_id = -1;
|
||||
entchannel = CHAN_VOICE;
|
||||
|
|
@ -84,7 +85,7 @@ public:
|
|||
dist = 0;
|
||||
initial_volume = 0.0f;
|
||||
volume = 0.0f;
|
||||
priority = MININT;
|
||||
priority = limits::MININT;
|
||||
loop = false;
|
||||
start_time = 0;
|
||||
}
|
||||
|
|
@ -168,7 +169,7 @@ void S_NoiseDebug()
|
|||
if (Channel[i].sfxinfo)
|
||||
{
|
||||
char temp[16];
|
||||
fixed_t *origin = Channel[i].pt;
|
||||
const fixed_t *origin = Channel[i].pt;
|
||||
|
||||
if (Channel[i].attenuation == ATTN_NONE && listenplayer().camera)
|
||||
{
|
||||
|
|
@ -186,7 +187,7 @@ void S_NoiseDebug()
|
|||
oy = Channel[i].y;
|
||||
}
|
||||
const int color = Channel[i].loop ? CR_BROWN : CR_GREY;
|
||||
M_StringCopy(temp, lumpinfo[Channel[i].sfxinfo->lumpnum].name, 9);
|
||||
M_StringCopy(temp, lumpinfo[Channel[i].sfxinfo->lumpnum].name.c_str(), 9);
|
||||
screen->DrawText (color, 0, y, temp);
|
||||
snprintf (temp, 16, "%d", ox / FRACUNIT);
|
||||
screen->DrawText (color, 70, y, temp);
|
||||
|
|
@ -277,8 +278,8 @@ void S_Init(float sfxVolume, float musicVolume)
|
|||
*/
|
||||
void S_Deinit()
|
||||
{
|
||||
::SoundCurve = NULL;
|
||||
::Channel = NULL;
|
||||
::SoundCurve = nullptr;
|
||||
::Channel = nullptr;
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -357,7 +358,7 @@ int S_GetChannel(sfxinfo_t* sfxinfo, float volume, int priority, unsigned max_in
|
|||
fixed_t dist, int channel)
|
||||
{
|
||||
// not a valid sound
|
||||
if (::Channel == NULL || sfxinfo == NULL)
|
||||
if (::Channel == nullptr || sfxinfo == nullptr)
|
||||
return -1;
|
||||
|
||||
// Sort the sound channels by descending priority levels
|
||||
|
|
@ -387,7 +388,7 @@ int S_GetChannel(sfxinfo_t* sfxinfo, float volume, int priority, unsigned max_in
|
|||
|
||||
// try to find the first empty channel
|
||||
for (size_t i = 0; i < numChannels; i++)
|
||||
if (Channel[i].sfxinfo == NULL)
|
||||
if (Channel[i].sfxinfo == nullptr)
|
||||
return i;
|
||||
|
||||
// No empty channels and this is an ambient sound?
|
||||
|
|
@ -608,7 +609,7 @@ static size_t ResolveSound(size_t soundid)
|
|||
// joek - choco's S_StartSoundAtVolume with some zdoom code
|
||||
// a bit of a whore of a funtion but she works ok
|
||||
//
|
||||
static void S_StartSound(fixed_t* pt, fixed_t x, fixed_t y, int channel,
|
||||
static void S_StartSound(const fixed_t* pt, fixed_t x, fixed_t y, int channel,
|
||||
int sfx_id, float volume, int attenuation, bool looping,
|
||||
float dist_scale = 0.0f)
|
||||
{
|
||||
|
|
@ -652,9 +653,9 @@ static void S_StartSound(fixed_t* pt, fixed_t x, fixed_t y, int channel,
|
|||
|
||||
if (pt == (fixed_t *)(~0))
|
||||
{
|
||||
pt = NULL;
|
||||
pt = nullptr;
|
||||
}
|
||||
else if (pt != NULL)
|
||||
else if (pt != nullptr)
|
||||
{
|
||||
x = pt[0];
|
||||
y = pt[1];
|
||||
|
|
@ -745,15 +746,15 @@ static void S_StartSound(fixed_t* pt, fixed_t x, fixed_t y, int channel,
|
|||
|
||||
void S_SoundID(int channel, int sound_id, float volume, int attenuation)
|
||||
{
|
||||
S_StartSound((fixed_t *)NULL, 0, 0, channel, sound_id, volume, attenuation, false);
|
||||
S_StartSound(nullptr, 0, 0, channel, sound_id, volume, attenuation, false);
|
||||
}
|
||||
|
||||
void S_SoundID(fixed_t x, fixed_t y, int channel, int sound_id, float volume, int attenuation)
|
||||
{
|
||||
S_StartSound((fixed_t *)NULL, x, y, channel, sound_id, volume, attenuation, false);
|
||||
S_StartSound(nullptr, x, y, channel, sound_id, volume, attenuation, false);
|
||||
}
|
||||
|
||||
void S_SoundID(AActor *ent, int channel, int sound_id, float volume, int attenuation)
|
||||
void S_SoundID(const AActor *ent, int channel, int sound_id, float volume, int attenuation)
|
||||
{
|
||||
if (!ent)
|
||||
return;
|
||||
|
|
@ -764,12 +765,12 @@ void S_SoundID(AActor *ent, int channel, int sound_id, float volume, int attenua
|
|||
S_StartSound (&ent->x, 0, 0, channel, sound_id, volume, attenuation, false);
|
||||
}
|
||||
|
||||
void S_SoundID(fixed_t *pt, int channel, int sound_id, float volume, int attenuation)
|
||||
void S_SoundID(const fixed_t *pt, int channel, int sound_id, float volume, int attenuation)
|
||||
{
|
||||
S_StartSound(pt, 0, 0, channel, sound_id, volume, attenuation, false);
|
||||
}
|
||||
|
||||
void S_LoopedSoundID(AActor *ent, int channel, int sound_id, float volume, int attenuation)
|
||||
void S_LoopedSoundID(const AActor *ent, int channel, int sound_id, float volume, int attenuation)
|
||||
{
|
||||
if (!ent)
|
||||
return;
|
||||
|
|
@ -780,12 +781,35 @@ void S_LoopedSoundID(AActor *ent, int channel, int sound_id, float volume, int a
|
|||
S_StartSound(&ent->x, 0, 0, channel, sound_id, volume, attenuation, true);
|
||||
}
|
||||
|
||||
void S_LoopedSoundID(fixed_t *pt, int channel, int sound_id, float volume, int attenuation)
|
||||
void S_LoopedSoundID(const fixed_t *pt, int channel, int sound_id, float volume, int attenuation)
|
||||
{
|
||||
S_StartSound(pt, 0, 0, channel, sound_id, volume, attenuation, true);
|
||||
}
|
||||
|
||||
static void S_StartNamedSound(AActor *ent, fixed_t *pt, fixed_t x, fixed_t y, int channel,
|
||||
int S_FindGenderedSound(std::string_view name, const AActor* ent)
|
||||
{
|
||||
static constexpr std::string_view templat = "player/{}/{}";
|
||||
// static constexpr std::string_view genders[] = { "male", "female", "cyborg", "other" };
|
||||
static constexpr std::string_view genders[] = { "male", "male", "male", "male" };
|
||||
player_t *player;
|
||||
|
||||
int sfx_id = -1;
|
||||
if (ent && ent != (AActor *)(~0) && (player = ent->player))
|
||||
{
|
||||
sfx_id = S_FindSound(fmt::format(templat, "base", name).c_str());
|
||||
if (sfx_id == -1)
|
||||
{
|
||||
sfx_id = S_FindSound(fmt::format(templat, genders[player->userinfo.gender], name).c_str());
|
||||
}
|
||||
}
|
||||
if (sfx_id == -1)
|
||||
{
|
||||
sfx_id = S_FindSound(fmt::format(templat, "male", name).c_str());
|
||||
}
|
||||
return sfx_id;
|
||||
}
|
||||
|
||||
static void S_StartNamedSound(const AActor *ent, const fixed_t *pt, fixed_t x, fixed_t y, int channel,
|
||||
const char *name, float volume, int attenuation, bool looping,
|
||||
float dist_scale = 0.0f)
|
||||
{
|
||||
|
|
@ -805,30 +829,7 @@ static void S_StartNamedSound(AActor *ent, fixed_t *pt, fixed_t x, fixed_t y, in
|
|||
|
||||
if (soundname[0] == '*')
|
||||
{
|
||||
// Sexed sound
|
||||
char nametemp[128];
|
||||
const char templat[] = "player/%s/%s";
|
||||
// Hacks away! -joek
|
||||
//const char *genders[] = { "male", "female", "cyborg" };
|
||||
const char *genders[] = { "male", "male", "male" };
|
||||
player_t *player;
|
||||
|
||||
sfx_id = -1;
|
||||
if (ent && ent != (AActor *)(~0) && (player = ent->player))
|
||||
{
|
||||
snprintf(nametemp, 128, templat, "base", soundname.substr(1).c_str());
|
||||
sfx_id = S_FindSound(nametemp);
|
||||
if (sfx_id == -1)
|
||||
{
|
||||
snprintf(nametemp, 128, templat, genders[player->userinfo.gender], soundname.substr(1).c_str());
|
||||
sfx_id = S_FindSound(nametemp);
|
||||
}
|
||||
}
|
||||
if (sfx_id == -1)
|
||||
{
|
||||
snprintf(nametemp, 128, templat, "male", soundname.substr(1).c_str());
|
||||
sfx_id = S_FindSound(nametemp);
|
||||
}
|
||||
sfx_id = S_FindGenderedSound(soundname.substr(1), ent);
|
||||
}
|
||||
else
|
||||
sfx_id = S_FindSound(soundname.c_str());
|
||||
|
|
@ -851,7 +852,7 @@ static void S_StartNamedSound(AActor *ent, fixed_t *pt, fixed_t x, fixed_t y, in
|
|||
void S_PlatSound(fixed_t *pt, int channel, const char *name, float volume, int attenuation)
|
||||
{
|
||||
if (!predicting)
|
||||
S_StartNamedSound(NULL, pt, 0, 0, channel, name, volume, attenuation, false);
|
||||
S_StartNamedSound(nullptr, pt, 0, 0, channel, name, volume, attenuation, false);
|
||||
}
|
||||
|
||||
void S_Sound(int channel, const char *name, float volume, int attenuation)
|
||||
|
|
@ -859,35 +860,35 @@ void S_Sound(int channel, const char *name, float volume, int attenuation)
|
|||
// [SL] 2011-05-27 - This particular S_Sound() function is only used for sounds
|
||||
// that should be full volume regardless of location. Ignore the specified
|
||||
// attenuation and use ATTN_NONE instead.
|
||||
S_StartNamedSound((AActor *)NULL, NULL, 0, 0, channel, name, volume, ATTN_NONE, false);
|
||||
S_StartNamedSound(nullptr, nullptr, 0, 0, channel, name, volume, ATTN_NONE, false);
|
||||
}
|
||||
|
||||
void S_Sound(AActor *ent, int channel, const char *name, float volume, int attenuation)
|
||||
void S_Sound(const AActor *ent, int channel, const char *name, float volume, int attenuation)
|
||||
{
|
||||
if(!co_globalsound && channel == CHAN_ITEM && ent != listenplayer().camera)
|
||||
return;
|
||||
|
||||
S_StartNamedSound(ent, NULL, 0, 0, channel, name, volume, attenuation, false);
|
||||
S_StartNamedSound(ent, nullptr, 0, 0, channel, name, volume, attenuation, false);
|
||||
}
|
||||
|
||||
void S_Sound(fixed_t *pt, int channel, const char *name, float volume, int attenuation)
|
||||
void S_Sound(const fixed_t *pt, int channel, const char *name, float volume, int attenuation)
|
||||
{
|
||||
S_StartNamedSound(NULL, pt, 0, 0, channel, name, volume, attenuation, false);
|
||||
S_StartNamedSound(nullptr, pt, 0, 0, channel, name, volume, attenuation, false);
|
||||
}
|
||||
|
||||
void S_LoopedSound(AActor *ent, int channel, const char *name, float volume, int attenuation)
|
||||
void S_LoopedSound(const AActor *ent, int channel, const char *name, float volume, int attenuation)
|
||||
{
|
||||
S_StartNamedSound(ent, NULL, 0, 0, channel, name, volume, attenuation, true);
|
||||
S_StartNamedSound(ent, nullptr, 0, 0, channel, name, volume, attenuation, true);
|
||||
}
|
||||
|
||||
void S_LoopedSound(fixed_t *pt, int channel, const char *name, float volume, int attenuation)
|
||||
void S_LoopedSound(const fixed_t *pt, int channel, const char *name, float volume, int attenuation)
|
||||
{
|
||||
S_StartNamedSound(NULL, pt, 0, 0, channel, name, volume, attenuation, true);
|
||||
S_StartNamedSound(nullptr, pt, 0, 0, channel, name, volume, attenuation, true);
|
||||
}
|
||||
|
||||
void S_Sound(fixed_t x, fixed_t y, int channel, const char *name, float volume, int attenuation)
|
||||
{
|
||||
S_StartNamedSound((AActor *)(~0), NULL, x, y, channel, name, volume, attenuation, false);
|
||||
S_StartNamedSound(nullptr, nullptr, x, y, channel, name, volume, attenuation, false);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -896,7 +897,7 @@ void S_Sound(fixed_t x, fixed_t y, int channel, const char *name, float volume,
|
|||
//
|
||||
static void S_StopChannel(unsigned int cnum)
|
||||
{
|
||||
if (::Channel == NULL)
|
||||
if (::Channel == nullptr)
|
||||
return;
|
||||
|
||||
if (cnum >= numChannels)
|
||||
|
|
@ -914,7 +915,7 @@ static void S_StopChannel(unsigned int cnum)
|
|||
}
|
||||
|
||||
|
||||
void S_StopSound(fixed_t *pt)
|
||||
void S_StopSound(const fixed_t *pt)
|
||||
{
|
||||
for (unsigned int i = 0; i < numChannels; i++)
|
||||
if (Channel[i].sfxinfo && (Channel[i].pt == pt))
|
||||
|
|
@ -923,9 +924,9 @@ void S_StopSound(fixed_t *pt)
|
|||
}
|
||||
}
|
||||
|
||||
void S_StopSound(fixed_t *pt, int channel)
|
||||
void S_StopSound(const fixed_t *pt, int channel)
|
||||
{
|
||||
if (::Channel == NULL)
|
||||
if (::Channel == nullptr)
|
||||
return;
|
||||
|
||||
for (unsigned int i = 0; i < numChannels; i++)
|
||||
|
|
@ -935,7 +936,7 @@ void S_StopSound(fixed_t *pt, int channel)
|
|||
S_StopChannel(i);
|
||||
}
|
||||
|
||||
void S_StopSound(AActor *ent, int channel)
|
||||
void S_StopSound(const AActor *ent, int channel)
|
||||
{
|
||||
S_StopSound(&ent->x, channel);
|
||||
}
|
||||
|
|
@ -989,17 +990,17 @@ void S_ResumeSound()
|
|||
|
||||
|
||||
// Moves all the sounds from one thing to another. If the destination is
|
||||
// NULL, then the sound becomes a positioned sound.
|
||||
void S_RelinkSound(AActor *from, AActor *to)
|
||||
// nullptr, then the sound becomes a positioned sound.
|
||||
void S_RelinkSound(const AActor *from, const AActor *to)
|
||||
{
|
||||
if (::Channel == NULL)
|
||||
if (::Channel == nullptr)
|
||||
return;
|
||||
|
||||
if (!from)
|
||||
return;
|
||||
|
||||
const fixed_t *frompt = &from->x;
|
||||
fixed_t *topt = to ? &to->x : NULL;
|
||||
const fixed_t *topt = to ? &to->x : nullptr;
|
||||
|
||||
for (unsigned int i = 0; i < numChannels; i++)
|
||||
{
|
||||
|
|
@ -1012,7 +1013,7 @@ void S_RelinkSound(AActor *from, AActor *to)
|
|||
}
|
||||
}
|
||||
|
||||
bool S_GetSoundPlayingInfo(fixed_t *pt, int sound_id)
|
||||
bool S_GetSoundPlayingInfo(const fixed_t *pt, int sound_id)
|
||||
{
|
||||
for (unsigned int i = 0; i < numChannels; i++)
|
||||
{
|
||||
|
|
@ -1022,9 +1023,9 @@ bool S_GetSoundPlayingInfo(fixed_t *pt, int sound_id)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool S_GetSoundPlayingInfo(AActor *ent, int sound_id)
|
||||
bool S_GetSoundPlayingInfo(const AActor *ent, int sound_id)
|
||||
{
|
||||
return S_GetSoundPlayingInfo (ent ? &ent->x : NULL, sound_id);
|
||||
return S_GetSoundPlayingInfo (ent ? &ent->x : nullptr, sound_id);
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -1052,12 +1053,11 @@ void S_ResumeMusic()
|
|||
// Updates music & sounds
|
||||
//
|
||||
// joek - from choco again
|
||||
void S_UpdateSounds(void* listener_p)
|
||||
void S_UpdateSounds(const AActor* listener)
|
||||
{
|
||||
if (::Channel == NULL)
|
||||
if (::Channel == nullptr)
|
||||
return;
|
||||
|
||||
AActor* listener = (AActor*)listener_p;
|
||||
for (int cnum = 0; cnum < (int)numChannels; cnum++)
|
||||
{
|
||||
channel_t* c = &Channel[cnum];
|
||||
|
|
@ -1139,7 +1139,7 @@ void S_UpdateMusic()
|
|||
void S_SetMusicVolume(float volume)
|
||||
{
|
||||
if (volume < 0.0 || volume > 1.0)
|
||||
Printf (PRINT_HIGH, "Attempt to set music volume at %f\n", volume);
|
||||
PrintFmt(PRINT_HIGH, "Attempt to set music volume at {}\n", volume);
|
||||
else
|
||||
I_SetMusicVolume (volume);
|
||||
}
|
||||
|
|
@ -1147,7 +1147,7 @@ void S_SetMusicVolume(float volume)
|
|||
void S_SetSfxVolume(float volume)
|
||||
{
|
||||
if (volume < 0.0 || volume > 1.0)
|
||||
Printf (PRINT_HIGH, "Attempt to set sfx volume at %f\n", volume);
|
||||
PrintFmt(PRINT_HIGH, "Attempt to set sfx volume at {}\n", volume);
|
||||
else
|
||||
I_SetSfxVolume (volume);
|
||||
}
|
||||
|
|
@ -1162,7 +1162,7 @@ void S_StartMusic(const char *m_id)
|
|||
|
||||
// [RH] S_ChangeMusic() now accepts the name of the music lump.
|
||||
// It's up to the caller to figure out what that name is.
|
||||
void S_ChangeMusic(std::string musicname, bool looping)
|
||||
void S_ChangeMusic(std::string musicname, bool looping, int order)
|
||||
{
|
||||
// [SL] Avoid caching music lumps if we're not playing music
|
||||
if (snd_musicsystem == MS_NONE)
|
||||
|
|
@ -1178,7 +1178,7 @@ void S_ChangeMusic(std::string musicname, bool looping)
|
|||
return;
|
||||
}
|
||||
|
||||
byte* data = NULL;
|
||||
byte* data = nullptr;
|
||||
size_t length = 0;
|
||||
FILE *f;
|
||||
|
||||
|
|
@ -1187,13 +1187,13 @@ void S_ChangeMusic(std::string musicname, bool looping)
|
|||
int lumpnum;
|
||||
if ((lumpnum = W_CheckNumForName (musicname.c_str())) == -1)
|
||||
{
|
||||
Printf (PRINT_HIGH, "Music lump \"%s\" not found\n", musicname);
|
||||
PrintFmt(PRINT_HIGH, "Music lump \"{}\" not found\n", musicname);
|
||||
return;
|
||||
}
|
||||
|
||||
data = static_cast<byte*>(W_CacheLumpNum(lumpnum, PU_CACHE));
|
||||
length = W_LumpLength(lumpnum);
|
||||
I_PlaySong({data, length}, looping);
|
||||
I_PlaySong({data, length}, looping, order);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1204,7 +1204,7 @@ void S_ChangeMusic(std::string musicname, bool looping)
|
|||
|
||||
if (result == 1)
|
||||
{
|
||||
I_PlaySong({data, length}, looping);
|
||||
I_PlaySong({data, length}, looping, order);
|
||||
}
|
||||
M_Free(data);
|
||||
}
|
||||
|
|
@ -1216,7 +1216,7 @@ void S_StopMusic()
|
|||
{
|
||||
I_StopSong();
|
||||
|
||||
mus_playing.name = "";
|
||||
mus_playing.name.clear();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1227,355 +1227,13 @@ void S_StopMusic()
|
|||
//
|
||||
// =============================== [RH]
|
||||
|
||||
typedef enum
|
||||
{
|
||||
AMB_TYPE_NONE,
|
||||
AMB_TYPE_POINT,
|
||||
AMB_TYPE_WORLD,
|
||||
} amb_type_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
AMB_MODE_NONE,
|
||||
AMB_MODE_CONTINUOUS,
|
||||
AMB_MODE_RANDOM,
|
||||
AMB_MODE_PERIODIC,
|
||||
} amb_mode_t;
|
||||
|
||||
static struct AmbientSound {
|
||||
amb_type_t type; // Ambient sound type
|
||||
amb_mode_t mode; // Ambient sound mode
|
||||
int periodmin; // # of tics between repeats
|
||||
int periodmax; // max # of tics for random ambients
|
||||
float volume; // relative volume of sound
|
||||
float attenuation; // Used for distance scaling
|
||||
char sound[MAX_SNDNAME+1]; // Logical name of sound to play
|
||||
} Ambients[256];
|
||||
|
||||
void S_HashSounds()
|
||||
{
|
||||
// Mark all buckets as empty
|
||||
for (auto& sfx : S_sfx)
|
||||
sfx.index = ~0;
|
||||
|
||||
// Now set up the chains
|
||||
for (unsigned i = 0; i < S_sfx.size(); i++)
|
||||
{
|
||||
const unsigned j = MakeKey(S_sfx[i].name) % static_cast<unsigned>(S_sfx.size() - 1);
|
||||
S_sfx[i].next = S_sfx[j].index;
|
||||
S_sfx[j].index = i;
|
||||
}
|
||||
}
|
||||
|
||||
int S_FindSound(const char *logicalname)
|
||||
{
|
||||
if (S_sfx.empty())
|
||||
return -1;
|
||||
|
||||
int i = S_sfx[MakeKey(logicalname) % static_cast<unsigned>(S_sfx.size() - 1)].index;
|
||||
|
||||
while ((i != -1) && strnicmp(S_sfx[i].name, logicalname, MAX_SNDNAME))
|
||||
i = S_sfx[i].next;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
int S_FindSoundByLump(int lump)
|
||||
{
|
||||
if (lump != -1)
|
||||
{
|
||||
for (unsigned i = 0; i < S_sfx.size(); i++)
|
||||
if (S_sfx[i].lumpnum == lump)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
size_t S_AddSoundLump(const char *logicalname, int lump)
|
||||
{
|
||||
sfxinfo_t& new_sfx = S_sfx.emplace_back();
|
||||
|
||||
// logicalname MUST be <= MAX_SNDNAME chars long
|
||||
M_StringCopy(new_sfx.name, logicalname, MAX_SNDNAME + 1);
|
||||
new_sfx.data = NULL;
|
||||
new_sfx.link = sfxinfo_t::NO_LINK;
|
||||
new_sfx.lumpnum = lump;
|
||||
return S_sfx.size() - 1;
|
||||
}
|
||||
|
||||
void S_ClearSoundLumps()
|
||||
{
|
||||
S_sfx.clear();
|
||||
S_rnd.clear();
|
||||
}
|
||||
|
||||
size_t FindSoundNoHash(const char* logicalname)
|
||||
{
|
||||
for (size_t i = 0; i < S_sfx.size(); i++)
|
||||
if (iequals(logicalname, S_sfx[i].name))
|
||||
return i;
|
||||
|
||||
return S_sfx.size();
|
||||
}
|
||||
|
||||
size_t FindSoundTentative(const char* name)
|
||||
{
|
||||
size_t id = FindSoundNoHash(name);
|
||||
if (id == S_sfx.size())
|
||||
{
|
||||
id = S_AddSoundLump(name, -1);
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
size_t S_AddSound(const char *logicalname, const char *lumpname)
|
||||
{
|
||||
size_t sfxid = FindSoundNoHash(logicalname);
|
||||
|
||||
const int lump = lumpname ? W_CheckNumForName(lumpname) : -1;
|
||||
|
||||
// Otherwise, prepare a new one.
|
||||
if (sfxid != S_sfx.size())
|
||||
{
|
||||
sfxinfo_t& sfx = S_sfx[sfxid];
|
||||
|
||||
sfx.lumpnum = lump;
|
||||
sfx.link = sfxinfo_t::NO_LINK;
|
||||
if (sfx.israndom)
|
||||
{
|
||||
S_rnd.erase(sfxid);
|
||||
sfx.israndom = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
sfxid = S_AddSoundLump(logicalname, lump);
|
||||
|
||||
return sfxid;
|
||||
}
|
||||
|
||||
void S_AddRandomSound(size_t owner, std::vector<size_t>& list)
|
||||
{
|
||||
S_rnd[owner] = list;
|
||||
S_sfx[owner].link = owner;
|
||||
S_sfx[owner].israndom = true;
|
||||
}
|
||||
|
||||
// S_ParseSndInfo
|
||||
// Parses all loaded SNDINFO lumps.
|
||||
void S_ParseSndInfo()
|
||||
{
|
||||
S_ClearSoundLumps();
|
||||
|
||||
int lump = -1;
|
||||
while ((lump = W_FindLump("SNDINFO", lump)) != -1)
|
||||
{
|
||||
char* buffer = static_cast<char*>(W_CacheLumpNum(lump, PU_CACHE));
|
||||
|
||||
const OScannerConfig config = {
|
||||
"SNDINFO", // lumpName
|
||||
true, // semiComments
|
||||
true, // cComments
|
||||
};
|
||||
OScanner os = OScanner::openBuffer(config, buffer, buffer + W_LumpLength(lump));
|
||||
|
||||
while (os.scan())
|
||||
{
|
||||
std::string tok = os.getToken();
|
||||
|
||||
// check if token is a command
|
||||
if (tok[0] == '$')
|
||||
{
|
||||
os.mustScan();
|
||||
if (os.compareTokenNoCase("ambient"))
|
||||
{
|
||||
// $ambient <num> <logical name> [point [atten]|surround] <type>
|
||||
// [secs] <relative volume>
|
||||
AmbientSound *ambient, dummy;
|
||||
|
||||
os.mustScanInt();
|
||||
const int index = os.getTokenInt();
|
||||
if (index < 0 || index > 255)
|
||||
{
|
||||
os.warning("Bad ambient index ({})\n", index);
|
||||
ambient = &dummy;
|
||||
}
|
||||
else
|
||||
{
|
||||
ambient = Ambients + index;
|
||||
}
|
||||
|
||||
ambient->type = AMB_TYPE_NONE;
|
||||
ambient->mode = AMB_MODE_NONE;
|
||||
ambient->periodmin = 0;
|
||||
ambient->periodmax = 0;
|
||||
ambient->volume = 0.0f;
|
||||
|
||||
os.mustScan();
|
||||
strncpy(ambient->sound, os.getToken().c_str(), MAX_SNDNAME);
|
||||
ambient->sound[MAX_SNDNAME] = 0;
|
||||
ambient->attenuation = 0.0f; // No change by default
|
||||
|
||||
os.mustScan();
|
||||
if (os.compareTokenNoCase("point"))
|
||||
{
|
||||
ambient->type = AMB_TYPE_POINT;
|
||||
os.mustScan();
|
||||
|
||||
if (IsRealNum(os.getToken().c_str()))
|
||||
{
|
||||
if (os.getTokenFloat() > 0.0f)
|
||||
{
|
||||
ambient->attenuation = os.getTokenFloat();
|
||||
}
|
||||
|
||||
os.mustScan();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ambient->type = AMB_TYPE_WORLD;
|
||||
|
||||
if (os.compareTokenNoCase("surround") ||
|
||||
os.compareTokenNoCase("world"))
|
||||
{
|
||||
os.mustScan();
|
||||
}
|
||||
}
|
||||
|
||||
if (os.compareTokenNoCase("continuous"))
|
||||
{
|
||||
ambient->mode = AMB_MODE_CONTINUOUS;
|
||||
}
|
||||
else if (os.compareTokenNoCase("random"))
|
||||
{
|
||||
ambient->mode = AMB_MODE_RANDOM;
|
||||
os.mustScanFloat();
|
||||
ambient->periodmin = static_cast<int>(os.getTokenFloat() * TICRATE);
|
||||
os.mustScanFloat();
|
||||
ambient->periodmax = static_cast<int>(os.getTokenFloat() * TICRATE);
|
||||
}
|
||||
else if (os.compareTokenNoCase("periodic"))
|
||||
{
|
||||
ambient->mode = AMB_MODE_PERIODIC;
|
||||
os.mustScanFloat();
|
||||
ambient->periodmin = static_cast<int>(os.getTokenFloat() * TICRATE);
|
||||
}
|
||||
else
|
||||
{
|
||||
os.warning("Unknown ambient type ({})\n", os.getToken());
|
||||
}
|
||||
|
||||
ambient->periodmin = MAX(0, ambient->periodmin);
|
||||
ambient->periodmax = MAX(ambient->periodmin, ambient->periodmax);
|
||||
|
||||
os.mustScanFloat();
|
||||
ambient->volume = clamp(os.getTokenFloat(), 0.0f, 1.0f);
|
||||
|
||||
if (ambient->mode == AMB_MODE_NONE || ambient->volume == 0.0f ||
|
||||
(ambient->mode != AMB_MODE_CONTINUOUS &&
|
||||
ambient->periodmin == 0 && ambient->periodmax == 0))
|
||||
{
|
||||
// Ignore bad ambient sounds
|
||||
ambient->type = AMB_TYPE_NONE;
|
||||
}
|
||||
}
|
||||
else if (os.compareTokenNoCase("map"))
|
||||
{
|
||||
// Hexen-style $MAP command
|
||||
char mapname[8];
|
||||
|
||||
os.mustScanInt();
|
||||
snprintf(mapname, 8, "MAP%02d", os.getTokenInt());
|
||||
level_pwad_info_t& info = getLevelInfos().findByName(mapname);
|
||||
os.mustScan();
|
||||
if (info.mapname[0])
|
||||
{
|
||||
info.music = os.getToken();
|
||||
}
|
||||
}
|
||||
else if (os.compareTokenNoCase("alias"))
|
||||
{
|
||||
os.mustScan();
|
||||
const size_t sfxfrom = S_AddSound(os.getToken().c_str(), NULL);
|
||||
os.mustScan();
|
||||
S_sfx[sfxfrom].link = FindSoundTentative(os.getToken().c_str());
|
||||
}
|
||||
else if (os.compareTokenNoCase("random"))
|
||||
{
|
||||
std::vector<size_t> list;
|
||||
|
||||
os.mustScan();
|
||||
const size_t owner = S_AddSound(os.getToken().c_str(), NULL);
|
||||
|
||||
os.mustScan();
|
||||
os.assertTokenIs("{");
|
||||
while (os.scan() && !os.compareToken("}"))
|
||||
{
|
||||
const size_t sfxto = FindSoundTentative(os.getToken().c_str());
|
||||
|
||||
if (owner == sfxto)
|
||||
{
|
||||
os.warning("Definition of random sound '{}' refers to itself "
|
||||
"recursively.\n", os.getToken());
|
||||
continue;
|
||||
}
|
||||
|
||||
list.push_back(sfxto);
|
||||
}
|
||||
if (list.size() == 1)
|
||||
{
|
||||
// only one sound; treat as alias
|
||||
S_sfx[owner].link = list[0];
|
||||
}
|
||||
else if (list.size() > 1)
|
||||
{
|
||||
S_AddRandomSound(owner, list);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
os.warning("Unknown SNDINFO command {}\n", os.getToken());
|
||||
while (os.scan())
|
||||
if (os.crossed())
|
||||
{
|
||||
os.unScan();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// token is a logical sound mapping
|
||||
char name[MAX_SNDNAME + 1];
|
||||
|
||||
strncpy(name, tok.c_str(), MAX_SNDNAME);
|
||||
name[MAX_SNDNAME] = 0;
|
||||
os.mustScan();
|
||||
|
||||
if (os.compareToken("="))
|
||||
{
|
||||
os.mustScan();
|
||||
}
|
||||
|
||||
S_AddSound(name, os.getToken().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
S_HashSounds();
|
||||
|
||||
sfx_empty = W_CheckNumForName("dsempty");
|
||||
sfx_noway = S_FindSoundByLump(W_CheckNumForName("dsnoway"));
|
||||
sfx_oof = S_FindSoundByLump(W_CheckNumForName("dsoof"));
|
||||
}
|
||||
|
||||
|
||||
static void SetTicker(int *tics, AmbientSound *ambient)
|
||||
{
|
||||
if (ambient->mode == AMB_MODE_CONTINUOUS)
|
||||
if (ambient->mode == amb_mode_t::CONTINUOUS)
|
||||
{
|
||||
*tics = 1;
|
||||
}
|
||||
else if (ambient->mode == AMB_MODE_RANDOM)
|
||||
else if (ambient->mode == amb_mode_t::RANDOM)
|
||||
{
|
||||
*tics = (int)(((float)rand() / (float)RAND_MAX) *
|
||||
(float)(ambient->periodmax - ambient->periodmin)) +
|
||||
|
|
@ -1599,7 +1257,7 @@ void A_Ambient(AActor *actor)
|
|||
|
||||
AmbientSound *ambient = &Ambients[actor->args[0]];
|
||||
|
||||
if (ambient->mode == AMB_MODE_CONTINUOUS)
|
||||
if (ambient->mode == amb_mode_t::CONTINUOUS)
|
||||
{
|
||||
if (S_GetSoundPlayingInfo (actor, S_FindSound (ambient->sound)))
|
||||
return;
|
||||
|
|
@ -1607,8 +1265,8 @@ void A_Ambient(AActor *actor)
|
|||
if (ambient->sound[0])
|
||||
{
|
||||
const int attn_type =
|
||||
(ambient->type == AMB_TYPE_POINT ? ATTN_IDLE : ATTN_NONE);
|
||||
S_StartNamedSound(actor, NULL, 0, 0, CHAN_AMBIENT, ambient->sound,
|
||||
(ambient->type == amb_type_t::POINT ? ATTN_IDLE : ATTN_NONE);
|
||||
S_StartNamedSound(actor, nullptr, 0, 0, CHAN_AMBIENT, ambient->sound,
|
||||
ambient->volume, attn_type, true, ambient->attenuation);
|
||||
|
||||
SetTicker (&actor->tics, ambient);
|
||||
|
|
@ -1623,8 +1281,8 @@ void A_Ambient(AActor *actor)
|
|||
if (ambient->sound[0])
|
||||
{
|
||||
const int attn_type =
|
||||
(ambient->type == AMB_TYPE_POINT ? ATTN_IDLE : ATTN_NONE);
|
||||
S_StartNamedSound(actor, NULL, 0, 0, CHAN_AMBIENT, ambient->sound,
|
||||
(ambient->type == amb_type_t::POINT ? ATTN_IDLE : ATTN_NONE);
|
||||
S_StartNamedSound(actor, nullptr, 0, 0, CHAN_AMBIENT, ambient->sound,
|
||||
ambient->volume, attn_type, false, ambient->attenuation);
|
||||
|
||||
SetTicker (&actor->tics, ambient);
|
||||
|
|
@ -1643,12 +1301,12 @@ void S_ActivateAmbient(AActor *origin, int ambient)
|
|||
|
||||
AmbientSound *amb = &Ambients[ambient];
|
||||
|
||||
if (amb->type == AMB_TYPE_NONE)
|
||||
if (amb->type == amb_type_t::NONE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (amb->mode != AMB_MODE_CONTINUOUS && amb->periodmin == 0)
|
||||
if (amb->mode != amb_mode_t::CONTINUOUS && amb->periodmin == 0)
|
||||
{
|
||||
const int sndnum = S_FindSound(amb->sound);
|
||||
if (sndnum == 0 || sndnum == -1)
|
||||
|
|
@ -1671,11 +1329,11 @@ BEGIN_COMMAND (snd_soundlist)
|
|||
if (S_sfx[i].lumpnum != -1)
|
||||
{
|
||||
const OLumpName lumpname = lumpinfo[S_sfx[i].lumpnum].name;
|
||||
Printf(PRINT_HIGH, "%3d. %s (%s)\n", i+1, S_sfx[i].name, lumpname.c_str());
|
||||
PrintFmt(PRINT_HIGH, "{:>3d}. {} ({})\n", i+1, S_sfx[i].name, lumpname);
|
||||
}
|
||||
// todo: check if sounds are multiple lumps rather than just one (i.e. random sounds)
|
||||
else
|
||||
Printf (PRINT_HIGH, "%3d. %s **not present**\n", i+1, S_sfx[i].name);
|
||||
PrintFmt(PRINT_HIGH, "{:>3d}. {} **not present**\n", i+1, S_sfx[i].name);
|
||||
}
|
||||
END_COMMAND (snd_soundlist)
|
||||
|
||||
|
|
@ -1683,7 +1341,7 @@ BEGIN_COMMAND (snd_soundlinks)
|
|||
{
|
||||
for (const auto& sfx : S_sfx)
|
||||
if (sfx.link != static_cast<int>(sfxinfo_t::NO_LINK))
|
||||
Printf(PRINT_HIGH, "%s -> %s\n", sfx.name, S_sfx[sfx.link].name);
|
||||
PrintFmt(PRINT_HIGH, "{} -> {}\n", sfx.name, S_sfx[sfx.link].name);
|
||||
}
|
||||
END_COMMAND (snd_soundlinks)
|
||||
|
||||
|
|
@ -1698,11 +1356,11 @@ BEGIN_COMMAND (changemus)
|
|||
{
|
||||
if (argc == 1)
|
||||
{
|
||||
Printf(PRINT_HIGH, "Usage: changemus lumpname [loop]");
|
||||
Printf(PRINT_HIGH, "\n");
|
||||
Printf(PRINT_HIGH, "Plays music from an internal lump, loop\n");
|
||||
Printf(PRINT_HIGH, "parameter determines if the music should play\n");
|
||||
Printf(PRINT_HIGH, "continuously or not, (1 or 0, default: 1)\n");
|
||||
PrintFmt(PRINT_HIGH, "Usage: changemus lumpname [loop]");
|
||||
PrintFmt(PRINT_HIGH, "\n");
|
||||
PrintFmt(PRINT_HIGH, "Plays music from an internal lump, loop\n");
|
||||
PrintFmt(PRINT_HIGH, "parameter determines if the music should play\n");
|
||||
PrintFmt(PRINT_HIGH, "continuously or not, (1 or 0, default: 1)\n");
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
@ -1725,7 +1383,7 @@ END_COMMAND (changemus)
|
|||
// UV_SoundAvoidCl
|
||||
// Sends a sound to clients, but doesn't send it to client 'player'.
|
||||
//
|
||||
void UV_SoundAvoidPlayer(AActor *mo, byte channel, const char *name, byte attenuation)
|
||||
void UV_SoundAvoidPlayer(const AActor *mo, byte channel, const char *name, byte attenuation)
|
||||
{
|
||||
S_Sound(mo, channel, name, 1, attenuation);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -438,6 +438,33 @@ void ST_voteDraw (int y) {
|
|||
true, false, true);
|
||||
ST_DrawBar(CR_GREEN, vote_state.yes, vote_state.yes_needed,
|
||||
(I_GetSurfaceWidth() >> 1), y, xscale * 40, false, true);
|
||||
|
||||
// [RV] Show bound keys for YES/NO while vote is undecided
|
||||
if (vote_state.result == VOTE_UNDEC)
|
||||
{
|
||||
// Use the same binding helper as the warmup code
|
||||
const std::string yesKey = ::Bindings.GetKeynameFromCommand("vote_yes");
|
||||
const std::string noKey = ::Bindings.GetKeynameFromCommand("vote_no");
|
||||
|
||||
// Fallbacks if nothing bound
|
||||
const char* yesStr = yesKey.empty() ? "Y" : yesKey.c_str();
|
||||
const char* noStr = noKey.empty() ? "N" : noKey.c_str();
|
||||
|
||||
// Match the warmup style (fmt::sprintf + TEXTCOLOR_* tags)
|
||||
const std::string hint = fmt::sprintf(
|
||||
"Press %s%s%s for %sYES%s, %s%s%s for %sNO%s", TEXTCOLOR_GOLD, yesStr,
|
||||
TEXTCOLOR_NORMAL, TEXTCOLOR_GREEN, TEXTCOLOR_NORMAL, TEXTCOLOR_GOLD, noStr,
|
||||
TEXTCOLOR_NORMAL, TEXTCOLOR_RED, TEXTCOLOR_NORMAL);
|
||||
|
||||
int hint_w = V_StringWidth(hint.c_str()) * xscale;
|
||||
int hx = (I_GetSurfaceWidth() - hint_w) >> 1;
|
||||
|
||||
y += yscale * 8; // place one line below the votestring lines
|
||||
if (hud_scale)
|
||||
screen->DrawTextClean(CR_GRAY, hx, y, hint.c_str());
|
||||
else
|
||||
screen->DrawText(CR_GRAY, hx, y, hint.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
namespace hud {
|
||||
|
|
|
|||
|
|
@ -645,7 +645,7 @@ BEGIN_COMMAND (idmus)
|
|||
map = CalcMapName(0, l);
|
||||
else
|
||||
{
|
||||
Printf(PRINT_HIGH, "%s\n", GStrings(STSTR_NOMUS));
|
||||
PrintFmt(PRINT_HIGH, "{}\n", GStrings(STSTR_NOMUS));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -660,12 +660,12 @@ BEGIN_COMMAND (idmus)
|
|||
if (info.music[0])
|
||||
{
|
||||
S_ChangeMusic(std::string(info.music.c_str(), 8), 1);
|
||||
Printf(PRINT_HIGH, "%s\n", GStrings(STSTR_MUS));
|
||||
PrintFmt(PRINT_HIGH, "{}\n", GStrings(STSTR_MUS));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Printf(PRINT_HIGH, "%s\n", GStrings(STSTR_NOMUS));
|
||||
PrintFmt(PRINT_HIGH, "{}\n", GStrings(STSTR_NOMUS));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -694,7 +694,7 @@ BEGIN_COMMAND (fov)
|
|||
return;
|
||||
|
||||
if (argc != 2)
|
||||
Printf(PRINT_HIGH, "FOV is %g\n", m_Instigator->player->fov);
|
||||
PrintFmt(PRINT_HIGH, "FOV is {:g}\n", m_Instigator->player->fov);
|
||||
else
|
||||
{
|
||||
m_Instigator->player->fov = clamp((float)atof(argv[1]), 45.0f, 135.0f);
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue