mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-12-28 02:32:48 +00:00
Merge branch 'threaded-software' into 'master'
Threaded software See merge request KartKrew/Kart!1553
This commit is contained in:
commit
005d05ac15
36 changed files with 2734 additions and 1730 deletions
|
|
@ -71,7 +71,7 @@ add_executable(SRB2SDL2 MACOSX_BUNDLE WIN32
|
|||
r_debug_parser.cpp
|
||||
r_draw.c
|
||||
r_fps.c
|
||||
r_main.c
|
||||
r_main.cpp
|
||||
r_plane.cpp
|
||||
r_segs.cpp
|
||||
r_skins.c
|
||||
|
|
|
|||
|
|
@ -1,3 +1,8 @@
|
|||
target_sources(SRB2SDL2 PRIVATE
|
||||
memory.cpp
|
||||
memory.h
|
||||
spmc_queue.hpp
|
||||
static_vec.hpp
|
||||
thread_pool.cpp
|
||||
thread_pool.h
|
||||
)
|
||||
|
|
|
|||
70
src/core/memory.cpp
Normal file
70
src/core/memory.cpp
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2023 by Ronald "Eidolon" Kinard
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "memory.h"
|
||||
|
||||
#include <array>
|
||||
#include <new>
|
||||
|
||||
#include "../z_zone.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
class LinearMemory
|
||||
{
|
||||
size_t size_;
|
||||
size_t height_;
|
||||
void* memory_;
|
||||
|
||||
public:
|
||||
constexpr explicit LinearMemory(size_t size) noexcept;
|
||||
|
||||
void* allocate(size_t size);
|
||||
void reset() noexcept;
|
||||
};
|
||||
|
||||
constexpr LinearMemory::LinearMemory(size_t size) noexcept : size_(size), height_{0}, memory_{nullptr} {}
|
||||
|
||||
void* LinearMemory::allocate(size_t size)
|
||||
{
|
||||
size_t aligned_size = (size + 15) & ~15;
|
||||
if (height_ + aligned_size > size_)
|
||||
{
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
|
||||
if (memory_ == nullptr)
|
||||
{
|
||||
memory_ = Z_Malloc(size_, PU_STATIC, nullptr);
|
||||
}
|
||||
|
||||
void* ptr = (void*)((uintptr_t)(memory_) + height_);
|
||||
height_ += aligned_size;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void LinearMemory::reset() noexcept
|
||||
{
|
||||
height_ = 0;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
static LinearMemory g_frame_memory {4 * 1024 * 1024};
|
||||
|
||||
void* Z_Frame_Alloc(size_t size)
|
||||
{
|
||||
return g_frame_memory.allocate(size);
|
||||
}
|
||||
|
||||
void Z_Frame_Reset()
|
||||
{
|
||||
g_frame_memory.reset();
|
||||
}
|
||||
31
src/core/memory.h
Normal file
31
src/core/memory.h
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2023 by Ronald "Eidolon" Kinard
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef __SRB2_CORE_MEMORY_H__
|
||||
#define __SRB2_CORE_MEMORY_H__
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cpluspplus
|
||||
|
||||
/// @brief Allocate a block of memory with a lifespan of the current main-thread frame.
|
||||
/// This function is NOT thread-safe, but the allocated memory may be used across threads.
|
||||
/// @return a pointer to a block of memory aligned with libc malloc alignment, or null if allocation fails
|
||||
void* Z_Frame_Alloc(size_t size);
|
||||
|
||||
/// @brief Resets per-frame memory. Not thread safe.
|
||||
void Z_Frame_Reset(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // __SRB2_CORE_MEMORY_H__
|
||||
192
src/core/spmc_queue.hpp
Normal file
192
src/core/spmc_queue.hpp
Normal file
|
|
@ -0,0 +1,192 @@
|
|||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
// This class is derived from Conor Williams' implementation of a concurrent deque
|
||||
// https://github.com/ConorWilliams/ConcurrentDeque
|
||||
// Copyright (C) 2021 Conor Williams
|
||||
|
||||
// The original version was for C++23. This one has been shrunk slightly and adapted to our conventions.
|
||||
|
||||
#ifndef __SRB2_CORE_SPMC_QUEUE_HPP__
|
||||
#define __SRB2_CORE_SPMC_QUEUE_HPP__
|
||||
|
||||
#include <array>
|
||||
#include <atomic>
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
|
||||
#include <tracy/tracy/Tracy.hpp>
|
||||
|
||||
#include "../cxxutil.hpp"
|
||||
|
||||
namespace srb2
|
||||
{
|
||||
|
||||
template <typename T>
|
||||
class SpMcQueue
|
||||
{
|
||||
struct RingBuff {
|
||||
public:
|
||||
explicit RingBuff(int64_t cap) : _cap{cap}, _mask{cap - 1}
|
||||
{
|
||||
SRB2_ASSERT(cap && (!(cap & (cap - 1))) && "Capacity must be buf power of 2!");
|
||||
_buff = std::unique_ptr<T[]>(new T[_cap]);
|
||||
}
|
||||
|
||||
std::int64_t capacity() const noexcept { return _cap; }
|
||||
|
||||
// Store (copy) at modulo index
|
||||
void store(int64_t i, T&& x) noexcept
|
||||
{
|
||||
_buff[i & _mask] = std::move(x);
|
||||
}
|
||||
|
||||
// Load (copy) at modulo index
|
||||
T load(int64_t i) const noexcept
|
||||
{
|
||||
return _buff[i & _mask];
|
||||
}
|
||||
|
||||
// Allocates and returns a new ring buffer, copies elements in range [b, t) into the new buffer.
|
||||
RingBuff* resize(std::int64_t b, std::int64_t t) const
|
||||
{
|
||||
ZoneScoped;
|
||||
RingBuff* ptr = new RingBuff{2 * _cap};
|
||||
for (std::int64_t i = t; i != b; ++i) {
|
||||
ptr->store(i, load(i));
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
private:
|
||||
int64_t _cap; // Capacity of the buffer
|
||||
int64_t _mask; // Bit mask to perform modulo capacity operations
|
||||
|
||||
std::unique_ptr<T[]> _buff;
|
||||
};
|
||||
|
||||
alignas(64) std::atomic<int64_t> bottom_;
|
||||
alignas(64) std::atomic<int64_t> top_;
|
||||
alignas(64) std::atomic<RingBuff*> buffer_;
|
||||
|
||||
std::vector<std::unique_ptr<RingBuff>> garbage_;
|
||||
|
||||
public:
|
||||
SpMcQueue(size_t capacity) : bottom_(0), top_(0), buffer_(new RingBuff(capacity))
|
||||
{
|
||||
garbage_.reserve(32);
|
||||
}
|
||||
~SpMcQueue() noexcept
|
||||
{
|
||||
delete buffer_.load(std::memory_order_relaxed);
|
||||
};
|
||||
|
||||
size_t size() const noexcept
|
||||
{
|
||||
int64_t bottom = bottom_.load(std::memory_order_relaxed);
|
||||
int64_t top = top_.load(std::memory_order_relaxed);
|
||||
return static_cast<size_t>(bottom >= top ? bottom - top : 0);
|
||||
}
|
||||
|
||||
bool empty() const noexcept
|
||||
{
|
||||
return size() == 0;
|
||||
}
|
||||
|
||||
void push(T&& v) noexcept
|
||||
{
|
||||
int64_t bottom = bottom_.load(std::memory_order_relaxed);
|
||||
int64_t top = top_.load(std::memory_order_acquire);
|
||||
RingBuff* buf = buffer_.load(std::memory_order_relaxed);
|
||||
|
||||
if (buf->capacity() < (bottom - top) + 1)
|
||||
{
|
||||
// Queue is full, build a new one
|
||||
RingBuff* newbuf = buf->resize(bottom, top);
|
||||
garbage_.emplace_back(buf);
|
||||
buffer_.store(newbuf, std::memory_order_relaxed);
|
||||
buf = newbuf;
|
||||
}
|
||||
|
||||
// Construct new object, this does not have to be atomic as no one can steal this item until after we
|
||||
// store the new value of bottom, ordering is maintained by surrounding atomics.
|
||||
buf->store(bottom, std::move(v));
|
||||
|
||||
std::atomic_thread_fence(std::memory_order_release);
|
||||
bottom_.store(bottom + 1, std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
std::optional<T> pop() noexcept
|
||||
{
|
||||
int64_t bottom = bottom_.load(std::memory_order_relaxed) - 1;
|
||||
RingBuff* buf = buffer_.load(std::memory_order_relaxed);
|
||||
|
||||
bottom_.store(bottom, std::memory_order_relaxed); // Stealers can no longer steal
|
||||
|
||||
std::atomic_thread_fence(std::memory_order_seq_cst);
|
||||
int64_t top = top_.load(std::memory_order_relaxed);
|
||||
|
||||
if (top <= bottom)
|
||||
{
|
||||
// Non-empty deque
|
||||
if (top == bottom)
|
||||
{
|
||||
// The last item could get stolen, by a stealer that loaded bottom before our write above
|
||||
if (!top_.compare_exchange_strong(top, top + 1, std::memory_order_seq_cst, std::memory_order_relaxed))
|
||||
{
|
||||
// Failed race, thief got the last item.
|
||||
bottom_.store(bottom + 1, std::memory_order_relaxed);
|
||||
return std::nullopt;
|
||||
}
|
||||
bottom_.store(bottom + 1, std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
// Can delay load until after acquiring slot as only this thread can push(), this load is not
|
||||
// required to be atomic as we are the exclusive writer.
|
||||
return buf->load(bottom);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
bottom_.store(bottom + 1, std::memory_order_relaxed);
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<T> steal() noexcept
|
||||
{
|
||||
int64_t top = top_.load(std::memory_order_acquire);
|
||||
std::atomic_thread_fence(std::memory_order_seq_cst);
|
||||
int64_t bottom = bottom_.load(std::memory_order_acquire);
|
||||
|
||||
if (top < bottom)
|
||||
{
|
||||
// Must load *before* acquiring the slot as slot may be overwritten immediately after acquiring.
|
||||
// This load is NOT required to be atomic even-though it may race with an overrite as we only
|
||||
// return the value if we win the race below garanteeing we had no race during our read. If we
|
||||
// loose the race then 'x' could be corrupt due to read-during-write race but as T is trivially
|
||||
// destructible this does not matter.
|
||||
T x = buffer_.load(std::memory_order_consume)->load(top);
|
||||
|
||||
if (!top_.compare_exchange_strong(top, top + 1, std::memory_order_seq_cst, std::memory_order_relaxed))
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return x;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace srb2
|
||||
|
||||
#endif // __SRB2_CORE_SPMC_QUEUE_HPP__
|
||||
345
src/core/thread_pool.cpp
Normal file
345
src/core/thread_pool.cpp
Normal file
|
|
@ -0,0 +1,345 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2023 by Ronald "Eidolon" Kinard
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "thread_pool.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <condition_variable>
|
||||
#include <exception>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <system_error>
|
||||
|
||||
#include <fmt/format.h>
|
||||
#include <tracy/tracy/Tracy.hpp>
|
||||
|
||||
#include "../cxxutil.hpp"
|
||||
#include "../m_argv.h"
|
||||
|
||||
using namespace srb2;
|
||||
|
||||
static void do_work(ThreadPool::Task& work)
|
||||
{
|
||||
try
|
||||
{
|
||||
ZoneScoped;
|
||||
(work.thunk)(work.raw.data());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
// can't do anything
|
||||
}
|
||||
|
||||
(work.deleter)(work.raw.data());
|
||||
if (work.pseudosema)
|
||||
{
|
||||
work.pseudosema->fetch_sub(1, std::memory_order_relaxed);
|
||||
}
|
||||
}
|
||||
|
||||
static void pool_executor(
|
||||
int thread_index,
|
||||
std::shared_ptr<std::atomic<bool>> pool_alive,
|
||||
std::shared_ptr<std::mutex> worker_ready_mutex,
|
||||
std::shared_ptr<std::condition_variable> worker_ready_condvar,
|
||||
std::shared_ptr<ThreadPool::Queue> my_wq,
|
||||
std::vector<std::shared_ptr<ThreadPool::Queue>> other_wqs
|
||||
)
|
||||
{
|
||||
{
|
||||
std::string thread_name = fmt::format("Thread Pool Thread {}", thread_index);
|
||||
tracy::SetThreadName(thread_name.c_str());
|
||||
}
|
||||
|
||||
int spins = 0;
|
||||
while (true)
|
||||
{
|
||||
std::optional<ThreadPool::Task> work = my_wq->steal();
|
||||
bool did_work = false;
|
||||
if (work)
|
||||
{
|
||||
do_work(*work);
|
||||
|
||||
did_work = true;
|
||||
spins = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (auto& q : other_wqs)
|
||||
{
|
||||
work = q->steal();
|
||||
if (work)
|
||||
{
|
||||
do_work(*work);
|
||||
|
||||
did_work = true;
|
||||
spins = 0;
|
||||
|
||||
// We only want to steal one work item at a time, to prioritize our own queue
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!did_work)
|
||||
{
|
||||
// Spin a few loops to avoid yielding, then wait for the ready lock
|
||||
spins += 1;
|
||||
if (spins > 100)
|
||||
{
|
||||
std::unique_lock<std::mutex> ready_lock {*worker_ready_mutex};
|
||||
while (my_wq->empty() && pool_alive->load())
|
||||
{
|
||||
worker_ready_condvar->wait(ready_lock);
|
||||
}
|
||||
|
||||
if (!pool_alive->load())
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ThreadPool::ThreadPool()
|
||||
{
|
||||
immediate_mode_ = true;
|
||||
}
|
||||
|
||||
ThreadPool::ThreadPool(size_t threads)
|
||||
{
|
||||
next_queue_index_ = 0;
|
||||
pool_alive_ = std::make_shared<std::atomic<bool>>(true);
|
||||
|
||||
for (size_t i = 0; i < threads; i++)
|
||||
{
|
||||
std::shared_ptr<Queue> wsq = std::make_shared<Queue>(2048);
|
||||
work_queues_.push_back(wsq);
|
||||
|
||||
std::shared_ptr<std::mutex> mutex = std::make_shared<std::mutex>();
|
||||
worker_ready_mutexes_.push_back(std::move(mutex));
|
||||
std::shared_ptr<std::condition_variable> condvar = std::make_shared<std::condition_variable>();
|
||||
worker_ready_condvars_.push_back(std::move(condvar));
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < threads; i++)
|
||||
{
|
||||
std::shared_ptr<Queue> my_queue = work_queues_[i];
|
||||
std::vector<std::shared_ptr<Queue>> other_queues;
|
||||
for (size_t j = 0; j < threads; j++)
|
||||
{
|
||||
// Order the other queues starting from the next adjacent worker
|
||||
// i.e. if this is worker 2 of 8, then other queues is 3, 4, 5, 6, 7, 0, 1
|
||||
// This tries to balance out work stealing behavior
|
||||
|
||||
size_t other_index = j + i;
|
||||
if (other_index >= threads)
|
||||
{
|
||||
other_index -= threads;
|
||||
}
|
||||
|
||||
if (other_index != i)
|
||||
{
|
||||
other_queues.push_back(work_queues_[other_index]);
|
||||
}
|
||||
}
|
||||
|
||||
std::thread thread;
|
||||
try
|
||||
{
|
||||
thread = std::thread
|
||||
{
|
||||
pool_executor,
|
||||
i,
|
||||
pool_alive_,
|
||||
worker_ready_mutexes_[i],
|
||||
worker_ready_condvars_[i],
|
||||
my_queue,
|
||||
other_queues
|
||||
};
|
||||
}
|
||||
catch (const std::system_error& error)
|
||||
{
|
||||
// Safe shutdown and rethrow
|
||||
pool_alive_->store(false);
|
||||
for (auto& t : threads_)
|
||||
{
|
||||
t.join();
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
|
||||
threads_.push_back(std::move(thread));
|
||||
}
|
||||
}
|
||||
|
||||
ThreadPool::ThreadPool(ThreadPool&&) = default;
|
||||
ThreadPool::~ThreadPool() = default;
|
||||
|
||||
ThreadPool& ThreadPool::operator=(ThreadPool&&) = default;
|
||||
|
||||
void ThreadPool::begin_sema()
|
||||
{
|
||||
sema_begun_ = true;
|
||||
}
|
||||
|
||||
ThreadPool::Sema ThreadPool::end_sema()
|
||||
{
|
||||
Sema ret = Sema(std::move(cur_sema_));
|
||||
cur_sema_ = nullptr;
|
||||
sema_begun_ = false;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ThreadPool::notify()
|
||||
{
|
||||
for (size_t i = 0; i < work_queues_.size(); i++)
|
||||
{
|
||||
auto& q = work_queues_[i];
|
||||
size_t count = q->size();
|
||||
if (count > 0)
|
||||
{
|
||||
worker_ready_condvars_[i]->notify_one();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ThreadPool::notify_sema(const ThreadPool::Sema& sema)
|
||||
{
|
||||
if (!sema.pseudosema_)
|
||||
{
|
||||
return;
|
||||
}
|
||||
notify();
|
||||
}
|
||||
|
||||
void ThreadPool::wait_idle()
|
||||
{
|
||||
if (immediate_mode_)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ZoneScoped;
|
||||
|
||||
for (size_t i = 0; i < work_queues_.size(); i++)
|
||||
{
|
||||
auto& q = work_queues_[i];
|
||||
|
||||
std::optional<Task> work;
|
||||
while ((work = q->pop()).has_value())
|
||||
{
|
||||
do_work(*work);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ThreadPool::wait_sema(const Sema& sema)
|
||||
{
|
||||
if (!sema.pseudosema_)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ZoneScoped;
|
||||
|
||||
while (sema.pseudosema_->load(std::memory_order_seq_cst) > 0)
|
||||
{
|
||||
// spin to win
|
||||
for (size_t i = 0; i < work_queues_.size(); i++)
|
||||
{
|
||||
auto& q = work_queues_[i];
|
||||
|
||||
std::optional<Task> work;
|
||||
if ((work = q->pop()).has_value())
|
||||
{
|
||||
do_work(*work);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sema.pseudosema_->load(std::memory_order_seq_cst) != 0)
|
||||
{
|
||||
throw std::exception();
|
||||
}
|
||||
}
|
||||
|
||||
void ThreadPool::shutdown()
|
||||
{
|
||||
if (immediate_mode_)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
wait_idle();
|
||||
|
||||
pool_alive_->store(false);
|
||||
|
||||
for (auto& condvar : worker_ready_condvars_)
|
||||
{
|
||||
condvar->notify_all();
|
||||
}
|
||||
for (auto& t : threads_)
|
||||
{
|
||||
t.join();
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<ThreadPool> srb2::g_main_threadpool;
|
||||
|
||||
void I_ThreadPoolInit(void)
|
||||
{
|
||||
SRB2_ASSERT(g_main_threadpool == nullptr);
|
||||
size_t thread_count = std::min(static_cast<unsigned int>(9), std::thread::hardware_concurrency());
|
||||
if (thread_count > 1)
|
||||
{
|
||||
// The main thread will act as a worker when waiting for pool idle
|
||||
// Make one less worker thread to avoid unnecessary context switching
|
||||
thread_count -= 1;
|
||||
}
|
||||
|
||||
if (M_CheckParm("-singlethreaded"))
|
||||
{
|
||||
g_main_threadpool = std::make_unique<ThreadPool>();
|
||||
}
|
||||
else
|
||||
{
|
||||
g_main_threadpool = std::make_unique<ThreadPool>(thread_count);
|
||||
}
|
||||
}
|
||||
|
||||
void I_ThreadPoolShutdown(void)
|
||||
{
|
||||
if (!g_main_threadpool)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
g_main_threadpool->shutdown();
|
||||
g_main_threadpool = nullptr;
|
||||
}
|
||||
|
||||
void I_ThreadPoolSubmit(srb2cthunk_t thunk, void* data)
|
||||
{
|
||||
SRB2_ASSERT(g_main_threadpool != nullptr);
|
||||
|
||||
g_main_threadpool->schedule([=]() {
|
||||
(thunk)(data);
|
||||
});
|
||||
g_main_threadpool->notify();
|
||||
}
|
||||
|
||||
void I_ThreadPoolWaitIdle(void)
|
||||
{
|
||||
SRB2_ASSERT(g_main_threadpool != nullptr);
|
||||
|
||||
g_main_threadpool->wait_idle();
|
||||
}
|
||||
162
src/core/thread_pool.h
Normal file
162
src/core/thread_pool.h
Normal file
|
|
@ -0,0 +1,162 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2023 by Ronald "Eidolon" Kinard
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef __SRB2_CORE_THREAD_POOL_H__
|
||||
#define __SRB2_CORE_THREAD_POOL_H__
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include <condition_variable>
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "spmc_queue.hpp"
|
||||
|
||||
namespace srb2
|
||||
{
|
||||
|
||||
class ThreadPool
|
||||
{
|
||||
public:
|
||||
struct Task
|
||||
{
|
||||
void (*thunk)(void*);
|
||||
void (*deleter)(void*);
|
||||
std::shared_ptr<std::atomic<uint32_t>> pseudosema;
|
||||
std::array<std::byte, 512 - sizeof(void(*)(void*)) * 2 - sizeof(std::shared_ptr<std::atomic<uint32_t>>)> raw;
|
||||
};
|
||||
|
||||
using Queue = SpMcQueue<Task>;
|
||||
|
||||
class Sema
|
||||
{
|
||||
std::shared_ptr<std::atomic<uint32_t>> pseudosema_;
|
||||
|
||||
explicit Sema(std::shared_ptr<std::atomic<uint32_t>> sema) : pseudosema_(sema) {}
|
||||
|
||||
friend class ThreadPool;
|
||||
public:
|
||||
Sema() = default;
|
||||
};
|
||||
|
||||
private:
|
||||
std::shared_ptr<std::atomic<bool>> pool_alive_;
|
||||
std::vector<std::shared_ptr<std::mutex>> worker_ready_mutexes_;
|
||||
std::vector<std::shared_ptr<std::condition_variable>> worker_ready_condvars_;
|
||||
std::vector<std::shared_ptr<Queue>> work_queues_;
|
||||
std::vector<std::thread> threads_;
|
||||
size_t next_queue_index_ = 0;
|
||||
std::shared_ptr<std::atomic<uint32_t>> cur_sema_;
|
||||
|
||||
bool immediate_mode_ = false;
|
||||
bool sema_begun_ = false;
|
||||
|
||||
public:
|
||||
ThreadPool();
|
||||
explicit ThreadPool(size_t threads);
|
||||
ThreadPool(const ThreadPool&) = delete;
|
||||
ThreadPool(ThreadPool&&);
|
||||
~ThreadPool();
|
||||
|
||||
ThreadPool& operator=(const ThreadPool&) = delete;
|
||||
ThreadPool& operator=(ThreadPool&&);
|
||||
|
||||
void begin_sema();
|
||||
ThreadPool::Sema end_sema();
|
||||
|
||||
/// Enqueue but don't notify
|
||||
template <typename T> void schedule(T&& thunk);
|
||||
/// Notify threads after several schedules
|
||||
void notify();
|
||||
void notify_sema(const Sema& sema);
|
||||
void wait_idle();
|
||||
void wait_sema(const Sema& sema);
|
||||
void shutdown();
|
||||
};
|
||||
|
||||
extern std::unique_ptr<ThreadPool> g_main_threadpool;
|
||||
|
||||
template <typename F>
|
||||
void callable_caller(F* f)
|
||||
{
|
||||
(*f)();
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
void callable_destroyer(F* f)
|
||||
{
|
||||
f->~F();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void ThreadPool::schedule(T&& thunk)
|
||||
{
|
||||
static_assert(sizeof(T) <= sizeof(std::declval<Task>().raw));
|
||||
|
||||
if (immediate_mode_)
|
||||
{
|
||||
(thunk)();
|
||||
return;
|
||||
}
|
||||
|
||||
if (sema_begun_)
|
||||
{
|
||||
if (cur_sema_ == nullptr)
|
||||
{
|
||||
cur_sema_ = std::make_shared<std::atomic<uint32_t>>(0);
|
||||
}
|
||||
cur_sema_->fetch_add(1, std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
size_t qi = next_queue_index_;
|
||||
|
||||
{
|
||||
std::shared_ptr<Queue> q = work_queues_[qi];
|
||||
Task task;
|
||||
task.thunk = reinterpret_cast<void(*)(void*)>(callable_caller<T>);
|
||||
task.deleter = reinterpret_cast<void(*)(void*)>(callable_destroyer<T>);
|
||||
task.pseudosema = cur_sema_;
|
||||
new (reinterpret_cast<T*>(task.raw.data())) T(std::move(thunk));
|
||||
|
||||
q->push(std::move(task));
|
||||
}
|
||||
// worker_ready_condvars_[qi]->notify_one();
|
||||
|
||||
next_queue_index_ += 1;
|
||||
if (next_queue_index_ >= threads_.size())
|
||||
{
|
||||
next_queue_index_ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace srb2
|
||||
|
||||
extern "C" {
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
typedef void (*srb2cthunk_t)(void*);
|
||||
|
||||
void I_ThreadPoolInit(void);
|
||||
void I_ThreadPoolShutdown(void);
|
||||
void I_ThreadPoolSubmit(srb2cthunk_t thunk, void* data);
|
||||
void I_ThreadPoolWaitIdle(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // __SRB2_CORE_THREAD_POOL_H__
|
||||
|
|
@ -72,6 +72,7 @@
|
|||
#include "filesrch.h" // refreshdirmenu
|
||||
#include "g_input.h" // tutorial mode control scheming
|
||||
#include "m_perfstats.h"
|
||||
#include "core/memory.h"
|
||||
|
||||
#include "monocypher/monocypher.h"
|
||||
#include "stun.h"
|
||||
|
|
@ -541,7 +542,7 @@ static void D_Display(void)
|
|||
viewssnum = i;
|
||||
|
||||
#ifdef HWRENDER
|
||||
if (rendermode != render_soft)
|
||||
if (rendermode == render_opengl)
|
||||
HWR_RenderPlayerView();
|
||||
else
|
||||
#endif
|
||||
|
|
@ -822,6 +823,8 @@ void D_SRB2Loop(void)
|
|||
precise_t enterprecise = I_GetPreciseTime();
|
||||
precise_t finishprecise = enterprecise;
|
||||
|
||||
Z_Frame_Reset();
|
||||
|
||||
{
|
||||
// Casting the return value of a function is bad practice (apparently)
|
||||
double budget = round((1.0 / R_GetFramerateCap()) * I_GetPrecisePrecision());
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
#include "r_picformats.h"
|
||||
#include "r_things.h" // R_Char2Frame
|
||||
#include "r_sky.h"
|
||||
#include "s_sound.h"
|
||||
#include "fastcmp.h"
|
||||
#include "lua_script.h" // Reluctantly included for LUA_EvalMath
|
||||
#include "d_clisrv.h"
|
||||
|
|
@ -1221,7 +1222,7 @@ void readlevelheader(MYFILE *f, char * name)
|
|||
sizeof(mapheaderinfo[num]->musname[j]), va("Level header %d: music", num));
|
||||
j++;
|
||||
} while ((tmp = strtok(NULL,",")) != NULL);
|
||||
|
||||
|
||||
if (tmp != NULL)
|
||||
deh_warning("Level header %d: additional music slots past %d discarded", num, MAXMUSNAMES);
|
||||
mapheaderinfo[num]->musname_size = j;
|
||||
|
|
@ -1245,7 +1246,7 @@ void readlevelheader(MYFILE *f, char * name)
|
|||
sizeof(mapheaderinfo[num]->associatedmus[j]), va("Level header %d: associated music", num));
|
||||
j++;
|
||||
} while ((tmp = strtok(NULL,",")) != NULL);
|
||||
|
||||
|
||||
if (tmp != NULL)
|
||||
deh_warning("Level header %d: additional associated music slots past %d discarded", num, MAXMUSNAMES);
|
||||
mapheaderinfo[num]->associatedmus_size = j;
|
||||
|
|
@ -2763,7 +2764,7 @@ static void readcondition(UINT16 set, UINT32 id, char *word2)
|
|||
deh_warning("Invalid cup result %s for condition ID %d", params[2], id+1);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
else if ((offset=0) || fastcmp(params[0], "PODIUMEMERALD")
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
#include "k_menu.h" // gametype_cons_t
|
||||
#include "r_things.h" // skins
|
||||
#include "mserv.h" // cv_advertise
|
||||
#include "s_sound.h"
|
||||
#include "z_zone.h"
|
||||
#include "byteptr.h"
|
||||
#include "stun.h"
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
#include "p_local.h"
|
||||
#include "p_mobj.h"
|
||||
#include "r_textures.h"
|
||||
#include "s_sound.h"
|
||||
#include "w_wad.h"
|
||||
#include "z_zone.h"
|
||||
|
||||
|
|
@ -740,7 +741,7 @@ static void K_SpawnSplashParticles(mobj_t *mo, t_splash_t *s, fixed_t impact)
|
|||
{
|
||||
mobj_t *dust = NULL;
|
||||
angle_t pushAngle = (particleSpread * i);
|
||||
|
||||
|
||||
fixed_t xOff = 0;
|
||||
fixed_t yOff = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#include "../i_video.h" // I_UpdateNoBlit
|
||||
#include "../m_misc.h" // NUMLOGIP
|
||||
#include "../f_finale.h" // g_wipeskiprender
|
||||
#include "../s_sound.h"
|
||||
|
||||
menuitem_t PLAY_MP_JoinIP[] =
|
||||
{
|
||||
|
|
|
|||
108
src/r_defs.h
108
src/r_defs.h
|
|
@ -1045,6 +1045,114 @@ struct spritedef_t
|
|||
spriteframe_t *spriteframes;
|
||||
};
|
||||
|
||||
// Column and span drawing data bundles
|
||||
|
||||
typedef struct
|
||||
{
|
||||
lighttable_t* colormap;
|
||||
lighttable_t* fullbright;
|
||||
INT32 x;
|
||||
INT32 yl;
|
||||
INT32 yh;
|
||||
fixed_t iscale;
|
||||
fixed_t texturemid;
|
||||
UINT8 hires;
|
||||
UINT8 shadowcolor;
|
||||
|
||||
UINT8* source; // first pixel in a column
|
||||
UINT8* brightmap; // brightmap texture column, can be NULL
|
||||
UINT8* lightmap; // lighting only
|
||||
|
||||
// translucency stuff here
|
||||
UINT8* transmap;
|
||||
|
||||
// translation stuff here
|
||||
UINT8* translation;
|
||||
|
||||
struct r_lightlist_t* lightlist;
|
||||
|
||||
INT32 numlights;
|
||||
INT32 maxlights;
|
||||
|
||||
//Fix TUTIFRUTI
|
||||
INT32 texheight;
|
||||
|
||||
UINT8 r8_flatcolor;
|
||||
} drawcolumndata_t;
|
||||
|
||||
extern drawcolumndata_t g_dc;
|
||||
|
||||
typedef struct {
|
||||
float x, y, z;
|
||||
} floatv3_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
INT32 y;
|
||||
INT32 x1;
|
||||
INT32 x2;
|
||||
lighttable_t* colormap;
|
||||
lighttable_t* fullbright;
|
||||
lighttable_t* translation;
|
||||
lighttable_t* flatlighting;
|
||||
|
||||
fixed_t xfrac;
|
||||
fixed_t yfrac;
|
||||
fixed_t xstep;
|
||||
fixed_t ystep;
|
||||
INT32 waterofs;
|
||||
INT32 bgofs;
|
||||
|
||||
fixed_t xoffs;
|
||||
fixed_t yoffs;
|
||||
|
||||
UINT16 flatwidth;
|
||||
UINT16 flatheight;
|
||||
boolean powersoftwo;
|
||||
|
||||
visplane_t *currentplane;
|
||||
UINT8 *source;
|
||||
UINT8 *brightmap;
|
||||
UINT8 *transmap;
|
||||
|
||||
UINT8 flatcolor;
|
||||
|
||||
float zeroheight;
|
||||
|
||||
// Vectors for Software's tilted slope drawers
|
||||
floatv3_t sup;
|
||||
floatv3_t svp;
|
||||
floatv3_t szp;
|
||||
floatv3_t slope_origin;
|
||||
floatv3_t slope_u;
|
||||
floatv3_t slope_v;
|
||||
|
||||
// Variable flat sizes
|
||||
UINT32 nflatxshift;
|
||||
UINT32 nflatyshift;
|
||||
UINT32 nflatshiftup;
|
||||
UINT32 nflatmask;
|
||||
|
||||
fixed_t planeheight;
|
||||
lighttable_t **planezlight;
|
||||
|
||||
//
|
||||
// Water ripple effect
|
||||
// Needs the height of the plane, and the vertical position of the span.
|
||||
// Sets planeripple.xfrac and planeripple.yfrac, added to ds_xfrac and ds_yfrac, if the span is not tilted.
|
||||
//
|
||||
struct
|
||||
{
|
||||
INT32 offset;
|
||||
fixed_t xfrac, yfrac;
|
||||
boolean active;
|
||||
} planeripple;
|
||||
|
||||
UINT8 r8_flatcolor;
|
||||
} drawspandata_t;
|
||||
|
||||
extern drawspandata_t g_ds;
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
|
|
|||
61
src/r_draw.c
61
src/r_draw.c
|
|
@ -33,6 +33,30 @@
|
|||
#include "hardware/hw_main.h"
|
||||
#endif
|
||||
|
||||
|
||||
// --------------------------------------------
|
||||
// assembly or c drawer routines for 8bpp/16bpp
|
||||
// --------------------------------------------
|
||||
coldrawfunc_t *colfunc;
|
||||
coldrawfunc_t *colfuncs[COLDRAWFUNC_MAX];
|
||||
#ifdef USE_COL_SPAN_ASM
|
||||
coldrawfunc_t *colfuncs_asm[COLDRAWFUNC_MAX];
|
||||
#endif
|
||||
int colfunctype;
|
||||
|
||||
spandrawfunc_t *spanfunc;
|
||||
|
||||
spandrawfunc_t *spanfuncs[SPANDRAWFUNC_MAX];
|
||||
spandrawfunc_t *spanfuncs_npo2[SPANDRAWFUNC_MAX];
|
||||
#ifdef USE_COL_SPAN_ASM
|
||||
spandrawfunc_t *spanfuncs_asm[SPANDRAWFUNC_MAX];
|
||||
#endif
|
||||
spandrawfunc_t *spanfuncs_flat[SPANDRAWFUNC_MAX];
|
||||
|
||||
drawcolumndata_t g_dc;
|
||||
drawspandata_t g_ds;
|
||||
|
||||
|
||||
// ==========================================================================
|
||||
// COMMON DATA FOR 8bpp AND 16bpp
|
||||
// ==========================================================================
|
||||
|
|
@ -74,17 +98,6 @@ UINT8 r8_flatcolor;
|
|||
// COLUMN DRAWING CODE STUFF
|
||||
// =========================================================================
|
||||
|
||||
lighttable_t *dc_colormap;
|
||||
lighttable_t *dc_fullbright;
|
||||
INT32 dc_x = 0, dc_yl = 0, dc_yh = 0;
|
||||
|
||||
fixed_t dc_iscale, dc_texturemid;
|
||||
UINT8 dc_hires; // under MSVC boolean is a byte, while on other systems, it a bit,
|
||||
// soo lets make it a byte on all system for the ASM code
|
||||
UINT8 *dc_source;
|
||||
UINT8 *dc_brightmap;
|
||||
UINT8 *dc_lightmap;
|
||||
|
||||
// -----------------------
|
||||
// translucency stuff here
|
||||
// -----------------------
|
||||
|
|
@ -107,41 +120,17 @@ UINT8 *dc_transmap; // one of the translucency tables
|
|||
UINT8 *dc_translation;
|
||||
|
||||
struct r_lightlist_t *dc_lightlist = NULL;
|
||||
INT32 dc_numlights = 0, dc_maxlights, dc_texheight;
|
||||
INT32 dc_numlights = 0, dc_maxlights;
|
||||
|
||||
// =========================================================================
|
||||
// SPAN DRAWING CODE STUFF
|
||||
// =========================================================================
|
||||
|
||||
INT32 ds_y, ds_x1, ds_x2;
|
||||
lighttable_t *ds_colormap;
|
||||
lighttable_t *ds_fullbright;
|
||||
lighttable_t *ds_translation; // Lactozilla: Sprite splat drawer
|
||||
lighttable_t *ds_flatlighting;
|
||||
|
||||
fixed_t ds_xfrac, ds_yfrac, ds_xstep, ds_ystep;
|
||||
INT32 ds_waterofs, ds_bgofs;
|
||||
|
||||
UINT16 ds_flatwidth, ds_flatheight;
|
||||
boolean ds_powersoftwo;
|
||||
|
||||
UINT8 *ds_source; // points to the start of a flat
|
||||
UINT8 *ds_brightmap; // start of brightmap flat
|
||||
UINT8 *ds_transmap; // one of the translucency tables
|
||||
|
||||
UINT8 dc_shadowcolor;
|
||||
|
||||
// Vectors for Software's tilted slope drawers
|
||||
floatv3_t *ds_su, *ds_sv, *ds_sz;
|
||||
floatv3_t *ds_sup, *ds_svp, *ds_szp;
|
||||
float focallengthf[MAXSPLITSCREENPLAYERS];
|
||||
float zeroheight;
|
||||
|
||||
/** \brief Variable flat sizes
|
||||
*/
|
||||
|
||||
UINT32 nflatxshift, nflatyshift, nflatshiftup, nflatmask;
|
||||
|
||||
// =========================================================================
|
||||
// TRANSLATION COLORMAP CODE
|
||||
// =========================================================================
|
||||
|
|
|
|||
205
src/r_draw.h
205
src/r_draw.h
|
|
@ -36,67 +36,15 @@ extern UINT8 r8_flatcolor;
|
|||
// COLUMN DRAWING CODE STUFF
|
||||
// -------------------------
|
||||
|
||||
extern lighttable_t *dc_colormap;
|
||||
extern lighttable_t *dc_fullbright;
|
||||
extern INT32 dc_x, dc_yl, dc_yh;
|
||||
extern fixed_t dc_iscale, dc_texturemid;
|
||||
extern UINT8 dc_hires;
|
||||
|
||||
extern UINT8 *dc_source; // first pixel in a column
|
||||
extern UINT8 *dc_brightmap; // brightmap texture column, can be NULL
|
||||
extern UINT8 *dc_lightmap; // lighting only
|
||||
|
||||
// translucency stuff here
|
||||
extern UINT8 *dc_transmap;
|
||||
|
||||
// translation stuff here
|
||||
|
||||
extern UINT8 *dc_translation;
|
||||
|
||||
extern struct r_lightlist_t *dc_lightlist;
|
||||
extern INT32 dc_numlights, dc_maxlights;
|
||||
|
||||
//Fix TUTIFRUTI
|
||||
extern INT32 dc_texheight;
|
||||
|
||||
extern UINT8 dc_shadowcolor;
|
||||
|
||||
// -----------------------
|
||||
// SPAN DRAWING CODE STUFF
|
||||
// -----------------------
|
||||
|
||||
extern INT32 ds_y, ds_x1, ds_x2;
|
||||
extern lighttable_t *ds_colormap;
|
||||
extern lighttable_t *ds_fullbright;
|
||||
extern lighttable_t *ds_translation;
|
||||
extern lighttable_t *ds_flatlighting;
|
||||
|
||||
extern fixed_t ds_xfrac, ds_yfrac, ds_xstep, ds_ystep;
|
||||
extern INT32 ds_waterofs, ds_bgofs;
|
||||
|
||||
extern UINT16 ds_flatwidth, ds_flatheight;
|
||||
extern boolean ds_powersoftwo;
|
||||
|
||||
extern UINT8 *ds_source;
|
||||
extern UINT8 *ds_brightmap;
|
||||
extern UINT8 *ds_transmap;
|
||||
|
||||
struct floatv3_t {
|
||||
float x, y, z;
|
||||
};
|
||||
|
||||
// Vectors for Software's tilted slope drawers
|
||||
extern floatv3_t *ds_su, *ds_sv, *ds_sz;
|
||||
extern floatv3_t *ds_sup, *ds_svp, *ds_szp;
|
||||
extern float focallengthf[MAXSPLITSCREENPLAYERS];
|
||||
extern float zeroheight;
|
||||
|
||||
// Variable flat sizes
|
||||
extern UINT32 nflatxshift;
|
||||
extern UINT32 nflatyshift;
|
||||
extern UINT32 nflatshiftup;
|
||||
extern UINT32 nflatmask;
|
||||
|
||||
/// \brief Top border
|
||||
#define BRDR_T 0
|
||||
/// \brief Bottom border
|
||||
|
|
@ -116,6 +64,74 @@ extern UINT32 nflatmask;
|
|||
|
||||
extern lumpnum_t viewborderlump[8];
|
||||
|
||||
|
||||
|
||||
// ---------------------------------------------
|
||||
// color mode dependent drawer function pointers
|
||||
// ---------------------------------------------
|
||||
|
||||
#define USE_COL_SPAN_ASM 0
|
||||
|
||||
#define BASEDRAWFUNC 0
|
||||
|
||||
enum
|
||||
{
|
||||
COLDRAWFUNC_BASE = BASEDRAWFUNC,
|
||||
COLDRAWFUNC_FUZZY,
|
||||
COLDRAWFUNC_TRANS,
|
||||
COLDRAWFUNC_SHADE,
|
||||
COLDRAWFUNC_SHADOWED,
|
||||
COLDRAWFUNC_TRANSTRANS,
|
||||
COLDRAWFUNC_TWOSMULTIPATCH,
|
||||
COLDRAWFUNC_TWOSMULTIPATCHTRANS,
|
||||
COLDRAWFUNC_FOG,
|
||||
COLDRAWFUNC_DROPSHADOW,
|
||||
|
||||
COLDRAWFUNC_MAX
|
||||
};
|
||||
|
||||
typedef void (coldrawfunc_t)(drawcolumndata_t*);
|
||||
typedef void (spandrawfunc_t)(drawspandata_t*);
|
||||
|
||||
extern coldrawfunc_t *colfunc;
|
||||
extern coldrawfunc_t *colfuncs[COLDRAWFUNC_MAX];
|
||||
#ifdef USE_COL_SPAN_ASM
|
||||
extern coldrawfunc_t *colfuncs_asm[COLDRAWFUNC_MAX];
|
||||
#endif
|
||||
extern int colfunctype;
|
||||
|
||||
enum
|
||||
{
|
||||
SPANDRAWFUNC_BASE = BASEDRAWFUNC,
|
||||
SPANDRAWFUNC_TRANS,
|
||||
SPANDRAWFUNC_TILTED,
|
||||
SPANDRAWFUNC_TILTEDTRANS,
|
||||
|
||||
SPANDRAWFUNC_SPLAT,
|
||||
SPANDRAWFUNC_TRANSSPLAT,
|
||||
SPANDRAWFUNC_TILTEDSPLAT,
|
||||
|
||||
SPANDRAWFUNC_SPRITE,
|
||||
SPANDRAWFUNC_TRANSSPRITE,
|
||||
SPANDRAWFUNC_TILTEDSPRITE,
|
||||
SPANDRAWFUNC_TILTEDTRANSSPRITE,
|
||||
|
||||
SPANDRAWFUNC_WATER,
|
||||
SPANDRAWFUNC_TILTEDWATER,
|
||||
|
||||
SPANDRAWFUNC_FOG,
|
||||
|
||||
SPANDRAWFUNC_MAX
|
||||
};
|
||||
|
||||
extern spandrawfunc_t *spanfunc;
|
||||
extern spandrawfunc_t *spanfuncs[SPANDRAWFUNC_MAX];
|
||||
extern spandrawfunc_t *spanfuncs_npo2[SPANDRAWFUNC_MAX];
|
||||
#ifdef USE_COL_SPAN_ASM
|
||||
extern spandrawfunc_t *spanfuncs_asm[SPANDRAWFUNC_MAX];
|
||||
#endif
|
||||
extern spandrawfunc_t *spanfuncs_flat[SPANDRAWFUNC_MAX];
|
||||
|
||||
// ------------------------------------------------
|
||||
// r_draw.c COMMON ROUTINES FOR BOTH 8bpp and 16bpp
|
||||
// ------------------------------------------------
|
||||
|
|
@ -186,63 +202,62 @@ void R_DrawViewBorder(void);
|
|||
// 8bpp DRAWING CODE
|
||||
// -----------------
|
||||
|
||||
void R_DrawColumn_8(void);
|
||||
void R_DrawShadeColumn_8(void);
|
||||
void R_DrawTranslucentColumn_8(void);
|
||||
void R_DrawDropShadowColumn_8(void);
|
||||
void R_DrawTranslatedColumn_8(void);
|
||||
void R_DrawTranslatedTranslucentColumn_8(void);
|
||||
void R_Draw2sMultiPatchColumn_8(void);
|
||||
void R_Draw2sMultiPatchTranslucentColumn_8(void);
|
||||
void R_DrawFogColumn_8(void);
|
||||
void R_DrawColumnShadowed_8(void);
|
||||
void R_DrawColumn_8(drawcolumndata_t* dc);
|
||||
void R_DrawShadeColumn_8(drawcolumndata_t* dc);
|
||||
void R_DrawTranslucentColumn_8(drawcolumndata_t* dc);
|
||||
void R_DrawDropShadowColumn_8(drawcolumndata_t* dc);
|
||||
void R_DrawTranslatedColumn_8(drawcolumndata_t* dc);
|
||||
void R_DrawTranslatedTranslucentColumn_8(drawcolumndata_t* dc);
|
||||
void R_Draw2sMultiPatchColumn_8(drawcolumndata_t* dc);
|
||||
void R_Draw2sMultiPatchTranslucentColumn_8(drawcolumndata_t* dc);
|
||||
void R_DrawFogColumn_8(drawcolumndata_t* dc);
|
||||
void R_DrawColumnShadowed_8(drawcolumndata_t* dc);
|
||||
|
||||
#define PLANELIGHTFLOAT (BASEVIDWIDTH * BASEVIDWIDTH / vid.width / zeroheight / 21.0f * FIXED_TO_FLOAT(fovtan[viewssnum]))
|
||||
#define PLANELIGHTFLOAT (BASEVIDWIDTH * BASEVIDWIDTH / vid.width / ds->zeroheight / 21.0f * FIXED_TO_FLOAT(fovtan[viewssnum]))
|
||||
|
||||
void R_DrawSpan_8(void);
|
||||
void R_DrawTranslucentSpan_8(void);
|
||||
void R_DrawTiltedSpan_8(void);
|
||||
void R_DrawTiltedTranslucentSpan_8(void);
|
||||
void R_DrawSpan_8(drawspandata_t* ds);
|
||||
void R_DrawTranslucentSpan_8(drawspandata_t* ds);
|
||||
void R_DrawTiltedSpan_8(drawspandata_t* ds);
|
||||
void R_DrawTiltedTranslucentSpan_8(drawspandata_t* ds);
|
||||
|
||||
void R_DrawSplat_8(void);
|
||||
void R_DrawTranslucentSplat_8(void);
|
||||
void R_DrawTiltedSplat_8(void);
|
||||
void R_DrawSplat_8(drawspandata_t* ds);
|
||||
void R_DrawTranslucentSplat_8(drawspandata_t* ds);
|
||||
void R_DrawTiltedSplat_8(drawspandata_t* ds);
|
||||
|
||||
void R_DrawFloorSprite_8(void);
|
||||
void R_DrawTranslucentFloorSprite_8(void);
|
||||
void R_DrawTiltedFloorSprite_8(void);
|
||||
void R_DrawTiltedTranslucentFloorSprite_8(void);
|
||||
void R_DrawFloorSprite_8(drawspandata_t* ds);
|
||||
void R_DrawTranslucentFloorSprite_8(drawspandata_t* ds);
|
||||
void R_DrawTiltedFloorSprite_8(drawspandata_t* ds);
|
||||
void R_DrawTiltedTranslucentFloorSprite_8(drawspandata_t* ds);
|
||||
|
||||
void R_CalcTiltedLighting(fixed_t start, fixed_t end);
|
||||
extern INT32 tiltlighting[MAXVIDWIDTH];
|
||||
void R_CalcTiltedLighting(INT32 *lightbuffer, INT32 x1, INT32 x2, fixed_t start, fixed_t end);
|
||||
|
||||
void R_DrawTranslucentWaterSpan_8(void);
|
||||
void R_DrawTiltedTranslucentWaterSpan_8(void);
|
||||
void R_DrawTranslucentWaterSpan_8(drawspandata_t* ds);
|
||||
void R_DrawTiltedTranslucentWaterSpan_8(drawspandata_t* ds);
|
||||
|
||||
void R_DrawFogSpan_8(void);
|
||||
void R_DrawFogSpan_8(drawspandata_t* ds);
|
||||
|
||||
// Lactozilla: Non-powers-of-two
|
||||
void R_DrawSpan_NPO2_8(void);
|
||||
void R_DrawTranslucentSpan_NPO2_8(void);
|
||||
void R_DrawTiltedSpan_NPO2_8(void);
|
||||
void R_DrawTiltedTranslucentSpan_NPO2_8(void);
|
||||
void R_DrawSpan_NPO2_8(drawspandata_t* ds);
|
||||
void R_DrawTranslucentSpan_NPO2_8(drawspandata_t* ds);
|
||||
void R_DrawTiltedSpan_NPO2_8(drawspandata_t* ds);
|
||||
void R_DrawTiltedTranslucentSpan_NPO2_8(drawspandata_t* ds);
|
||||
|
||||
void R_DrawSplat_NPO2_8(void);
|
||||
void R_DrawTranslucentSplat_NPO2_8(void);
|
||||
void R_DrawTiltedSplat_NPO2_8(void);
|
||||
void R_DrawSplat_NPO2_8(drawspandata_t* ds);
|
||||
void R_DrawTranslucentSplat_NPO2_8(drawspandata_t* ds);
|
||||
void R_DrawTiltedSplat_NPO2_8(drawspandata_t* ds);
|
||||
|
||||
void R_DrawFloorSprite_NPO2_8(void);
|
||||
void R_DrawTranslucentFloorSprite_NPO2_8(void);
|
||||
void R_DrawTiltedFloorSprite_NPO2_8(void);
|
||||
void R_DrawTiltedTranslucentFloorSprite_NPO2_8(void);
|
||||
void R_DrawFloorSprite_NPO2_8(drawspandata_t* ds);
|
||||
void R_DrawTranslucentFloorSprite_NPO2_8(drawspandata_t* ds);
|
||||
void R_DrawTiltedFloorSprite_NPO2_8(drawspandata_t* ds);
|
||||
void R_DrawTiltedTranslucentFloorSprite_NPO2_8(drawspandata_t* ds);
|
||||
|
||||
void R_DrawTranslucentWaterSpan_NPO2_8(void);
|
||||
void R_DrawTiltedTranslucentWaterSpan_NPO2_8(void);
|
||||
void R_DrawTranslucentWaterSpan_NPO2_8(drawspandata_t* ds);
|
||||
void R_DrawTiltedTranslucentWaterSpan_NPO2_8(drawspandata_t* ds);
|
||||
|
||||
// Debugging - highlight surfaces in flat colors
|
||||
void R_DrawColumn_Flat_8(void);
|
||||
void R_DrawSpan_Flat_8(void);
|
||||
void R_DrawTiltedSpan_Flat_8(void);
|
||||
void R_DrawColumn_Flat_8(drawcolumndata_t* dc);
|
||||
void R_DrawSpan_Flat_8(drawspandata_t* ds);
|
||||
void R_DrawTiltedSpan_Flat_8(drawspandata_t* ds);
|
||||
|
||||
#ifdef USEASM
|
||||
void ASMCALL R_DrawColumn_8_ASM(void);
|
||||
|
|
|
|||
872
src/r_draw8.c
872
src/r_draw8.c
File diff suppressed because it is too large
Load diff
|
|
@ -12,19 +12,19 @@
|
|||
/// \brief 8bpp span/column drawer functions for debugging (draws in flat colors only)
|
||||
/// \note no includes because this is included as part of r_draw.c
|
||||
|
||||
void R_DrawColumn_Flat_8 (void)
|
||||
void R_DrawColumn_Flat_8 (drawcolumndata_t* dc)
|
||||
{
|
||||
INT32 count;
|
||||
UINT8 color = dc_lightmap[r8_flatcolor];
|
||||
UINT8 color = dc->lightmap[dc->r8_flatcolor];
|
||||
register UINT8 *dest;
|
||||
|
||||
count = dc_yh - dc_yl;
|
||||
count = dc->yh - dc->yl;
|
||||
|
||||
if (count < 0) // Zero length, column does not exceed a pixel.
|
||||
return;
|
||||
|
||||
#ifdef RANGECHECK
|
||||
if ((unsigned)dc_x >= (unsigned)vid.width || dc_yl < 0 || dc_yh >= vid.height)
|
||||
if ((unsigned)dc->x >= (unsigned)vid.width || dc->yl < 0 || dc->yh >= vid.height)
|
||||
return;
|
||||
#endif
|
||||
|
||||
|
|
@ -33,7 +33,7 @@ void R_DrawColumn_Flat_8 (void)
|
|||
// Use columnofs LUT for subwindows?
|
||||
|
||||
//dest = ylookup[dc_yl] + columnofs[dc_x];
|
||||
dest = &topleft[dc_yl*vid.width + dc_x];
|
||||
dest = &topleft[dc->yl*vid.width + dc->x];
|
||||
|
||||
count++;
|
||||
|
||||
|
|
@ -44,36 +44,37 @@ void R_DrawColumn_Flat_8 (void)
|
|||
} while (--count);
|
||||
}
|
||||
|
||||
void R_DrawSpan_Flat_8 (void)
|
||||
void R_DrawSpan_Flat_8 (drawspandata_t* ds)
|
||||
{
|
||||
UINT8 *dest = ylookup[ds_y] + columnofs[ds_x1];
|
||||
UINT8 *dest = ylookup[ds->y] + columnofs[ds->x1];
|
||||
|
||||
memset(dest, ds_colormap[r8_flatcolor], (ds_x2 - ds_x1) + 1);
|
||||
memset(dest, ds->colormap[ds->r8_flatcolor], (ds->x2 - ds->x1) + 1);
|
||||
}
|
||||
|
||||
void R_DrawTiltedSpan_Flat_8 (void)
|
||||
void R_DrawTiltedSpan_Flat_8 (drawspandata_t* ds)
|
||||
{
|
||||
// x1, x2 = ds_x1, ds_x2
|
||||
int width = ds_x2 - ds_x1;
|
||||
double iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx);
|
||||
int width = ds->x2 - ds->x1;
|
||||
double iz = ds->szp.z + ds->szp.y*(centery-ds->y) + ds->szp.x*(ds->x1-centerx);
|
||||
INT32 tiltlighting[MAXVIDWIDTH];
|
||||
|
||||
UINT8 *dest = ylookup[ds_y];
|
||||
UINT8 *dest = ylookup[ds->y];
|
||||
|
||||
// Lighting is simple. It's just linear interpolation from start to end
|
||||
{
|
||||
float planelightfloat = PLANELIGHTFLOAT;
|
||||
float lightstart, lightend;
|
||||
|
||||
lightend = (iz + ds_szp->x*width) * planelightfloat;
|
||||
lightend = (iz + ds->szp.x*width) * planelightfloat;
|
||||
lightstart = iz * planelightfloat;
|
||||
|
||||
R_CalcTiltedLighting(FLOAT_TO_FIXED(lightstart), FLOAT_TO_FIXED(lightend));
|
||||
R_CalcTiltedLighting(tiltlighting, ds->x1, ds->x2, FLOAT_TO_FIXED(lightstart), FLOAT_TO_FIXED(lightend));
|
||||
//CONS_Printf("tilted lighting %f to %f (foc %f)\n", lightstart, lightend, focallengthf);
|
||||
}
|
||||
|
||||
while (ds_x1 <= ds_x2)
|
||||
while (ds->x1 <= ds->x2)
|
||||
{
|
||||
dest[ds_x1] = planezlight[tiltlighting[ds_x1]][r8_flatcolor];
|
||||
ds_x1++;
|
||||
dest[ds->x1] = ds->planezlight[tiltlighting[ds->x1]][ds->r8_flatcolor];
|
||||
ds->x1++;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -408,8 +408,8 @@ void R_CreateInterpolator_Polyobj(thinker_t *thinker, polyobj_t *polyobj)
|
|||
interp->polyobj.polyobj = polyobj;
|
||||
interp->polyobj.vertices_size = polyobj->numVertices;
|
||||
|
||||
interp->polyobj.oldvertices = Z_CallocAlign(sizeof(fixed_t) * 2 * polyobj->numVertices, PU_LEVEL, NULL, 32);
|
||||
interp->polyobj.bakvertices = Z_CallocAlign(sizeof(fixed_t) * 2 * polyobj->numVertices, PU_LEVEL, NULL, 32);
|
||||
interp->polyobj.oldvertices = Z_Calloc(sizeof(fixed_t) * 2 * polyobj->numVertices, PU_LEVEL, NULL);
|
||||
interp->polyobj.bakvertices = Z_Calloc(sizeof(fixed_t) * 2 * polyobj->numVertices, PU_LEVEL, NULL);
|
||||
for (size_t i = 0; i < polyobj->numVertices; i++)
|
||||
{
|
||||
interp->polyobj.oldvertices[i * 2 ] = interp->polyobj.bakvertices[i * 2 ] = polyobj->vertices[i]->x;
|
||||
|
|
@ -579,7 +579,7 @@ void R_RestoreLevelInterpolators(void)
|
|||
for (i = 0; i < levelinterpolators_len; i++)
|
||||
{
|
||||
levelinterpolator_t *interp = levelinterpolators[i];
|
||||
|
||||
|
||||
switch (interp->type)
|
||||
{
|
||||
case LVLINTERP_SectorPlane:
|
||||
|
|
@ -634,7 +634,7 @@ void R_DestroyLevelInterpolators(thinker_t *thinker)
|
|||
for (i = 0; i < levelinterpolators_len; i++)
|
||||
{
|
||||
levelinterpolator_t *interp = levelinterpolators[i];
|
||||
|
||||
|
||||
if (interp->thinker == thinker)
|
||||
{
|
||||
// Swap the tail of the level interpolators to this spot
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@
|
|||
/// utility functions (BSP, geometry, trigonometry).
|
||||
/// See tables.c, too.
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "doomdef.h"
|
||||
#include "g_game.h"
|
||||
#include "g_input.h"
|
||||
|
|
@ -37,6 +39,7 @@
|
|||
#include "i_system.h" // I_GetPreciseTime
|
||||
#include "doomstat.h" // MAXSPLITSCREENPLAYERS
|
||||
#include "r_fps.h" // Frame interpolation/uncapped
|
||||
#include "core/thread_pool.h"
|
||||
|
||||
#ifdef HWRENDER
|
||||
#include "hardware/hw_main.h"
|
||||
|
|
@ -180,31 +183,31 @@ void SplitScreen_OnChange(void)
|
|||
}
|
||||
}
|
||||
}
|
||||
void Fov_OnChange(void);
|
||||
extern "C" void Fov_OnChange(void);
|
||||
void Fov_OnChange(void)
|
||||
{
|
||||
R_SetViewSize();
|
||||
}
|
||||
|
||||
void ChaseCam_OnChange(void);
|
||||
extern "C" void ChaseCam_OnChange(void);
|
||||
void ChaseCam_OnChange(void)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
void ChaseCam2_OnChange(void);
|
||||
extern "C" void ChaseCam2_OnChange(void);
|
||||
void ChaseCam2_OnChange(void)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
void ChaseCam3_OnChange(void);
|
||||
extern "C" void ChaseCam3_OnChange(void);
|
||||
void ChaseCam3_OnChange(void)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
void ChaseCam4_OnChange(void);
|
||||
extern "C" void ChaseCam4_OnChange(void);
|
||||
void ChaseCam4_OnChange(void)
|
||||
{
|
||||
;
|
||||
|
|
@ -218,7 +221,7 @@ void ChaseCam4_OnChange(void)
|
|||
//
|
||||
// killough 5/2/98: reformatted
|
||||
//
|
||||
INT32 R_PointOnSide(fixed_t x, fixed_t y, node_t *restrict node)
|
||||
INT32 R_PointOnSide(fixed_t x, fixed_t y, node_t *node)
|
||||
{
|
||||
if (!node->dx)
|
||||
return x <= node->x ? node->dy > 0 : node->dy < 0;
|
||||
|
|
@ -457,10 +460,10 @@ void R_GetRenderBlockMapDimensions(fixed_t drawdist, INT32 *xl, INT32 *xh, INT32
|
|||
const fixed_t vyright = viewy + FixedMul(drawdist, FSIN(right));
|
||||
|
||||
// Try to narrow the search to within only the field of view
|
||||
*xl = (unsigned)(min(viewx, min(vxleft, vxright)) - bmaporgx)>>MAPBLOCKSHIFT;
|
||||
*xh = (unsigned)(max(viewx, max(vxleft, vxright)) - bmaporgx)>>MAPBLOCKSHIFT;
|
||||
*yl = (unsigned)(min(viewy, min(vyleft, vyright)) - bmaporgy)>>MAPBLOCKSHIFT;
|
||||
*yh = (unsigned)(max(viewy, max(vyleft, vyright)) - bmaporgy)>>MAPBLOCKSHIFT;
|
||||
*xl = (unsigned)(std::min(viewx, std::min(vxleft, vxright)) - bmaporgx)>>MAPBLOCKSHIFT;
|
||||
*xh = (unsigned)(std::max(viewx, std::max(vxleft, vxright)) - bmaporgx)>>MAPBLOCKSHIFT;
|
||||
*yl = (unsigned)(std::min(viewy, std::min(vyleft, vyright)) - bmaporgy)>>MAPBLOCKSHIFT;
|
||||
*yh = (unsigned)(std::max(viewy, std::max(vyleft, vyright)) - bmaporgy)>>MAPBLOCKSHIFT;
|
||||
|
||||
if (*xh >= bmapwidth)
|
||||
*xh = bmapwidth - 1;
|
||||
|
|
@ -685,7 +688,7 @@ void R_CheckViewMorph(int s)
|
|||
{
|
||||
if (v->scrmap)
|
||||
free(v->scrmap);
|
||||
v->scrmap = malloc(width * height * sizeof(INT32));
|
||||
v->scrmap = static_cast<INT32*>(malloc(width * height * sizeof(INT32)));
|
||||
v->scrmapsize = width * height;
|
||||
}
|
||||
|
||||
|
|
@ -714,7 +717,7 @@ void R_CheckViewMorph(int s)
|
|||
}
|
||||
#endif
|
||||
|
||||
temp = max(x1, y1)*FRACUNIT;
|
||||
temp = std::max(x1, y1)*FRACUNIT;
|
||||
if (temp < FRACUNIT)
|
||||
temp = FRACUNIT;
|
||||
else
|
||||
|
|
@ -770,10 +773,10 @@ void R_CheckViewMorph(int s)
|
|||
xb = width-1-xa;
|
||||
yb = height-1-ya;
|
||||
|
||||
v->ceilingclip[xa] = min(v->ceilingclip[xa], ya);
|
||||
v->floorclip[xa] = max(v->floorclip[xa], ya);
|
||||
v->ceilingclip[xb] = min(v->ceilingclip[xb], yb);
|
||||
v->floorclip[xb] = max(v->floorclip[xb], yb);
|
||||
v->ceilingclip[xa] = std::min(v->ceilingclip[xa], ya);
|
||||
v->floorclip[xa] = std::max(v->floorclip[xa], ya);
|
||||
v->ceilingclip[xb] = std::min(v->ceilingclip[xb], yb);
|
||||
v->floorclip[xb] = std::max(v->floorclip[xb], yb);
|
||||
x2 += rollcos;
|
||||
y2 += rollsin;
|
||||
}
|
||||
|
|
@ -787,10 +790,10 @@ void R_CheckViewMorph(int s)
|
|||
xb = width-1-xa;
|
||||
yb = height-1-ya;
|
||||
|
||||
v->ceilingclip[xa] = min(v->ceilingclip[xa], ya);
|
||||
v->floorclip[xa] = max(v->floorclip[xa], ya);
|
||||
v->ceilingclip[xb] = min(v->ceilingclip[xb], yb);
|
||||
v->floorclip[xb] = max(v->floorclip[xb], yb);
|
||||
v->ceilingclip[xa] = std::min(v->ceilingclip[xa], ya);
|
||||
v->floorclip[xa] = std::max(v->floorclip[xa], ya);
|
||||
v->ceilingclip[xb] = std::min(v->ceilingclip[xb], yb);
|
||||
v->floorclip[xb] = std::max(v->floorclip[xb], yb);
|
||||
x2 -= rollsin;
|
||||
y2 += rollcos;
|
||||
}
|
||||
|
|
@ -1035,7 +1038,6 @@ void R_ExecuteSetViewSize(void)
|
|||
Z_Free(ds_sz);
|
||||
|
||||
ds_su = ds_sv = ds_sz = NULL;
|
||||
ds_sup = ds_svp = ds_szp = NULL;
|
||||
}
|
||||
|
||||
memset(scalelight, 0xFF, sizeof(scalelight));
|
||||
|
|
@ -1212,7 +1214,7 @@ void R_SetupFrame(int s)
|
|||
camera_t *thiscam = &camera[s];
|
||||
boolean chasecam = (cv_chasecam[s].value != 0);
|
||||
|
||||
R_SetViewContext(VIEWCONTEXT_PLAYER1 + s);
|
||||
R_SetViewContext(static_cast<viewcontext_e>(VIEWCONTEXT_PLAYER1 + s));
|
||||
|
||||
if (player->spectator)
|
||||
{
|
||||
|
|
@ -1275,7 +1277,7 @@ void R_SkyboxFrame(int s)
|
|||
player_t *player = &players[displayplayers[s]];
|
||||
camera_t *thiscam = &camera[s];
|
||||
|
||||
R_SetViewContext(VIEWCONTEXT_SKY1 + s);
|
||||
R_SetViewContext(static_cast<viewcontext_e>(VIEWCONTEXT_SKY1 + s));
|
||||
|
||||
// cut-away view stuff
|
||||
newview->sky = true;
|
||||
|
|
@ -1474,7 +1476,7 @@ void R_RenderPlayerView(void)
|
|||
{
|
||||
player_t * player = &players[displayplayers[viewssnum]];
|
||||
INT32 nummasks = 1;
|
||||
maskcount_t* masks = malloc(sizeof(maskcount_t));
|
||||
maskcount_t* masks = static_cast<maskcount_t*>(malloc(sizeof(maskcount_t)));
|
||||
|
||||
R_SetupFrame(viewssnum);
|
||||
framecount++;
|
||||
|
|
@ -1511,7 +1513,11 @@ void R_RenderPlayerView(void)
|
|||
#endif
|
||||
ps_numbspcalls = ps_numpolyobjects = ps_numdrawnodes = 0;
|
||||
ps_bsptime = I_GetPreciseTime();
|
||||
|
||||
srb2::ThreadPool::Sema tp_sema;
|
||||
srb2::g_main_threadpool->begin_sema();
|
||||
R_RenderViewpoint(&masks[nummasks - 1]);
|
||||
|
||||
ps_bsptime = I_GetPreciseTime() - ps_bsptime;
|
||||
#ifdef TIMING
|
||||
RDMSR(0x10, &mycount);
|
||||
|
|
@ -1534,6 +1540,11 @@ void R_RenderPlayerView(void)
|
|||
ps_sw_portaltime = I_GetPreciseTime();
|
||||
if (portal_base && !cv_debugrender_portal.value)
|
||||
{
|
||||
// tp_sema = srb2::g_main_threadpool->end_sema();
|
||||
// srb2::g_main_threadpool->notify_sema(tp_sema);
|
||||
// srb2::g_main_threadpool->wait_sema(tp_sema);
|
||||
// srb2::g_main_threadpool->begin_sema();
|
||||
|
||||
portal_t *portal;
|
||||
|
||||
for(portal = portal_base; portal; portal = portal_base)
|
||||
|
|
@ -1556,12 +1567,13 @@ void R_RenderPlayerView(void)
|
|||
|
||||
validcount++;
|
||||
|
||||
masks = realloc(masks, (++nummasks)*sizeof(maskcount_t));
|
||||
masks = static_cast<maskcount_t*>(realloc(masks, (++nummasks)*sizeof(maskcount_t)));
|
||||
|
||||
portalskipprecipmobjs = portal->isskybox;
|
||||
|
||||
// Render the BSP from the new viewpoint, and clip
|
||||
// any sprites with the new clipsegs and window.
|
||||
|
||||
R_RenderViewpoint(&masks[nummasks - 1]);
|
||||
|
||||
portalskipprecipmobjs = false;
|
||||
|
|
@ -1570,11 +1582,19 @@ void R_RenderPlayerView(void)
|
|||
|
||||
Portal_Remove(portal);
|
||||
}
|
||||
|
||||
// tp_sema = srb2::g_main_threadpool->end_sema();
|
||||
// srb2::g_main_threadpool->notify_sema(tp_sema);
|
||||
// srb2::g_main_threadpool->wait_sema(tp_sema);
|
||||
// srb2::g_main_threadpool->begin_sema();
|
||||
}
|
||||
ps_sw_portaltime = I_GetPreciseTime() - ps_sw_portaltime;
|
||||
|
||||
ps_sw_planetime = I_GetPreciseTime();
|
||||
R_DrawPlanes();
|
||||
tp_sema = srb2::g_main_threadpool->end_sema();
|
||||
srb2::g_main_threadpool->notify_sema(tp_sema);
|
||||
srb2::g_main_threadpool->wait_sema(tp_sema);
|
||||
ps_sw_planetime = I_GetPreciseTime() - ps_sw_planetime;
|
||||
|
||||
// draw mid texture and sprite
|
||||
|
|
@ -1596,8 +1616,8 @@ void R_RenderPlayerView(void)
|
|||
|
||||
for (i = 0; i < width; ++i)
|
||||
{
|
||||
INT32 yl = max(portal->ceilingclip[i] + 1, 0);
|
||||
INT32 yh = min(portal->floorclip[i], viewheight);
|
||||
INT32 yl = std::max(portal->ceilingclip[i] + 1, 0);
|
||||
INT32 yh = std::min(static_cast<INT32>(portal->floorclip[i]), viewheight);
|
||||
|
||||
for (; yl < yh; ++yl)
|
||||
{
|
||||
507
src/r_plane.cpp
507
src/r_plane.cpp
|
|
@ -29,6 +29,7 @@
|
|||
#include "r_splats.h" // faB(21jan):testing
|
||||
#include "r_sky.h"
|
||||
#include "r_portal.h"
|
||||
#include "core/thread_pool.h"
|
||||
|
||||
#include "v_video.h"
|
||||
#include "w_wad.h"
|
||||
|
|
@ -52,7 +53,6 @@ static visplane_t **freehead = &freetail;
|
|||
|
||||
visplane_t *floorplane;
|
||||
visplane_t *ceilingplane;
|
||||
static visplane_t *currentplane;
|
||||
|
||||
visffloor_t ffloor[MAXFFLOORS];
|
||||
INT32 numffloors;
|
||||
|
|
@ -82,8 +82,6 @@ static INT32 spanstart[MAXVIDHEIGHT];
|
|||
//
|
||||
// texture mapping
|
||||
//
|
||||
lighttable_t **planezlight;
|
||||
static fixed_t planeheight;
|
||||
|
||||
//added : 10-02-98: yslopetab is what yslope used to be,
|
||||
// yslope points somewhere into yslopetab,
|
||||
|
|
@ -95,14 +93,6 @@ static fixed_t planeheight;
|
|||
fixed_t yslopetab[MAXSPLITSCREENPLAYERS][MAXVIDHEIGHT*16];
|
||||
fixed_t *yslope;
|
||||
|
||||
fixed_t cachedheight[MAXVIDHEIGHT];
|
||||
fixed_t cacheddistance[MAXVIDHEIGHT];
|
||||
fixed_t cachedxstep[MAXVIDHEIGHT];
|
||||
fixed_t cachedystep[MAXVIDHEIGHT];
|
||||
|
||||
static fixed_t xoffs, yoffs;
|
||||
static floatv3_t ds_slope_origin, ds_slope_u, ds_slope_v;
|
||||
|
||||
//
|
||||
// R_InitPlanes
|
||||
// Only at game startup.
|
||||
|
|
@ -112,42 +102,31 @@ void R_InitPlanes(void)
|
|||
// FIXME: unused
|
||||
}
|
||||
|
||||
//
|
||||
// Water ripple effect
|
||||
// Needs the height of the plane, and the vertical position of the span.
|
||||
// Sets planeripple.xfrac and planeripple.yfrac, added to ds_xfrac and ds_yfrac, if the span is not tilted.
|
||||
//
|
||||
|
||||
static struct
|
||||
{
|
||||
INT32 offset;
|
||||
fixed_t xfrac, yfrac;
|
||||
boolean active;
|
||||
} planeripple;
|
||||
|
||||
// ripples da water texture
|
||||
static fixed_t R_CalculateRippleOffset(INT32 y)
|
||||
static fixed_t R_CalculateRippleOffset(drawspandata_t* ds, INT32 y)
|
||||
{
|
||||
fixed_t distance = FixedMul(planeheight, yslope[y]);
|
||||
const INT32 yay = (planeripple.offset + (distance>>9)) & 8191;
|
||||
fixed_t distance = FixedMul(ds->planeheight, yslope[y]);
|
||||
const INT32 yay = (ds->planeripple.offset + (distance>>9)) & 8191;
|
||||
return FixedDiv(FINESINE(yay), (1<<12) + (distance>>11));
|
||||
}
|
||||
|
||||
static void R_CalculatePlaneRipple(angle_t angle)
|
||||
static void R_CalculatePlaneRipple(drawspandata_t* ds, angle_t angle)
|
||||
{
|
||||
angle >>= ANGLETOFINESHIFT;
|
||||
angle = (angle + 2048) & 8191; // 90 degrees
|
||||
planeripple.xfrac = FixedMul(FINECOSINE(angle), ds_bgofs);
|
||||
planeripple.yfrac = FixedMul(FINESINE(angle), ds_bgofs);
|
||||
ds->planeripple.xfrac = FixedMul(FINECOSINE(angle), ds->bgofs);
|
||||
ds->planeripple.yfrac = FixedMul(FINESINE(angle), ds->bgofs);
|
||||
}
|
||||
|
||||
static void R_UpdatePlaneRipple(void)
|
||||
static void R_UpdatePlaneRipple(drawspandata_t* ds)
|
||||
{
|
||||
ds_waterofs = (leveltime & 1)*16384;
|
||||
planeripple.offset = (leveltime * 140);
|
||||
ds->waterofs = (leveltime & 1)*16384;
|
||||
ds->planeripple.offset = (leveltime * 140);
|
||||
}
|
||||
|
||||
static void R_MapPlane(INT32 y, INT32 x1, INT32 x2)
|
||||
static void R_SetSlopePlaneVectors(drawspandata_t* ds, visplane_t *pl, INT32 y, fixed_t xoff, fixed_t yoff);
|
||||
|
||||
static void R_MapPlane(drawspandata_t *ds, spandrawfunc_t *spanfunc, INT32 y, INT32 x1, INT32 x2, boolean allow_parallel)
|
||||
{
|
||||
ZoneScoped;
|
||||
angle_t angle, planecos, planesin;
|
||||
|
|
@ -162,62 +141,48 @@ static void R_MapPlane(INT32 y, INT32 x1, INT32 x2)
|
|||
if (x1 >= vid.width)
|
||||
x1 = vid.width - 1;
|
||||
|
||||
angle = (currentplane->viewangle + currentplane->plangle)>>ANGLETOFINESHIFT;
|
||||
angle = (ds->currentplane->viewangle + ds->currentplane->plangle)>>ANGLETOFINESHIFT;
|
||||
planecos = FINECOSINE(angle);
|
||||
planesin = FINESINE(angle);
|
||||
|
||||
if (planeheight != cachedheight[y])
|
||||
distance = FixedMul(ds->planeheight, yslope[y]);
|
||||
span = abs(centery - y);
|
||||
if (span) // Don't divide by zero
|
||||
{
|
||||
cachedheight[y] = planeheight;
|
||||
cacheddistance[y] = distance = FixedMul(planeheight, yslope[y]);
|
||||
span = abs(centery - y);
|
||||
|
||||
if (span) // Don't divide by zero
|
||||
{
|
||||
ds_xstep = FixedMul(planesin, planeheight) / span;
|
||||
ds_ystep = FixedMul(planecos, planeheight) / span;
|
||||
}
|
||||
else
|
||||
ds_xstep = ds_ystep = FRACUNIT;
|
||||
|
||||
cachedxstep[y] = ds_xstep;
|
||||
cachedystep[y] = ds_ystep;
|
||||
ds->xstep = FixedMul(planesin, ds->planeheight) / span;
|
||||
ds->ystep = FixedMul(planecos, ds->planeheight) / span;
|
||||
}
|
||||
else
|
||||
{
|
||||
distance = cacheddistance[y];
|
||||
ds_xstep = cachedxstep[y];
|
||||
ds_ystep = cachedystep[y];
|
||||
}
|
||||
ds->xstep = ds->ystep = FRACUNIT;
|
||||
|
||||
// [RH] Instead of using the xtoviewangle array, I calculated the fractional values
|
||||
// at the middle of the screen, then used the calculated ds_xstep and ds_ystep
|
||||
// to step from those to the proper texture coordinate to start drawing at.
|
||||
// That way, the texture coordinate is always calculated by its position
|
||||
// on the screen and not by its position relative to the edge of the visplane.
|
||||
ds_xfrac = xoffs + FixedMul(planecos, distance) + (x1 - centerx) * ds_xstep;
|
||||
ds_yfrac = yoffs - FixedMul(planesin, distance) + (x1 - centerx) * ds_ystep;
|
||||
ds->xfrac = ds->xoffs + FixedMul(planecos, distance) + (x1 - centerx) * ds->xstep;
|
||||
ds->yfrac = ds->yoffs - FixedMul(planesin, distance) + (x1 - centerx) * ds->ystep;
|
||||
|
||||
// Water ripple effect
|
||||
if (planeripple.active)
|
||||
if (ds->planeripple.active)
|
||||
{
|
||||
ds_bgofs = R_CalculateRippleOffset(y);
|
||||
ds->bgofs = R_CalculateRippleOffset(ds, y);
|
||||
|
||||
R_CalculatePlaneRipple(currentplane->viewangle + currentplane->plangle);
|
||||
R_CalculatePlaneRipple(ds, ds->currentplane->viewangle + ds->currentplane->plangle);
|
||||
|
||||
ds_xfrac += planeripple.xfrac;
|
||||
ds_yfrac += planeripple.yfrac;
|
||||
ds_bgofs >>= FRACBITS;
|
||||
ds->xfrac += ds->planeripple.xfrac;
|
||||
ds->yfrac += ds->planeripple.yfrac;
|
||||
ds->bgofs >>= FRACBITS;
|
||||
|
||||
if ((y + ds_bgofs) >= viewheight)
|
||||
ds_bgofs = viewheight-y-1;
|
||||
if ((y + ds_bgofs) < 0)
|
||||
ds_bgofs = -y;
|
||||
if ((y + ds->bgofs) >= viewheight)
|
||||
ds->bgofs = viewheight-y-1;
|
||||
if ((y + ds->bgofs) < 0)
|
||||
ds->bgofs = -y;
|
||||
}
|
||||
|
||||
if (ds_flatlighting)
|
||||
if (ds->flatlighting)
|
||||
{
|
||||
ds_colormap = ds_flatlighting;
|
||||
ds->colormap = ds->flatlighting;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -225,30 +190,30 @@ static void R_MapPlane(INT32 y, INT32 x1, INT32 x2)
|
|||
if (pindex >= MAXLIGHTZ)
|
||||
pindex = MAXLIGHTZ - 1;
|
||||
|
||||
ds_colormap = planezlight[pindex];
|
||||
ds->colormap = ds->planezlight[pindex];
|
||||
|
||||
if (!debugrender_highlight)
|
||||
{
|
||||
if (currentplane->extra_colormap)
|
||||
ds_colormap = currentplane->extra_colormap->colormap + (ds_colormap - colormaps);
|
||||
if (ds->currentplane->extra_colormap)
|
||||
ds->colormap = ds->currentplane->extra_colormap->colormap + (ds->colormap - colormaps);
|
||||
|
||||
ds_fullbright = colormaps;
|
||||
if (encoremap && !currentplane->noencore)
|
||||
ds->fullbright = colormaps;
|
||||
if (encoremap && !ds->currentplane->noencore)
|
||||
{
|
||||
ds_colormap += COLORMAP_REMAPOFFSET;
|
||||
ds_fullbright += COLORMAP_REMAPOFFSET;
|
||||
ds->colormap += COLORMAP_REMAPOFFSET;
|
||||
ds->fullbright += COLORMAP_REMAPOFFSET;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ds_y = y;
|
||||
ds_x1 = x1;
|
||||
ds_x2 = x2;
|
||||
ds->y = y;
|
||||
ds->x1 = x1;
|
||||
ds->x2 = x2;
|
||||
|
||||
spanfunc();
|
||||
spanfunc(ds);
|
||||
}
|
||||
|
||||
static void R_MapTiltedPlane(INT32 y, INT32 x1, INT32 x2)
|
||||
static void R_MapTiltedPlane(drawspandata_t *ds, void(*spanfunc)(drawspandata_t*), INT32 y, INT32 x1, INT32 x2, boolean allow_parallel)
|
||||
{
|
||||
ZoneScoped;
|
||||
#ifdef RANGECHECK
|
||||
|
|
@ -260,37 +225,40 @@ static void R_MapTiltedPlane(INT32 y, INT32 x1, INT32 x2)
|
|||
x1 = vid.width - 1;
|
||||
|
||||
// Water ripple effect
|
||||
if (planeripple.active)
|
||||
if (ds->planeripple.active)
|
||||
{
|
||||
ds_bgofs = R_CalculateRippleOffset(y);
|
||||
ds->bgofs = R_CalculateRippleOffset(ds, y);
|
||||
|
||||
R_SetTiltedSpan(std::clamp(y, 0, viewheight));
|
||||
R_SetTiltedSpan(ds, std::clamp(y, 0, viewheight));
|
||||
|
||||
ds_bgofs >>= FRACBITS;
|
||||
R_CalculatePlaneRipple(ds, ds->currentplane->viewangle + ds->currentplane->plangle);
|
||||
R_SetSlopePlaneVectors(ds, ds->currentplane, y, (ds->xoffs + ds->planeripple.xfrac), (ds->yoffs + ds->planeripple.yfrac));
|
||||
|
||||
if ((y + ds_bgofs) >= viewheight)
|
||||
ds_bgofs = viewheight-y-1;
|
||||
if ((y + ds_bgofs) < 0)
|
||||
ds_bgofs = -y;
|
||||
ds->bgofs >>= FRACBITS;
|
||||
|
||||
if ((y + ds->bgofs) >= viewheight)
|
||||
ds->bgofs = viewheight-y-1;
|
||||
if ((y + ds->bgofs) < 0)
|
||||
ds->bgofs = -y;
|
||||
}
|
||||
|
||||
if (currentplane->extra_colormap)
|
||||
ds_colormap = currentplane->extra_colormap->colormap;
|
||||
if (ds->currentplane->extra_colormap)
|
||||
ds->colormap = ds->currentplane->extra_colormap->colormap;
|
||||
else
|
||||
ds_colormap = colormaps;
|
||||
ds->colormap = colormaps;
|
||||
|
||||
ds_fullbright = colormaps;
|
||||
if (encoremap && !currentplane->noencore)
|
||||
ds->fullbright = colormaps;
|
||||
if (encoremap && !ds->currentplane->noencore)
|
||||
{
|
||||
ds_colormap += COLORMAP_REMAPOFFSET;
|
||||
ds_fullbright += COLORMAP_REMAPOFFSET;
|
||||
ds->colormap += COLORMAP_REMAPOFFSET;
|
||||
ds->fullbright += COLORMAP_REMAPOFFSET;
|
||||
}
|
||||
|
||||
ds_y = y;
|
||||
ds_x1 = x1;
|
||||
ds_x2 = x2;
|
||||
ds->y = y;
|
||||
ds->x1 = x1;
|
||||
ds->x2 = x2;
|
||||
|
||||
spanfunc();
|
||||
spanfunc(ds);
|
||||
}
|
||||
|
||||
void R_ClearFFloorClips (void)
|
||||
|
|
@ -339,9 +307,6 @@ void R_ClearPlanes(void)
|
|||
}
|
||||
|
||||
lastopening = openings;
|
||||
|
||||
// texture calculation
|
||||
memset(cachedheight, 0, sizeof (cachedheight));
|
||||
}
|
||||
|
||||
static visplane_t *new_visplane(unsigned hash)
|
||||
|
|
@ -603,8 +568,9 @@ void R_ExpandPlane(visplane_t *pl, INT32 start, INT32 stop)
|
|||
if (pl->maxx < stop) pl->maxx = stop;
|
||||
}
|
||||
|
||||
static void R_MakeSpans(void (*mapfunc)(INT32, INT32, INT32), INT32 x, INT32 t1, INT32 b1, INT32 t2, INT32 b2)
|
||||
static void R_MakeSpans(void (*mapfunc)(drawspandata_t* ds, void(*spanfunc)(drawspandata_t*), INT32, INT32, INT32, boolean), spandrawfunc_t* spanfunc, drawspandata_t* ds, INT32 x, INT32 t1, INT32 b1, INT32 t2, INT32 b2, boolean allow_parallel)
|
||||
{
|
||||
ZoneScoped;
|
||||
// Alam: from r_splats's R_RasterizeFloorSplat
|
||||
if (t1 >= vid.height) t1 = vid.height-1;
|
||||
if (b1 >= vid.height) b1 = vid.height-1;
|
||||
|
|
@ -612,15 +578,69 @@ static void R_MakeSpans(void (*mapfunc)(INT32, INT32, INT32), INT32 x, INT32 t1,
|
|||
if (b2 >= vid.height) b2 = vid.height-1;
|
||||
if (x-1 >= vid.width) x = vid.width;
|
||||
|
||||
// We want to draw N spans per subtask to ensure the work is
|
||||
// coarse enough to not be too slow due to task scheduling overhead.
|
||||
// To safely do this, we need to copy part of spanstart to a local.
|
||||
// This is essentially loop unrolling across threads.
|
||||
constexpr const int kSpanTaskGranularity = 8;
|
||||
drawspandata_t dc_copy = *ds;
|
||||
while (t1 < t2 && t1 <= b1)
|
||||
{
|
||||
mapfunc(t1, spanstart[t1], x - 1);
|
||||
t1++;
|
||||
INT32 spanstartcopy[kSpanTaskGranularity] = {0};
|
||||
INT32 taskspans = 0;
|
||||
for (int i = 0; i < kSpanTaskGranularity; i++)
|
||||
{
|
||||
if (!((t1 + i) < t2 && (t1 + i) <= b1))
|
||||
{
|
||||
break;
|
||||
}
|
||||
spanstartcopy[i] = spanstart[t1 + i];
|
||||
taskspans += 1;
|
||||
}
|
||||
auto task = [=]() mutable -> void {
|
||||
for (int i = 0; i < taskspans; i++)
|
||||
{
|
||||
mapfunc(&dc_copy, spanfunc, t1 + i, spanstartcopy[i], x - 1, false);
|
||||
}
|
||||
};
|
||||
if (allow_parallel)
|
||||
{
|
||||
srb2::g_main_threadpool->schedule(std::move(task));
|
||||
}
|
||||
else
|
||||
{
|
||||
(task)();
|
||||
}
|
||||
t1 += taskspans;
|
||||
}
|
||||
while (b1 > b2 && b1 >= t1)
|
||||
{
|
||||
mapfunc(b1, spanstart[b1], x - 1);
|
||||
b1--;
|
||||
INT32 spanstartcopy[kSpanTaskGranularity] = {0};
|
||||
INT32 taskspans = 0;
|
||||
for (int i = 0; i < kSpanTaskGranularity; i++)
|
||||
{
|
||||
if (!((b1 - i) > b2 && (b1 - i) >= t1))
|
||||
{
|
||||
break;
|
||||
}
|
||||
spanstartcopy[i] = spanstart[b1 - i];
|
||||
taskspans += 1;
|
||||
}
|
||||
auto task = [=]() mutable -> void {
|
||||
for (int i = 0; i < taskspans; i++)
|
||||
{
|
||||
mapfunc(&dc_copy, spanfunc, b1 - i, spanstartcopy[i], x - 1, false);
|
||||
}
|
||||
};
|
||||
if (allow_parallel)
|
||||
{
|
||||
srb2::g_main_threadpool->schedule(std::move(task));
|
||||
}
|
||||
else
|
||||
{
|
||||
(task)();
|
||||
}
|
||||
b1 -= taskspans;
|
||||
}
|
||||
|
||||
while (t2 < t1 && t2 <= b2)
|
||||
|
|
@ -633,10 +653,11 @@ void R_DrawPlanes(void)
|
|||
{
|
||||
visplane_t *pl;
|
||||
INT32 i;
|
||||
drawspandata_t ds {0};
|
||||
|
||||
ZoneScoped;
|
||||
|
||||
R_UpdatePlaneRipple();
|
||||
R_UpdatePlaneRipple(&ds);
|
||||
|
||||
for (i = 0; i < MAXVISPLANES; i++, pl++)
|
||||
{
|
||||
|
|
@ -645,7 +666,7 @@ void R_DrawPlanes(void)
|
|||
if (pl->ffloor != NULL || pl->polyobj != NULL)
|
||||
continue;
|
||||
|
||||
R_DrawSinglePlane(pl);
|
||||
R_DrawSinglePlane(&ds, pl, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -655,10 +676,10 @@ void R_DrawPlanes(void)
|
|||
// Draws the sky within the plane's top/bottom bounds
|
||||
// Note: this uses column drawers instead of span drawers, since the sky is always a texture
|
||||
//
|
||||
static void R_DrawSkyPlane(visplane_t *pl)
|
||||
static void R_DrawSkyPlane(visplane_t *pl, void(*colfunc)(drawcolumndata_t*), boolean allow_parallel)
|
||||
{
|
||||
INT32 x;
|
||||
INT32 angle;
|
||||
drawcolumndata_t dc {0};
|
||||
|
||||
ZoneScoped;
|
||||
|
||||
|
|
@ -669,39 +690,71 @@ static void R_DrawSkyPlane(visplane_t *pl)
|
|||
R_SetColumnFunc(BASEDRAWFUNC, false);
|
||||
|
||||
// use correct aspect ratio scale
|
||||
dc_iscale = skyscale[viewssnum];
|
||||
dc.iscale = skyscale[viewssnum];
|
||||
|
||||
// Sky is always drawn full bright,
|
||||
// i.e. colormaps[0] is used.
|
||||
// Because of this hack, sky is not affected
|
||||
// by sector colormaps (INVUL inverse mapping is not implemented in SRB2 so is irrelevant).
|
||||
dc_colormap = colormaps;
|
||||
dc_fullbright = colormaps;
|
||||
dc.colormap = colormaps;
|
||||
dc.fullbright = colormaps;
|
||||
if (encoremap)
|
||||
{
|
||||
dc_colormap += COLORMAP_REMAPOFFSET;
|
||||
dc_fullbright += COLORMAP_REMAPOFFSET;
|
||||
dc.colormap += COLORMAP_REMAPOFFSET;
|
||||
dc.fullbright += COLORMAP_REMAPOFFSET;
|
||||
}
|
||||
dc_lightmap = colormaps;
|
||||
dc_texturemid = skytexturemid;
|
||||
dc_texheight = textureheight[skytexture]
|
||||
dc.lightmap = colormaps;
|
||||
dc.texturemid = skytexturemid;
|
||||
dc.texheight = textureheight[skytexture]
|
||||
>>FRACBITS;
|
||||
for (x = pl->minx; x <= pl->maxx; x++)
|
||||
{
|
||||
dc_yl = pl->top[x];
|
||||
dc_yh = pl->bottom[x];
|
||||
|
||||
if (dc_yl <= dc_yh)
|
||||
x = pl->minx;
|
||||
|
||||
// Precache the texture so we don't corrupt the zoned heap off-main thread
|
||||
if (!texturecache[texturetranslation[skytexture]])
|
||||
{
|
||||
R_GenerateTexture(texturetranslation[skytexture]);
|
||||
}
|
||||
|
||||
while (x <= pl->maxx)
|
||||
{
|
||||
// Tune concurrency granularity here to maximize throughput
|
||||
// The cheaper colfunc is, the more coarse the task should be
|
||||
constexpr const int kSkyPlaneMacroColumns = 8;
|
||||
|
||||
auto thunk = [=]() mutable -> void {
|
||||
for (int i = 0; i < kSkyPlaneMacroColumns && i + x <= pl->maxx; i++)
|
||||
{
|
||||
dc.yl = pl->top[x + i];
|
||||
dc.yh = pl->bottom[x + i];
|
||||
|
||||
if (dc.yl > dc.yh)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
INT32 angle = (pl->viewangle + xtoviewangle[viewssnum][x + i])>>ANGLETOSKYSHIFT;
|
||||
dc.iscale = FixedMul(skyscale[viewssnum], FINECOSINE(xtoviewangle[viewssnum][x + i]>>ANGLETOFINESHIFT));
|
||||
dc.x = x + i;
|
||||
dc.source =
|
||||
R_GetColumn(texturetranslation[skytexture],
|
||||
-angle); // get negative of angle for each column to display sky correct way round! --Monster Iestyn 27/01/18
|
||||
dc.brightmap = NULL;
|
||||
|
||||
colfunc(&dc);
|
||||
}
|
||||
};
|
||||
|
||||
if (allow_parallel)
|
||||
{
|
||||
angle = (pl->viewangle + xtoviewangle[viewssnum][x])>>ANGLETOSKYSHIFT;
|
||||
dc_iscale = FixedMul(skyscale[viewssnum], FINECOSINE(xtoviewangle[viewssnum][x]>>ANGLETOFINESHIFT));
|
||||
dc_x = x;
|
||||
dc_source =
|
||||
R_GetColumn(texturetranslation[skytexture],
|
||||
-angle); // get negative of angle for each column to display sky correct way round! --Monster Iestyn 27/01/18
|
||||
dc_brightmap = NULL;
|
||||
colfunc();
|
||||
srb2::g_main_threadpool->schedule(std::move(thunk));
|
||||
}
|
||||
else
|
||||
{
|
||||
(thunk)();
|
||||
}
|
||||
|
||||
x += kSkyPlaneMacroColumns;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -718,9 +771,9 @@ static INT64 R_GetSlopeZAt(const pslope_t *slope, fixed_t x, fixed_t y)
|
|||
}
|
||||
|
||||
// Sets the texture origin vector of the sloped plane.
|
||||
static void R_SetSlopePlaneOrigin(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, fixed_t xoff, fixed_t yoff, fixed_t angle)
|
||||
static void R_SetSlopePlaneOrigin(drawspandata_t *ds, pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, fixed_t xoff, fixed_t yoff, fixed_t angle)
|
||||
{
|
||||
floatv3_t *p = &ds_slope_origin;
|
||||
floatv3_t *p = &ds->slope_origin;
|
||||
|
||||
INT64 vx = (INT64)xpos + (INT64)xoff;
|
||||
INT64 vy = (INT64)ypos - (INT64)yoff;
|
||||
|
|
@ -738,17 +791,17 @@ static void R_SetSlopePlaneOrigin(pslope_t *slope, fixed_t xpos, fixed_t ypos, f
|
|||
}
|
||||
|
||||
// This function calculates all of the vectors necessary for drawing a sloped plane.
|
||||
void R_SetSlopePlane(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, fixed_t xoff, fixed_t yoff, angle_t angle, angle_t plangle)
|
||||
void R_SetSlopePlane(drawspandata_t* ds, pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, fixed_t xoff, fixed_t yoff, angle_t angle, angle_t plangle)
|
||||
{
|
||||
// Potentially override other stuff for now cus we're mean. :< But draw a slope plane!
|
||||
// I copied ZDoom's code and adapted it to SRB2... -Red
|
||||
floatv3_t *m = &ds_slope_v, *n = &ds_slope_u;
|
||||
floatv3_t *m = &ds->slope_v, *n = &ds->slope_u;
|
||||
fixed_t height, temp;
|
||||
float ang;
|
||||
|
||||
R_SetSlopePlaneOrigin(slope, xpos, ypos, zpos, xoff, yoff, angle);
|
||||
R_SetSlopePlaneOrigin(ds, slope, xpos, ypos, zpos, xoff, yoff, angle);
|
||||
height = P_GetSlopeZAt(slope, xpos, ypos);
|
||||
zeroheight = FixedToFloat(height - zpos);
|
||||
ds->zeroheight = FixedToFloat(height - zpos);
|
||||
|
||||
// m is the v direction vector in view space
|
||||
ang = ANG2RAD(ANGLE_180 - (angle + plangle));
|
||||
|
|
@ -767,18 +820,18 @@ void R_SetSlopePlane(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos,
|
|||
}
|
||||
|
||||
// This function calculates all of the vectors necessary for drawing a sloped and scaled plane.
|
||||
void R_SetScaledSlopePlane(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, fixed_t xs, fixed_t ys, fixed_t xoff, fixed_t yoff, angle_t angle, angle_t plangle)
|
||||
void R_SetScaledSlopePlane(drawspandata_t* ds, pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, fixed_t xs, fixed_t ys, fixed_t xoff, fixed_t yoff, angle_t angle, angle_t plangle)
|
||||
{
|
||||
floatv3_t *m = &ds_slope_v, *n = &ds_slope_u;
|
||||
floatv3_t *m = &ds->slope_v, *n = &ds->slope_u;
|
||||
fixed_t height, temp;
|
||||
|
||||
float xscale = FixedToFloat(xs);
|
||||
float yscale = FixedToFloat(ys);
|
||||
float ang;
|
||||
|
||||
R_SetSlopePlaneOrigin(slope, xpos, ypos, zpos, xoff, yoff, angle);
|
||||
R_SetSlopePlaneOrigin(ds, slope, xpos, ypos, zpos, xoff, yoff, angle);
|
||||
height = P_GetSlopeZAt(slope, xpos, ypos);
|
||||
zeroheight = FixedToFloat(height - zpos);
|
||||
ds->zeroheight = FixedToFloat(height - zpos);
|
||||
|
||||
// m is the v direction vector in view space
|
||||
ang = ANG2RAD(ANGLE_180 - (angle + plangle));
|
||||
|
|
@ -796,37 +849,37 @@ void R_SetScaledSlopePlane(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t
|
|||
n->y = FixedToFloat(temp - height);
|
||||
}
|
||||
|
||||
void R_CalculateSlopeVectors(void)
|
||||
void R_CalculateSlopeVectors(drawspandata_t* ds)
|
||||
{
|
||||
float sfmult = 65536.f;
|
||||
|
||||
// Eh. I tried making this stuff fixed-point and it exploded on me. Here's a macro for the only floating-point vector function I recall using.
|
||||
#define CROSS(d, v1, v2) \
|
||||
d->x = (v1.y * v2.z) - (v1.z * v2.y);\
|
||||
d->y = (v1.z * v2.x) - (v1.x * v2.z);\
|
||||
d->z = (v1.x * v2.y) - (v1.y * v2.x)
|
||||
CROSS(ds_sup, ds_slope_origin, ds_slope_v);
|
||||
CROSS(ds_svp, ds_slope_origin, ds_slope_u);
|
||||
CROSS(ds_szp, ds_slope_v, ds_slope_u);
|
||||
d.x = (v1.y * v2.z) - (v1.z * v2.y);\
|
||||
d.y = (v1.z * v2.x) - (v1.x * v2.z);\
|
||||
d.z = (v1.x * v2.y) - (v1.y * v2.x)
|
||||
CROSS(ds->sup, ds->slope_origin, ds->slope_v);
|
||||
CROSS(ds->svp, ds->slope_origin, ds->slope_u);
|
||||
CROSS(ds->szp, ds->slope_v, ds->slope_u);
|
||||
#undef CROSS
|
||||
|
||||
ds_sup->z *= focallengthf[viewssnum];
|
||||
ds_svp->z *= focallengthf[viewssnum];
|
||||
ds_szp->z *= focallengthf[viewssnum];
|
||||
ds->sup.z *= focallengthf[viewssnum];
|
||||
ds->svp.z *= focallengthf[viewssnum];
|
||||
ds->szp.z *= focallengthf[viewssnum];
|
||||
|
||||
// Premultiply the texture vectors with the scale factors
|
||||
if (ds_powersoftwo)
|
||||
sfmult *= (1 << nflatshiftup);
|
||||
if (ds->powersoftwo)
|
||||
sfmult *= (1 << ds->nflatshiftup);
|
||||
|
||||
ds_sup->x *= sfmult;
|
||||
ds_sup->y *= sfmult;
|
||||
ds_sup->z *= sfmult;
|
||||
ds_svp->x *= sfmult;
|
||||
ds_svp->y *= sfmult;
|
||||
ds_svp->z *= sfmult;
|
||||
ds->sup.x *= sfmult;
|
||||
ds->sup.y *= sfmult;
|
||||
ds->sup.z *= sfmult;
|
||||
ds->svp.x *= sfmult;
|
||||
ds->svp.y *= sfmult;
|
||||
ds->svp.z *= sfmult;
|
||||
}
|
||||
|
||||
void R_SetTiltedSpan(INT32 span)
|
||||
void R_SetTiltedSpan(drawspandata_t* ds, INT32 span)
|
||||
{
|
||||
if (ds_su == NULL)
|
||||
ds_su = static_cast<floatv3_t*>(Z_Calloc(sizeof(*ds_su) * vid.height, PU_STATIC, NULL));
|
||||
|
|
@ -835,48 +888,48 @@ void R_SetTiltedSpan(INT32 span)
|
|||
if (ds_sz == NULL)
|
||||
ds_sz = static_cast<floatv3_t*>(Z_Calloc(sizeof(*ds_sz) * vid.height, PU_STATIC, NULL));
|
||||
|
||||
ds_sup = &ds_su[span];
|
||||
ds_svp = &ds_sv[span];
|
||||
ds_szp = &ds_sz[span];
|
||||
ds->sup = ds_su[span];
|
||||
ds->svp = ds_sv[span];
|
||||
ds->szp = ds_sz[span];
|
||||
}
|
||||
|
||||
static void R_SetSlopePlaneVectors(visplane_t *pl, INT32 y, fixed_t xoff, fixed_t yoff)
|
||||
static void R_SetSlopePlaneVectors(drawspandata_t* ds, visplane_t *pl, INT32 y, fixed_t xoff, fixed_t yoff)
|
||||
{
|
||||
R_SetTiltedSpan(y);
|
||||
R_SetSlopePlane(pl->slope, pl->viewx, pl->viewy, pl->viewz, xoff, yoff, pl->viewangle, pl->plangle);
|
||||
R_CalculateSlopeVectors();
|
||||
R_SetTiltedSpan(ds, y);
|
||||
R_SetSlopePlane(ds, pl->slope, pl->viewx, pl->viewy, pl->viewz, xoff, yoff, pl->viewangle, pl->plangle);
|
||||
R_CalculateSlopeVectors(ds);
|
||||
}
|
||||
|
||||
static inline void R_AdjustSlopeCoordinates(vector3_t *origin)
|
||||
static inline void R_AdjustSlopeCoordinates(drawspandata_t* ds, vector3_t *origin)
|
||||
{
|
||||
const fixed_t modmask = ((1 << (32-nflatshiftup)) - 1);
|
||||
const fixed_t modmask = ((1 << (32-ds->nflatshiftup)) - 1);
|
||||
|
||||
fixed_t ox = (origin->x & modmask);
|
||||
fixed_t oy = -(origin->y & modmask);
|
||||
|
||||
xoffs &= modmask;
|
||||
yoffs &= modmask;
|
||||
ds->xoffs &= modmask;
|
||||
ds->yoffs &= modmask;
|
||||
|
||||
xoffs -= (origin->x - ox);
|
||||
yoffs += (origin->y + oy);
|
||||
ds->xoffs -= (origin->x - ox);
|
||||
ds->yoffs += (origin->y + oy);
|
||||
}
|
||||
|
||||
static inline void R_AdjustSlopeCoordinatesNPO2(vector3_t *origin)
|
||||
static inline void R_AdjustSlopeCoordinatesNPO2(drawspandata_t* ds, vector3_t *origin)
|
||||
{
|
||||
const fixed_t modmaskw = (ds_flatwidth << FRACBITS);
|
||||
const fixed_t modmaskh = (ds_flatheight << FRACBITS);
|
||||
const fixed_t modmaskw = (ds->flatwidth << FRACBITS);
|
||||
const fixed_t modmaskh = (ds->flatheight << FRACBITS);
|
||||
|
||||
fixed_t ox = (origin->x % modmaskw);
|
||||
fixed_t oy = -(origin->y % modmaskh);
|
||||
|
||||
xoffs %= modmaskw;
|
||||
yoffs %= modmaskh;
|
||||
ds->xoffs %= modmaskw;
|
||||
ds->yoffs %= modmaskh;
|
||||
|
||||
xoffs -= (origin->x - ox);
|
||||
yoffs += (origin->y + oy);
|
||||
ds->xoffs -= (origin->x - ox);
|
||||
ds->yoffs += (origin->y + oy);
|
||||
}
|
||||
|
||||
void R_DrawSinglePlane(visplane_t *pl)
|
||||
void R_DrawSinglePlane(drawspandata_t *ds, visplane_t *pl, boolean allow_parallel)
|
||||
{
|
||||
levelflat_t *levelflat;
|
||||
INT32 light = 0;
|
||||
|
|
@ -884,7 +937,7 @@ void R_DrawSinglePlane(visplane_t *pl)
|
|||
ffloor_t *rover;
|
||||
INT32 type, spanfunctype = BASEDRAWFUNC;
|
||||
debugrender_highlight_t debug = debugrender_highlight_t::SW_HI_PLANES;
|
||||
void (*mapfunc)(INT32, INT32, INT32) = R_MapPlane;
|
||||
void (*mapfunc)(drawspandata_t*, void(*)(drawspandata_t*), INT32, INT32, INT32, boolean) = R_MapPlane;
|
||||
bool highlight = R_PlaneIsHighlighted(pl);
|
||||
|
||||
if (!(pl->minx <= pl->maxx))
|
||||
|
|
@ -892,30 +945,33 @@ void R_DrawSinglePlane(visplane_t *pl)
|
|||
|
||||
ZoneScoped;
|
||||
|
||||
R_UpdatePlaneRipple(ds);
|
||||
|
||||
// sky flat
|
||||
if (pl->picnum == skyflatnum)
|
||||
{
|
||||
if (highlight)
|
||||
{
|
||||
r8_flatcolor = 35; // red
|
||||
dc_lightmap = colormaps;
|
||||
drawcolumndata_t dc = {};
|
||||
dc.r8_flatcolor = 35; // red
|
||||
dc.lightmap = colormaps;
|
||||
|
||||
for (dc_x = pl->minx; dc_x <= pl->maxx; ++dc_x)
|
||||
for (dc.x = pl->minx; dc.x <= pl->maxx; ++dc.x)
|
||||
{
|
||||
dc_yl = pl->top[dc_x];
|
||||
dc_yh = pl->bottom[dc_x];
|
||||
R_DrawColumn_Flat_8();
|
||||
dc.yl = pl->top[dc.x];
|
||||
dc.yh = pl->bottom[dc.x];
|
||||
R_DrawColumn_Flat_8(&dc);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
R_DrawSkyPlane(pl);
|
||||
R_DrawSkyPlane(pl, colfunc, allow_parallel);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
planeripple.active = false;
|
||||
ds_brightmap = NULL;
|
||||
ds->planeripple.active = false;
|
||||
ds->brightmap = NULL;
|
||||
R_SetSpanFunc(BASEDRAWFUNC, false, false);
|
||||
|
||||
if (pl->polyobj)
|
||||
|
|
@ -926,7 +982,7 @@ void R_DrawSinglePlane(visplane_t *pl)
|
|||
else if (pl->polyobj->translucency > 0)
|
||||
{
|
||||
spanfunctype = (pl->polyobj->flags & POF_SPLAT) ? SPANDRAWFUNC_TRANSSPLAT : SPANDRAWFUNC_TRANS;
|
||||
ds_transmap = R_GetTranslucencyTable(pl->polyobj->translucency);
|
||||
ds->transmap = R_GetTranslucencyTable(pl->polyobj->translucency);
|
||||
}
|
||||
else if (pl->polyobj->flags & POF_SPLAT) // Opaque, but allow transparent flat pixels
|
||||
spanfunctype = SPANDRAWFUNC_SPLAT;
|
||||
|
|
@ -968,7 +1024,7 @@ void R_DrawSinglePlane(visplane_t *pl)
|
|||
INT32 trans = (10*((256+12) - pl->ffloor->alpha))/255;
|
||||
if (trans >= 10)
|
||||
return; // Don't even draw it
|
||||
if (!(ds_transmap = R_GetBlendTable(pl->ffloor->blend, trans)))
|
||||
if (!(ds->transmap = R_GetBlendTable(pl->ffloor->blend, trans)))
|
||||
spanfunctype = SPANDRAWFUNC_SPLAT; // Opaque, but allow transparent flat pixels
|
||||
}
|
||||
|
||||
|
|
@ -998,7 +1054,7 @@ void R_DrawSinglePlane(visplane_t *pl)
|
|||
{
|
||||
INT32 top, bottom;
|
||||
|
||||
planeripple.active = true;
|
||||
ds->planeripple.active = true;
|
||||
if (spanfunctype == SPANDRAWFUNC_TRANS)
|
||||
{
|
||||
spanfunctype = SPANDRAWFUNC_WATER;
|
||||
|
|
@ -1050,7 +1106,7 @@ void R_DrawSinglePlane(visplane_t *pl)
|
|||
#endif
|
||||
}
|
||||
|
||||
currentplane = pl;
|
||||
ds->currentplane = pl;
|
||||
levelflat = &levelflats[pl->picnum];
|
||||
|
||||
/* :james: */
|
||||
|
|
@ -1060,18 +1116,18 @@ void R_DrawSinglePlane(visplane_t *pl)
|
|||
case LEVELFLAT_NONE:
|
||||
return;
|
||||
case LEVELFLAT_FLAT:
|
||||
ds_source = (UINT8 *)R_GetFlat(levelflat->u.flat.lumpnum);
|
||||
R_CheckFlatLength(W_LumpLength(levelflat->u.flat.lumpnum));
|
||||
ds->source = (UINT8 *)R_GetFlat(levelflat->u.flat.lumpnum);
|
||||
R_CheckFlatLength(ds, W_LumpLength(levelflat->u.flat.lumpnum));
|
||||
// Raw flats always have dimensions that are powers-of-two numbers.
|
||||
ds_powersoftwo = true;
|
||||
ds->powersoftwo = true;
|
||||
break;
|
||||
default:
|
||||
ds_source = (UINT8 *)R_GetLevelFlat(levelflat);
|
||||
if (!ds_source)
|
||||
ds->source = (UINT8 *)R_GetLevelFlat(ds, levelflat);
|
||||
if (!ds->source)
|
||||
return;
|
||||
// Check if this texture or patch has power-of-two dimensions.
|
||||
if (R_CheckPowersOfTwo())
|
||||
R_CheckFlatLength(ds_flatwidth * ds_flatheight);
|
||||
if (R_CheckPowersOfTwo(ds))
|
||||
R_CheckFlatLength(ds, ds->flatwidth * ds->flatheight);
|
||||
}
|
||||
|
||||
if (type == LEVELFLAT_TEXTURE)
|
||||
|
|
@ -1084,19 +1140,18 @@ void R_DrawSinglePlane(visplane_t *pl)
|
|||
// FIXME: This has the potential to read out of
|
||||
// bounds if the brightmap texture is not as
|
||||
// large as the flat.
|
||||
ds_brightmap = (UINT8 *)R_GenerateTextureAsFlat(bmNum);
|
||||
ds->brightmap = (UINT8 *)R_GenerateTextureAsFlat(bmNum);
|
||||
}
|
||||
}
|
||||
|
||||
if (!pl->slope // Don't mess with angle on slopes! We'll handle this ourselves later
|
||||
&& viewangle != pl->viewangle+pl->plangle)
|
||||
{
|
||||
memset(cachedheight, 0, sizeof (cachedheight));
|
||||
viewangle = pl->viewangle+pl->plangle;
|
||||
}
|
||||
|
||||
xoffs = pl->xoffs;
|
||||
yoffs = pl->yoffs;
|
||||
ds->xoffs = pl->xoffs;
|
||||
ds->yoffs = pl->yoffs;
|
||||
|
||||
if (light >= LIGHTLEVELS)
|
||||
light = LIGHTLEVELS-1;
|
||||
|
|
@ -1112,27 +1167,27 @@ void R_DrawSinglePlane(visplane_t *pl)
|
|||
|
||||
if (!pl->plangle)
|
||||
{
|
||||
if (ds_powersoftwo)
|
||||
R_AdjustSlopeCoordinates(&pl->slope->o);
|
||||
if (ds->powersoftwo)
|
||||
R_AdjustSlopeCoordinates(ds, &pl->slope->o);
|
||||
else
|
||||
R_AdjustSlopeCoordinatesNPO2(&pl->slope->o);
|
||||
R_AdjustSlopeCoordinatesNPO2(ds, &pl->slope->o);
|
||||
}
|
||||
|
||||
if (planeripple.active)
|
||||
if (ds->planeripple.active)
|
||||
{
|
||||
planeheight = abs(P_GetSlopeZAt(pl->slope, pl->viewx, pl->viewy) - pl->viewz);
|
||||
ds->planeheight = abs(P_GetSlopeZAt(pl->slope, pl->viewx, pl->viewy) - pl->viewz);
|
||||
|
||||
R_PlaneBounds(pl);
|
||||
|
||||
for (x = pl->high; x < pl->low; x++)
|
||||
{
|
||||
ds_bgofs = R_CalculateRippleOffset(x);
|
||||
R_CalculatePlaneRipple(pl->viewangle + pl->plangle);
|
||||
R_SetSlopePlaneVectors(pl, x, (xoffs + planeripple.xfrac), (yoffs + planeripple.yfrac));
|
||||
ds->bgofs = R_CalculateRippleOffset(ds, x);
|
||||
R_CalculatePlaneRipple(ds, pl->viewangle + pl->plangle);
|
||||
R_SetSlopePlaneVectors(ds, pl, x, (ds->xoffs + ds->planeripple.xfrac), (ds->yoffs + ds->planeripple.yfrac));
|
||||
}
|
||||
}
|
||||
else
|
||||
R_SetSlopePlaneVectors(pl, 0, xoffs, yoffs);
|
||||
R_SetSlopePlaneVectors(ds, pl, 0, ds->xoffs, ds->yoffs);
|
||||
|
||||
switch (spanfunctype)
|
||||
{
|
||||
|
|
@ -1150,27 +1205,27 @@ void R_DrawSinglePlane(visplane_t *pl)
|
|||
break;
|
||||
}
|
||||
|
||||
planezlight = scalelight[light];
|
||||
ds->planezlight = scalelight[light];
|
||||
}
|
||||
else
|
||||
{
|
||||
planeheight = abs(pl->height - pl->viewz);
|
||||
planezlight = zlight[light];
|
||||
ds->planeheight = abs(pl->height - pl->viewz);
|
||||
ds->planezlight = zlight[light];
|
||||
}
|
||||
|
||||
if (highlight && R_SetSpanFuncFlat(BASEDRAWFUNC))
|
||||
{
|
||||
r8_flatcolor = 35; // red
|
||||
ds_flatlighting = colormaps;
|
||||
ds->r8_flatcolor = 35; // red
|
||||
ds->flatlighting = colormaps;
|
||||
}
|
||||
else
|
||||
{
|
||||
R_CheckDebugHighlight(debug);
|
||||
|
||||
// Use the correct span drawer depending on the powers-of-twoness
|
||||
R_SetSpanFunc(spanfunctype, !ds_powersoftwo, ds_brightmap != NULL);
|
||||
R_SetSpanFunc(spanfunctype, !ds->powersoftwo, ds->brightmap != NULL);
|
||||
|
||||
ds_flatlighting = NULL;
|
||||
ds->flatlighting = NULL;
|
||||
}
|
||||
|
||||
// set the maximum value for unsigned
|
||||
|
|
@ -1182,7 +1237,7 @@ void R_DrawSinglePlane(visplane_t *pl)
|
|||
stop = pl->maxx + 1;
|
||||
|
||||
for (x = pl->minx; x <= stop; x++)
|
||||
R_MakeSpans(mapfunc, x, pl->top[x-1], pl->bottom[x-1], pl->top[x], pl->bottom[x]);
|
||||
R_MakeSpans(mapfunc, spanfunc, ds, x, pl->top[x-1], pl->bottom[x-1], pl->top[x], pl->bottom[x], allow_parallel);
|
||||
|
||||
/*
|
||||
QUINCUNX anti-aliasing technique (sort of)
|
||||
|
|
@ -1230,7 +1285,7 @@ using the palette colors.
|
|||
yoffs += FRACUNIT/4;
|
||||
break;
|
||||
}
|
||||
planeheight = abs(pl->height - pl->viewz);
|
||||
ds->planeheight = abs(pl->height - pl->viewz);
|
||||
|
||||
if (light >= LIGHTLEVELS)
|
||||
light = LIGHTLEVELS-1;
|
||||
|
|
|
|||
|
|
@ -75,13 +75,8 @@ extern size_t maxopenings;
|
|||
extern INT16 floorclip[MAXVIDWIDTH], ceilingclip[MAXVIDWIDTH];
|
||||
extern fixed_t frontscale[MAXVIDWIDTH];
|
||||
extern fixed_t yslopetab[MAXSPLITSCREENPLAYERS][MAXVIDHEIGHT*16];
|
||||
extern fixed_t cachedheight[MAXVIDHEIGHT];
|
||||
extern fixed_t cacheddistance[MAXVIDHEIGHT];
|
||||
extern fixed_t cachedxstep[MAXVIDHEIGHT];
|
||||
extern fixed_t cachedystep[MAXVIDHEIGHT];
|
||||
|
||||
extern fixed_t *yslope;
|
||||
extern lighttable_t **planezlight;
|
||||
|
||||
void R_InitPlanes(void);
|
||||
void R_ClearPlanes(void);
|
||||
|
|
@ -96,19 +91,19 @@ void R_ExpandPlane(visplane_t *pl, INT32 start, INT32 stop);
|
|||
void R_PlaneBounds(visplane_t *plane);
|
||||
|
||||
size_t R_FlatDimensionsFromLumpSize(size_t size);
|
||||
void R_CheckFlatLength(size_t size);
|
||||
boolean R_CheckPowersOfTwo(void);
|
||||
void R_CheckFlatLength(drawspandata_t* ds, size_t size);
|
||||
boolean R_CheckPowersOfTwo(drawspandata_t* ds);
|
||||
|
||||
// Draws a single visplane.
|
||||
void R_DrawSinglePlane(visplane_t *pl);
|
||||
void R_DrawSinglePlane(drawspandata_t* ds, visplane_t *pl, boolean allow_parallel);
|
||||
|
||||
// Calculates the slope vectors needed for tilted span drawing.
|
||||
void R_SetSlopePlane(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, fixed_t xoff, fixed_t yoff, angle_t angle, angle_t plangle);
|
||||
void R_SetScaledSlopePlane(pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, fixed_t xs, fixed_t ys, fixed_t xoff, fixed_t yoff, angle_t angle, angle_t plangle);
|
||||
void R_CalculateSlopeVectors(void);
|
||||
void R_SetSlopePlane(drawspandata_t* ds, pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, fixed_t xoff, fixed_t yoff, angle_t angle, angle_t plangle);
|
||||
void R_SetScaledSlopePlane(drawspandata_t* ds, pslope_t *slope, fixed_t xpos, fixed_t ypos, fixed_t zpos, fixed_t xs, fixed_t ys, fixed_t xoff, fixed_t yoff, angle_t angle, angle_t plangle);
|
||||
void R_CalculateSlopeVectors(drawspandata_t* ds);
|
||||
|
||||
// Sets the slope vector pointers for the current tilted span.
|
||||
void R_SetTiltedSpan(INT32 span);
|
||||
void R_SetTiltedSpan(drawspandata_t* ds, INT32 span);
|
||||
|
||||
boolean R_PlaneIsHighlighted(const visplane_t *pl);
|
||||
|
||||
|
|
|
|||
464
src/r_segs.cpp
464
src/r_segs.cpp
File diff suppressed because it is too large
Load diff
|
|
@ -30,6 +30,7 @@
|
|||
#include "m_cond.h"
|
||||
#include "k_kart.h"
|
||||
#include "m_random.h"
|
||||
#include "s_sound.h"
|
||||
#if 0
|
||||
#include "k_kart.h" // K_KartResetPlayerColor
|
||||
#endif
|
||||
|
|
@ -520,7 +521,7 @@ void SetRandomFakePlayerSkin(player_t* player, boolean fast)
|
|||
{
|
||||
S_StartSound(player->mo, sfx_kc33);
|
||||
S_StartSound(player->mo, sfx_cdfm44);
|
||||
|
||||
|
||||
mobj_t *parent = player->mo;
|
||||
fixed_t baseangle = P_RandomRange(PR_DECORATION, 0, 359);
|
||||
INT32 j;
|
||||
|
|
@ -551,7 +552,7 @@ void SetRandomFakePlayerSkin(player_t* player, boolean fast)
|
|||
box->cusval = 1;
|
||||
else
|
||||
box->cusval = 0;
|
||||
|
||||
|
||||
if (j > 3)
|
||||
{
|
||||
P_SetMobjState(box, (j == 4) ? S_MAGICIANBOX_TOP : S_MAGICIANBOX_BOTTOM);
|
||||
|
|
@ -1066,7 +1067,7 @@ next_token:
|
|||
Z_Free(unloadedskin);
|
||||
|
||||
break;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -328,6 +328,8 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr
|
|||
fixed_t offsetx = 0, offsety = 0;
|
||||
fixed_t planeheight = 0;
|
||||
fixed_t step;
|
||||
drawcolumndata_t dc = {0};
|
||||
drawspandata_t ds = {0};
|
||||
|
||||
int spanfunctype = SPANDRAWFUNC_SPRITE;
|
||||
|
||||
|
|
@ -391,18 +393,18 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr
|
|||
// do segment d -> left side of texture
|
||||
RASTERPARAMS(0,3,pSplat->width-1,0,0,1);
|
||||
|
||||
ds_source = (UINT8 *)pSplat->pic;
|
||||
ds_flatwidth = pSplat->width;
|
||||
ds_flatheight = pSplat->height;
|
||||
ds.source = (UINT8 *)pSplat->pic;
|
||||
ds.flatwidth = pSplat->width;
|
||||
ds.flatheight = pSplat->height;
|
||||
|
||||
if (R_CheckPowersOfTwo())
|
||||
R_CheckFlatLength(ds_flatwidth * ds_flatheight);
|
||||
if (R_CheckPowersOfTwo(&ds))
|
||||
R_CheckFlatLength(&ds, ds.flatwidth * ds.flatheight);
|
||||
|
||||
if (pSplat->slope)
|
||||
{
|
||||
R_SetTiltedSpan(0);
|
||||
R_SetScaledSlopePlane(pSplat->slope, vis->viewpoint.x, vis->viewpoint.y, vis->viewpoint.z, pSplat->xscale, pSplat->yscale, -pSplat->verts[0].x, pSplat->verts[0].y, vis->viewpoint.angle, pSplat->angle);
|
||||
R_CalculateSlopeVectors();
|
||||
R_SetTiltedSpan(&ds, 0);
|
||||
R_SetScaledSlopePlane(&ds, pSplat->slope, vis->viewpoint.x, vis->viewpoint.y, vis->viewpoint.z, pSplat->xscale, pSplat->yscale, -pSplat->verts[0].x, pSplat->verts[0].y, vis->viewpoint.angle, pSplat->angle);
|
||||
R_CalculateSlopeVectors(&ds);
|
||||
spanfunctype = SPANDRAWFUNC_TILTEDSPRITE;
|
||||
}
|
||||
else
|
||||
|
|
@ -417,8 +419,6 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr
|
|||
angle_t angle = (pSplat->angle >> ANGLETOFINESHIFT);
|
||||
offsetx = FixedMul(a, FINECOSINE(angle)) - FixedMul(b, FINESINE(angle));
|
||||
offsety = -FixedMul(a, FINESINE(angle)) - FixedMul(b, FINECOSINE(angle));
|
||||
|
||||
memset(cachedheight, 0, sizeof(cachedheight));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -427,31 +427,31 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr
|
|||
}
|
||||
}
|
||||
|
||||
ds_colormap = vis->colormap;
|
||||
ds_fullbright = colormaps;
|
||||
ds_brightmap = NULL;
|
||||
ds.colormap = vis->colormap;
|
||||
ds.fullbright = colormaps;
|
||||
ds.brightmap = NULL;
|
||||
|
||||
ds_translation = R_GetSpriteTranslation(vis);
|
||||
if (ds_translation == NULL)
|
||||
ds_translation = colormaps;
|
||||
ds.translation = R_GetSpriteTranslation(vis);
|
||||
if (ds.translation == NULL)
|
||||
ds.translation = colormaps;
|
||||
|
||||
if (vis->extra_colormap)
|
||||
{
|
||||
if (!ds_colormap)
|
||||
ds_colormap = vis->extra_colormap->colormap;
|
||||
if (!ds.colormap)
|
||||
ds.colormap = vis->extra_colormap->colormap;
|
||||
else
|
||||
ds_colormap = &vis->extra_colormap->colormap[ds_colormap - colormaps];
|
||||
ds.colormap = &vis->extra_colormap->colormap[ds.colormap - colormaps];
|
||||
}
|
||||
|
||||
if (encoremap && !vis->mobj->color && !(vis->mobj->flags & MF_DONTENCOREMAP))
|
||||
{
|
||||
dc_colormap += COLORMAP_REMAPOFFSET;
|
||||
dc_fullbright += COLORMAP_REMAPOFFSET;
|
||||
dc.colormap += COLORMAP_REMAPOFFSET;
|
||||
dc.fullbright += COLORMAP_REMAPOFFSET;
|
||||
}
|
||||
|
||||
if (vis->transmap)
|
||||
{
|
||||
ds_transmap = vis->transmap;
|
||||
ds.transmap = vis->transmap;
|
||||
|
||||
if (pSplat->slope)
|
||||
spanfunctype = SPANDRAWFUNC_TILTEDTRANSSPRITE;
|
||||
|
|
@ -459,9 +459,9 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr
|
|||
spanfunctype = SPANDRAWFUNC_TRANSSPRITE;
|
||||
}
|
||||
else
|
||||
ds_transmap = NULL;
|
||||
ds.transmap = NULL;
|
||||
|
||||
R_SetSpanFunc(spanfunctype, !ds_powersoftwo, false);
|
||||
R_SetSpanFunc(spanfunctype, !ds.powersoftwo, false);
|
||||
|
||||
if (maxy >= vid.height)
|
||||
maxy = vid.height-1;
|
||||
|
|
@ -526,48 +526,32 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr
|
|||
angle_t planecos = FINECOSINE(angle);
|
||||
angle_t planesin = FINESINE(angle);
|
||||
|
||||
if (planeheight != cachedheight[y])
|
||||
distance = FixedMul(planeheight, yslope[y]);
|
||||
span = abs(centery - y);
|
||||
|
||||
if (span) // Don't divide by zero
|
||||
{
|
||||
cachedheight[y] = planeheight;
|
||||
distance = cacheddistance[y] = FixedMul(planeheight, yslope[y]);
|
||||
span = abs(centery - y);
|
||||
|
||||
if (span) // Don't divide by zero
|
||||
{
|
||||
xstep = FixedMul(planesin, planeheight) / span;
|
||||
ystep = FixedMul(planecos, planeheight) / span;
|
||||
}
|
||||
else
|
||||
xstep = ystep = FRACUNIT;
|
||||
|
||||
cachedxstep[y] = xstep;
|
||||
cachedystep[y] = ystep;
|
||||
xstep = FixedMul(planesin, planeheight) / span;
|
||||
ystep = FixedMul(planecos, planeheight) / span;
|
||||
}
|
||||
else
|
||||
{
|
||||
distance = cacheddistance[y];
|
||||
xstep = cachedxstep[y];
|
||||
ystep = cachedystep[y];
|
||||
}
|
||||
xstep = ystep = FRACUNIT;
|
||||
|
||||
ds_xstep = FixedDiv(xstep, pSplat->xscale);
|
||||
ds_ystep = FixedDiv(ystep, pSplat->yscale);
|
||||
ds.xstep = FixedDiv(xstep, pSplat->xscale);
|
||||
ds.ystep = FixedDiv(ystep, pSplat->yscale);
|
||||
|
||||
ds_xfrac = FixedDiv(offsetx + FixedMul(planecos, distance) + (x1 - centerx) * xstep, pSplat->xscale);
|
||||
ds_yfrac = FixedDiv(offsety - FixedMul(planesin, distance) + (x1 - centerx) * ystep, pSplat->yscale);
|
||||
ds.xfrac = FixedDiv(offsetx + FixedMul(planecos, distance) + (x1 - centerx) * xstep, pSplat->xscale);
|
||||
ds.yfrac = FixedDiv(offsety - FixedMul(planesin, distance) + (x1 - centerx) * ystep, pSplat->yscale);
|
||||
}
|
||||
|
||||
ds_y = y;
|
||||
ds_x1 = x1;
|
||||
ds_x2 = x2;
|
||||
spanfunc();
|
||||
ds.y = y;
|
||||
ds.x1 = x1;
|
||||
ds.x2 = x2;
|
||||
spanfunc(&ds);
|
||||
|
||||
rastertab[y].minx = INT32_MAX;
|
||||
rastertab[y].maxx = INT32_MIN;
|
||||
}
|
||||
|
||||
if (pSplat->angle && !pSplat->slope)
|
||||
memset(cachedheight, 0, sizeof(cachedheight));
|
||||
}
|
||||
|
||||
static void prepare_rastertab(void)
|
||||
|
|
|
|||
128
src/r_textures.c
128
src/r_textures.c
|
|
@ -896,7 +896,7 @@ void *R_GetFlat(lumpnum_t flatlumpnum)
|
|||
//
|
||||
// If needed, convert a texture or patch to a flat.
|
||||
//
|
||||
void *R_GetLevelFlat(levelflat_t *levelflat)
|
||||
void *R_GetLevelFlat(drawspandata_t* ds, levelflat_t *levelflat)
|
||||
{
|
||||
boolean isleveltexture = (levelflat->type == LEVELFLAT_TEXTURE);
|
||||
texture_t *texture = (isleveltexture ? textures[levelflat->u.texture.num] : NULL);
|
||||
|
|
@ -909,8 +909,8 @@ void *R_GetLevelFlat(levelflat_t *levelflat)
|
|||
if (texture->flat)
|
||||
{
|
||||
flatdata = texture->flat;
|
||||
ds_flatwidth = texture->width;
|
||||
ds_flatheight = texture->height;
|
||||
ds->flatwidth = texture->width;
|
||||
ds->flatheight = texture->height;
|
||||
texturechanged = false;
|
||||
}
|
||||
else
|
||||
|
|
@ -924,8 +924,8 @@ void *R_GetLevelFlat(levelflat_t *levelflat)
|
|||
if (isleveltexture)
|
||||
{
|
||||
levelflat->picture = R_GenerateTextureAsFlat(levelflat->u.texture.num);
|
||||
ds_flatwidth = levelflat->width = texture->width;
|
||||
ds_flatheight = levelflat->height = texture->height;
|
||||
ds->flatwidth = levelflat->width = texture->width;
|
||||
ds->flatheight = levelflat->height = texture->height;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -938,8 +938,8 @@ void *R_GetLevelFlat(levelflat_t *levelflat)
|
|||
levelflat->width = (UINT16)pngwidth;
|
||||
levelflat->height = (UINT16)pngheight;
|
||||
|
||||
ds_flatwidth = levelflat->width;
|
||||
ds_flatheight = levelflat->height;
|
||||
ds->flatwidth = levelflat->width;
|
||||
ds->flatheight = levelflat->height;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
|
@ -949,8 +949,8 @@ void *R_GetLevelFlat(levelflat_t *levelflat)
|
|||
size_t size;
|
||||
softwarepatch_t *patch = W_CacheLumpNum(levelflat->u.flat.lumpnum, PU_CACHE);
|
||||
|
||||
levelflat->width = ds_flatwidth = SHORT(patch->width);
|
||||
levelflat->height = ds_flatheight = SHORT(patch->height);
|
||||
levelflat->width = ds->flatwidth = SHORT(patch->width);
|
||||
levelflat->height = ds->flatheight = SHORT(patch->height);
|
||||
|
||||
levelflat->picture = Z_Malloc(levelflat->width * levelflat->height, PU_LEVEL, NULL);
|
||||
converted = Picture_FlatConvert(PICFMT_DOOMPATCH, patch, PICFMT_FLAT, 0, &size, levelflat->width, levelflat->height, SHORT(patch->topoffset), SHORT(patch->leftoffset), 0);
|
||||
|
|
@ -961,8 +961,8 @@ void *R_GetLevelFlat(levelflat_t *levelflat)
|
|||
}
|
||||
else
|
||||
{
|
||||
ds_flatwidth = levelflat->width;
|
||||
ds_flatheight = levelflat->height;
|
||||
ds->flatwidth = levelflat->width;
|
||||
ds->flatheight = levelflat->height;
|
||||
}
|
||||
|
||||
levelflat->u.texture.lastnum = levelflat->u.texture.num;
|
||||
|
|
@ -977,21 +977,21 @@ void *R_GetLevelFlat(levelflat_t *levelflat)
|
|||
//
|
||||
// Sets ds_powersoftwo true if the flat's dimensions are powers of two, and returns that.
|
||||
//
|
||||
boolean R_CheckPowersOfTwo(void)
|
||||
boolean R_CheckPowersOfTwo(drawspandata_t* ds)
|
||||
{
|
||||
boolean wpow2 = (!(ds_flatwidth & (ds_flatwidth - 1)));
|
||||
boolean hpow2 = (!(ds_flatheight & (ds_flatheight - 1)));
|
||||
boolean wpow2 = (!(ds->flatwidth & (ds->flatwidth - 1)));
|
||||
boolean hpow2 = (!(ds->flatheight & (ds->flatheight - 1)));
|
||||
|
||||
// Initially, the flat isn't powers-of-two-sized.
|
||||
ds_powersoftwo = false;
|
||||
ds->powersoftwo = false;
|
||||
|
||||
// But if the width and height are powers of two,
|
||||
// and are EQUAL, then it's okay :]
|
||||
if ((ds_flatwidth == ds_flatheight) && (wpow2 && hpow2))
|
||||
ds_powersoftwo = true;
|
||||
if ((ds->flatwidth == ds->flatheight) && (wpow2 && hpow2))
|
||||
ds->powersoftwo = true;
|
||||
|
||||
// Just return ds_powersoftwo.
|
||||
return ds_powersoftwo;
|
||||
return ds->powersoftwo;
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -1037,72 +1037,72 @@ size_t R_FlatDimensionsFromLumpSize(size_t size)
|
|||
//
|
||||
// Determine the flat's dimensions from its lump length.
|
||||
//
|
||||
void R_CheckFlatLength(size_t size)
|
||||
void R_CheckFlatLength(drawspandata_t* ds, size_t size)
|
||||
{
|
||||
switch (size)
|
||||
{
|
||||
case 4194304: // 2048x2048 lump
|
||||
nflatmask = 0x3FF800;
|
||||
nflatxshift = 21;
|
||||
nflatyshift = 10;
|
||||
nflatshiftup = 5;
|
||||
ds_flatwidth = ds_flatheight = 2048;
|
||||
ds->nflatmask = 0x3FF800;
|
||||
ds->nflatxshift = 21;
|
||||
ds->nflatyshift = 10;
|
||||
ds->nflatshiftup = 5;
|
||||
ds->flatwidth = ds->flatheight = 2048;
|
||||
break;
|
||||
case 1048576: // 1024x1024 lump
|
||||
nflatmask = 0xFFC00;
|
||||
nflatxshift = 22;
|
||||
nflatyshift = 12;
|
||||
nflatshiftup = 6;
|
||||
ds_flatwidth = ds_flatheight = 1024;
|
||||
ds->nflatmask = 0xFFC00;
|
||||
ds->nflatxshift = 22;
|
||||
ds->nflatyshift = 12;
|
||||
ds->nflatshiftup = 6;
|
||||
ds->flatwidth = ds->flatheight = 1024;
|
||||
break;
|
||||
case 262144:// 512x512 lump
|
||||
nflatmask = 0x3FE00;
|
||||
nflatxshift = 23;
|
||||
nflatyshift = 14;
|
||||
nflatshiftup = 7;
|
||||
ds_flatwidth = ds_flatheight = 512;
|
||||
ds->nflatmask = 0x3FE00;
|
||||
ds->nflatxshift = 23;
|
||||
ds->nflatyshift = 14;
|
||||
ds->nflatshiftup = 7;
|
||||
ds->flatwidth = ds->flatheight = 512;
|
||||
break;
|
||||
case 65536: // 256x256 lump
|
||||
nflatmask = 0xFF00;
|
||||
nflatxshift = 24;
|
||||
nflatyshift = 16;
|
||||
nflatshiftup = 8;
|
||||
ds_flatwidth = ds_flatheight = 256;
|
||||
ds->nflatmask = 0xFF00;
|
||||
ds->nflatxshift = 24;
|
||||
ds->nflatyshift = 16;
|
||||
ds->nflatshiftup = 8;
|
||||
ds->flatwidth = ds->flatheight = 256;
|
||||
break;
|
||||
case 16384: // 128x128 lump
|
||||
nflatmask = 0x3F80;
|
||||
nflatxshift = 25;
|
||||
nflatyshift = 18;
|
||||
nflatshiftup = 9;
|
||||
ds_flatwidth = ds_flatheight = 128;
|
||||
ds->nflatmask = 0x3F80;
|
||||
ds->nflatxshift = 25;
|
||||
ds->nflatyshift = 18;
|
||||
ds->nflatshiftup = 9;
|
||||
ds->flatwidth = ds->flatheight = 128;
|
||||
break;
|
||||
case 1024: // 32x32 lump
|
||||
nflatmask = 0x3E0;
|
||||
nflatxshift = 27;
|
||||
nflatyshift = 22;
|
||||
nflatshiftup = 11;
|
||||
ds_flatwidth = ds_flatheight = 32;
|
||||
ds->nflatmask = 0x3E0;
|
||||
ds->nflatxshift = 27;
|
||||
ds->nflatyshift = 22;
|
||||
ds->nflatshiftup = 11;
|
||||
ds->flatwidth = ds->flatheight = 32;
|
||||
break;
|
||||
case 256: // 16x16 lump
|
||||
nflatmask = 0xF0;
|
||||
nflatxshift = 28;
|
||||
nflatyshift = 24;
|
||||
nflatshiftup = 12;
|
||||
ds_flatwidth = ds_flatheight = 16;
|
||||
ds->nflatmask = 0xF0;
|
||||
ds->nflatxshift = 28;
|
||||
ds->nflatyshift = 24;
|
||||
ds->nflatshiftup = 12;
|
||||
ds->flatwidth = ds->flatheight = 16;
|
||||
break;
|
||||
case 64: // 8x8 lump
|
||||
nflatmask = 0x38;
|
||||
nflatxshift = 29;
|
||||
nflatyshift = 26;
|
||||
nflatshiftup = 13;
|
||||
ds_flatwidth = ds_flatheight = 8;
|
||||
ds->nflatmask = 0x38;
|
||||
ds->nflatxshift = 29;
|
||||
ds->nflatyshift = 26;
|
||||
ds->nflatshiftup = 13;
|
||||
ds->flatwidth = ds->flatheight = 8;
|
||||
break;
|
||||
default: // 64x64 lump
|
||||
nflatmask = 0xFC0;
|
||||
nflatxshift = 26;
|
||||
nflatyshift = 20;
|
||||
nflatshiftup = 10;
|
||||
ds_flatwidth = ds_flatheight = 64;
|
||||
ds->nflatmask = 0xFC0;
|
||||
ds->nflatxshift = 26;
|
||||
ds->nflatyshift = 20;
|
||||
ds->nflatshiftup = 10;
|
||||
ds->flatwidth = ds->flatheight = 64;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -98,13 +98,13 @@ void R_CheckTextureCache(INT32 tex);
|
|||
void R_ClearTextureNumCache(boolean btell);
|
||||
|
||||
// Retrieve texture data.
|
||||
void *R_GetLevelFlat(levelflat_t *levelflat);
|
||||
void *R_GetLevelFlat(drawspandata_t* ds, levelflat_t *levelflat);
|
||||
UINT8 *R_GetColumn(fixed_t tex, INT32 col);
|
||||
UINT8 *R_GetBrightmapColumn(fixed_t tex, INT32 col);
|
||||
void *R_GetFlat(lumpnum_t flatnum);
|
||||
|
||||
boolean R_CheckPowersOfTwo(void);
|
||||
void R_CheckFlatLength(size_t size);
|
||||
boolean R_CheckPowersOfTwo(drawspandata_t* ds);
|
||||
void R_CheckFlatLength(drawspandata_t* ds, size_t size);
|
||||
|
||||
void R_UpdateTextureBrightmap(INT32 tx, INT32 bm);
|
||||
|
||||
|
|
|
|||
220
src/r_things.cpp
220
src/r_things.cpp
|
|
@ -39,6 +39,7 @@
|
|||
#include "d_netfil.h" // blargh. for nameonly().
|
||||
#include "m_cheat.h" // objectplace
|
||||
#include "p_local.h" // stplyr
|
||||
#include "core/thread_pool.h"
|
||||
#ifdef HWRENDER
|
||||
#include "hardware/hw_md2.h"
|
||||
#include "hardware/hw_glob.h"
|
||||
|
|
@ -637,17 +638,17 @@ INT16 *mceilingclip;
|
|||
fixed_t spryscale = 0, sprtopscreen = 0, sprbotscreen = 0;
|
||||
fixed_t windowtop = 0, windowbottom = 0;
|
||||
|
||||
void R_DrawMaskedColumn(column_t *column, column_t *brightmap, INT32 baseclip)
|
||||
void R_DrawMaskedColumn(drawcolumndata_t* dc, column_t *column, column_t *brightmap, INT32 baseclip)
|
||||
{
|
||||
INT32 topscreen;
|
||||
INT32 bottomscreen;
|
||||
fixed_t basetexturemid;
|
||||
INT32 topdelta, prevdelta = 0;
|
||||
|
||||
basetexturemid = dc_texturemid;
|
||||
basetexturemid = dc->texturemid;
|
||||
|
||||
R_SetColumnFunc(colfunctype, brightmap != NULL);
|
||||
dc_brightmap = NULL;
|
||||
dc->brightmap = NULL;
|
||||
|
||||
for (; column->topdelta != 0xff ;)
|
||||
{
|
||||
|
|
@ -660,49 +661,53 @@ void R_DrawMaskedColumn(column_t *column, column_t *brightmap, INT32 baseclip)
|
|||
topscreen = sprtopscreen + spryscale*topdelta;
|
||||
bottomscreen = topscreen + spryscale*column->length;
|
||||
|
||||
dc_yl = (topscreen+FRACUNIT-1)>>FRACBITS;
|
||||
dc_yh = (bottomscreen-1)>>FRACBITS;
|
||||
dc->yl = (topscreen+FRACUNIT-1)>>FRACBITS;
|
||||
dc->yh = (bottomscreen-1)>>FRACBITS;
|
||||
|
||||
if (windowtop != INT32_MAX && windowbottom != INT32_MAX)
|
||||
{
|
||||
if (windowtop > topscreen)
|
||||
dc_yl = (windowtop + FRACUNIT - 1)>>FRACBITS;
|
||||
dc->yl = (windowtop + FRACUNIT - 1)>>FRACBITS;
|
||||
if (windowbottom < bottomscreen)
|
||||
dc_yh = (windowbottom - 1)>>FRACBITS;
|
||||
dc->yh = (windowbottom - 1)>>FRACBITS;
|
||||
}
|
||||
|
||||
if (dc_yh >= mfloorclip[dc_x])
|
||||
dc_yh = mfloorclip[dc_x]-1;
|
||||
if (dc_yl <= mceilingclip[dc_x])
|
||||
dc_yl = mceilingclip[dc_x]+1;
|
||||
if (dc->yh >= mfloorclip[dc->x])
|
||||
dc->yh = mfloorclip[dc->x]-1;
|
||||
if (dc->yl <= mceilingclip[dc->x])
|
||||
dc->yl = mceilingclip[dc->x]+1;
|
||||
|
||||
if (dc_yl < 0)
|
||||
dc_yl = 0;
|
||||
if (dc_yh >= vid.height) // dc_yl must be < vid.height, so reduces number of checks in tight loop
|
||||
dc_yh = vid.height - 1;
|
||||
if (dc->yl < 0)
|
||||
dc->yl = 0;
|
||||
if (dc->yh >= vid.height) // dc_yl must be < vid.height, so reduces number of checks in tight loop
|
||||
dc->yh = vid.height - 1;
|
||||
|
||||
if (dc_yh >= baseclip && baseclip != -1)
|
||||
dc_yh = baseclip;
|
||||
if (dc->yh >= baseclip && baseclip != -1)
|
||||
dc->yh = baseclip;
|
||||
|
||||
if (dc_yl <= dc_yh && dc_yh > 0)
|
||||
if (dc->yl <= dc->yh && dc->yh > 0)
|
||||
{
|
||||
dc_source = (UINT8 *)column + 3;
|
||||
dc->source = (UINT8 *)column + 3;
|
||||
if (brightmap != NULL)
|
||||
{
|
||||
dc_brightmap = (UINT8 *)brightmap + 3;
|
||||
dc->brightmap = (UINT8 *)brightmap + 3;
|
||||
}
|
||||
|
||||
dc_texturemid = basetexturemid - (topdelta<<FRACBITS);
|
||||
dc->texturemid = basetexturemid - (topdelta<<FRACBITS);
|
||||
|
||||
// Drawn by R_DrawColumn.
|
||||
// This stuff is a likely cause of the splitscreen water crash bug.
|
||||
// FIXTHIS: Figure out what "something more proper" is and do it.
|
||||
// quick fix... something more proper should be done!!!
|
||||
if (ylookup[dc_yl])
|
||||
colfunc();
|
||||
if (ylookup[dc->yl])
|
||||
{
|
||||
drawcolumndata_t dc_copy = *dc;
|
||||
coldrawfunc_t* colfunccopy = colfunc;
|
||||
colfunccopy(const_cast<drawcolumndata_t*>(&dc_copy));
|
||||
}
|
||||
#ifdef PARANOIA
|
||||
else
|
||||
I_Error("R_DrawMaskedColumn: Invalid ylookup for dc_yl %d", dc_yl);
|
||||
I_Error("R_DrawMaskedColumn: Invalid ylookup for dc_yl %d", dc->yl);
|
||||
#endif
|
||||
}
|
||||
column = (column_t *)((UINT8 *)column + column->length + 4);
|
||||
|
|
@ -712,21 +717,21 @@ void R_DrawMaskedColumn(column_t *column, column_t *brightmap, INT32 baseclip)
|
|||
}
|
||||
}
|
||||
|
||||
dc_texturemid = basetexturemid;
|
||||
dc->texturemid = basetexturemid;
|
||||
}
|
||||
|
||||
INT32 lengthcol; // column->length : for flipped column function pointers and multi-patch on 2sided wall = texture->height
|
||||
|
||||
void R_DrawFlippedMaskedColumn(column_t *column, column_t *brightmap, INT32 baseclip)
|
||||
void R_DrawFlippedMaskedColumn(drawcolumndata_t* dc, column_t *column, column_t *brightmap, INT32 baseclip)
|
||||
{
|
||||
INT32 topscreen;
|
||||
INT32 bottomscreen;
|
||||
fixed_t basetexturemid = dc_texturemid;
|
||||
fixed_t basetexturemid = dc->texturemid;
|
||||
INT32 topdelta, prevdelta = -1;
|
||||
UINT8 *d,*s;
|
||||
|
||||
R_SetColumnFunc(colfunctype, brightmap != NULL);
|
||||
dc_brightmap = NULL;
|
||||
dc->brightmap = NULL;
|
||||
|
||||
for (; column->topdelta != 0xff ;)
|
||||
{
|
||||
|
|
@ -741,53 +746,57 @@ void R_DrawFlippedMaskedColumn(column_t *column, column_t *brightmap, INT32 base
|
|||
bottomscreen = sprbotscreen == INT32_MAX ? topscreen + spryscale*column->length
|
||||
: sprbotscreen + spryscale*column->length;
|
||||
|
||||
dc_yl = (topscreen+FRACUNIT-1)>>FRACBITS;
|
||||
dc_yh = (bottomscreen-1)>>FRACBITS;
|
||||
dc->yl = (topscreen+FRACUNIT-1)>>FRACBITS;
|
||||
dc->yh = (bottomscreen-1)>>FRACBITS;
|
||||
|
||||
if (windowtop != INT32_MAX && windowbottom != INT32_MAX)
|
||||
{
|
||||
if (windowtop > topscreen)
|
||||
dc_yl = (windowtop + FRACUNIT - 1)>>FRACBITS;
|
||||
dc->yl = (windowtop + FRACUNIT - 1)>>FRACBITS;
|
||||
if (windowbottom < bottomscreen)
|
||||
dc_yh = (windowbottom - 1)>>FRACBITS;
|
||||
dc->yh = (windowbottom - 1)>>FRACBITS;
|
||||
}
|
||||
|
||||
if (dc_yh >= mfloorclip[dc_x])
|
||||
dc_yh = mfloorclip[dc_x]-1;
|
||||
if (dc_yl <= mceilingclip[dc_x])
|
||||
dc_yl = mceilingclip[dc_x]+1;
|
||||
if (dc->yh >= mfloorclip[dc->x])
|
||||
dc->yh = mfloorclip[dc->x]-1;
|
||||
if (dc->yl <= mceilingclip[dc->x])
|
||||
dc->yl = mceilingclip[dc->x]+1;
|
||||
|
||||
if (dc_yh >= baseclip && baseclip != -1)
|
||||
dc_yh = baseclip;
|
||||
if (dc->yh >= baseclip && baseclip != -1)
|
||||
dc->yh = baseclip;
|
||||
|
||||
if (dc_yl < 0)
|
||||
dc_yl = 0;
|
||||
if (dc_yh >= vid.height) // dc_yl must be < vid.height, so reduces number of checks in tight loop
|
||||
dc_yh = vid.height - 1;
|
||||
if (dc->yl < 0)
|
||||
dc->yl = 0;
|
||||
if (dc->yh >= vid.height) // dc_yl must be < vid.height, so reduces number of checks in tight loop
|
||||
dc->yh = vid.height - 1;
|
||||
|
||||
if (dc_yl <= dc_yh && dc_yh > 0)
|
||||
if (dc->yl <= dc->yh && dc->yh > 0)
|
||||
{
|
||||
dc_source = static_cast<UINT8*>(ZZ_Alloc(column->length));
|
||||
for (s = (UINT8 *)column+2+column->length, d = dc_source; d < dc_source+column->length; --s)
|
||||
dc->source = static_cast<UINT8*>(ZZ_Alloc(column->length));
|
||||
for (s = (UINT8 *)column+2+column->length, d = dc->source; d < dc->source+column->length; --s)
|
||||
*d++ = *s;
|
||||
|
||||
if (brightmap != NULL)
|
||||
{
|
||||
dc_brightmap = static_cast<UINT8*>(ZZ_Alloc(brightmap->length));
|
||||
for (s = (UINT8 *)brightmap+2+brightmap->length, d = dc_brightmap; d < dc_brightmap+brightmap->length; --s)
|
||||
dc->brightmap = static_cast<UINT8*>(ZZ_Alloc(brightmap->length));
|
||||
for (s = (UINT8 *)brightmap+2+brightmap->length, d = dc->brightmap; d < dc->brightmap+brightmap->length; --s)
|
||||
*d++ = *s;
|
||||
}
|
||||
|
||||
dc_texturemid = basetexturemid - (topdelta<<FRACBITS);
|
||||
dc->texturemid = basetexturemid - (topdelta<<FRACBITS);
|
||||
|
||||
// Still drawn by R_DrawColumn.
|
||||
if (ylookup[dc_yl])
|
||||
colfunc();
|
||||
if (ylookup[dc->yl])
|
||||
{
|
||||
drawcolumndata_t dc_copy = *dc;
|
||||
coldrawfunc_t* colfunccopy = colfunc;
|
||||
colfunccopy(const_cast<drawcolumndata_t*>(&dc_copy));
|
||||
}
|
||||
#ifdef PARANOIA
|
||||
else
|
||||
I_Error("R_DrawMaskedColumn: Invalid ylookup for dc_yl %d", dc_yl);
|
||||
I_Error("R_DrawMaskedColumn: Invalid ylookup for dc_yl %d", dc->yl);
|
||||
#endif
|
||||
Z_Free(dc_source);
|
||||
Z_Free(dc->source);
|
||||
}
|
||||
column = (column_t *)((UINT8 *)column + column->length + 4);
|
||||
if (brightmap != NULL)
|
||||
|
|
@ -796,7 +805,7 @@ void R_DrawFlippedMaskedColumn(column_t *column, column_t *brightmap, INT32 base
|
|||
}
|
||||
}
|
||||
|
||||
dc_texturemid = basetexturemid;
|
||||
dc->texturemid = basetexturemid;
|
||||
}
|
||||
|
||||
static boolean hitlag_is_flashing(mobj_t *thing)
|
||||
|
|
@ -866,7 +875,7 @@ UINT8 *R_GetSpriteTranslation(vissprite_t *vis)
|
|||
static void R_DrawVisSprite(vissprite_t *vis)
|
||||
{
|
||||
column_t *column, *bmcol = NULL;
|
||||
void (*localcolfunc)(column_t *, column_t *, INT32);
|
||||
void (*localcolfunc)(drawcolumndata_t*, column_t *, column_t *, INT32);
|
||||
INT32 texturecolumn;
|
||||
INT32 pwidth;
|
||||
fixed_t frac;
|
||||
|
|
@ -876,6 +885,7 @@ static void R_DrawVisSprite(vissprite_t *vis)
|
|||
INT32 x1, x2;
|
||||
INT64 overflow_test;
|
||||
INT32 baseclip = -1;
|
||||
drawcolumndata_t dc {0};
|
||||
|
||||
if (!patch)
|
||||
return;
|
||||
|
|
@ -917,9 +927,9 @@ static void R_DrawVisSprite(vissprite_t *vis)
|
|||
}
|
||||
|
||||
R_SetColumnFunc(BASEDRAWFUNC, false); // hack: this isn't resetting properly somewhere.
|
||||
dc_colormap = vis->colormap;
|
||||
dc_fullbright = colormaps;
|
||||
dc_translation = R_GetSpriteTranslation(vis);
|
||||
dc.colormap = vis->colormap;
|
||||
dc.fullbright = colormaps;
|
||||
dc.translation = R_GetSpriteTranslation(vis);
|
||||
|
||||
// Hack: Use a special column function for drop shadows that bypasses
|
||||
// invalid memory access crashes caused by R_ProjectDropShadow putting wrong values
|
||||
|
|
@ -927,8 +937,8 @@ static void R_DrawVisSprite(vissprite_t *vis)
|
|||
if (vis->cut & SC_SHADOW)
|
||||
{
|
||||
R_SetColumnFunc(COLDRAWFUNC_DROPSHADOW, false);
|
||||
dc_transmap = vis->transmap;
|
||||
dc_shadowcolor = vis->color;
|
||||
dc.transmap = vis->transmap;
|
||||
dc.shadowcolor = vis->color;
|
||||
}
|
||||
else if (!(vis->cut & SC_PRECIP) &&
|
||||
R_ThingIsFlashing(vis->mobj)) // Bosses "flash"
|
||||
|
|
@ -938,12 +948,12 @@ static void R_DrawVisSprite(vissprite_t *vis)
|
|||
else if (vis->mobj->color && vis->transmap) // Color mapping
|
||||
{
|
||||
R_SetColumnFunc(COLDRAWFUNC_TRANSTRANS, false);
|
||||
dc_transmap = vis->transmap;
|
||||
dc.transmap = vis->transmap;
|
||||
}
|
||||
else if (vis->transmap)
|
||||
{
|
||||
R_SetColumnFunc(COLDRAWFUNC_FUZZY, false);
|
||||
dc_transmap = vis->transmap; //Fab : 29-04-98: translucency table
|
||||
dc.transmap = vis->transmap; //Fab : 29-04-98: translucency table
|
||||
}
|
||||
else if (vis->mobj->color) // translate green skin to another color
|
||||
R_SetColumnFunc(COLDRAWFUNC_TRANS, false);
|
||||
|
|
@ -952,26 +962,26 @@ static void R_DrawVisSprite(vissprite_t *vis)
|
|||
|
||||
if (vis->extra_colormap && !(vis->cut & SC_FULLBRIGHT) && !(vis->renderflags & RF_NOCOLORMAPS))
|
||||
{
|
||||
if (!dc_colormap)
|
||||
dc_colormap = vis->extra_colormap->colormap;
|
||||
if (!dc.colormap)
|
||||
dc.colormap = vis->extra_colormap->colormap;
|
||||
else
|
||||
dc_colormap = &vis->extra_colormap->colormap[dc_colormap - colormaps];
|
||||
dc.colormap = &vis->extra_colormap->colormap[dc.colormap - colormaps];
|
||||
}
|
||||
if (!dc_colormap)
|
||||
dc_colormap = colormaps;
|
||||
if (!dc.colormap)
|
||||
dc.colormap = colormaps;
|
||||
|
||||
dc_lightmap = colormaps;
|
||||
dc.lightmap = colormaps;
|
||||
|
||||
dc_fullbright = colormaps;
|
||||
dc.fullbright = colormaps;
|
||||
|
||||
if (encoremap && !vis->mobj->color && !(vis->mobj->flags & MF_DONTENCOREMAP))
|
||||
{
|
||||
dc_colormap += COLORMAP_REMAPOFFSET;
|
||||
dc_fullbright += COLORMAP_REMAPOFFSET;
|
||||
dc.colormap += COLORMAP_REMAPOFFSET;
|
||||
dc.fullbright += COLORMAP_REMAPOFFSET;
|
||||
}
|
||||
|
||||
dc_texturemid = vis->texturemid;
|
||||
dc_texheight = 0;
|
||||
dc.texturemid = vis->texturemid;
|
||||
dc.texheight = 0;
|
||||
|
||||
frac = vis->startfrac;
|
||||
windowtop = windowbottom = sprbotscreen = INT32_MAX;
|
||||
|
|
@ -991,16 +1001,16 @@ static void R_DrawVisSprite(vissprite_t *vis)
|
|||
vis->xiscale = FixedDiv(vis->xiscale,this_scale);
|
||||
vis->cut = static_cast<spritecut_e>(vis->cut | SC_ISSCALED);
|
||||
}
|
||||
dc_texturemid = FixedDiv(dc_texturemid,this_scale);
|
||||
dc.texturemid = FixedDiv(dc.texturemid,this_scale);
|
||||
}
|
||||
|
||||
spryscale = vis->scale;
|
||||
|
||||
if (!(vis->scalestep))
|
||||
{
|
||||
sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale);
|
||||
sprtopscreen = centeryfrac - FixedMul(dc.texturemid, spryscale);
|
||||
sprtopscreen += vis->shear.tan * vis->shear.offset;
|
||||
dc_iscale = FixedDiv(FRACUNIT, vis->scale);
|
||||
dc.iscale = FixedDiv(FRACUNIT, vis->scale);
|
||||
}
|
||||
|
||||
if (vis->floorclip)
|
||||
|
|
@ -1037,9 +1047,9 @@ static void R_DrawVisSprite(vissprite_t *vis)
|
|||
pwidth = patch->width;
|
||||
|
||||
// Papersprite drawing loop
|
||||
for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, spryscale += scalestep)
|
||||
for (dc.x = vis->x1; dc.x <= vis->x2; dc.x++, spryscale += scalestep)
|
||||
{
|
||||
angle_t angle = ((vis->centerangle + xtoviewangle[viewssnum][dc_x]) >> ANGLETOFINESHIFT) & 0xFFF;
|
||||
angle_t angle = ((vis->centerangle + xtoviewangle[viewssnum][dc.x]) >> ANGLETOFINESHIFT) & 0xFFF;
|
||||
texturecolumn = (vis->paperoffset - FixedMul(FINETANGENT(angle), vis->paperdistance)) / horzscale;
|
||||
|
||||
if (texturecolumn < 0 || texturecolumn >= pwidth)
|
||||
|
|
@ -1048,15 +1058,15 @@ static void R_DrawVisSprite(vissprite_t *vis)
|
|||
if (vis->xiscale < 0) // Flipped sprite
|
||||
texturecolumn = pwidth - 1 - texturecolumn;
|
||||
|
||||
sprtopscreen = (centeryfrac - FixedMul(dc_texturemid, spryscale));
|
||||
dc_iscale = (0xffffffffu / (unsigned)spryscale);
|
||||
sprtopscreen = (centeryfrac - FixedMul(dc.texturemid, spryscale));
|
||||
dc.iscale = (0xffffffffu / (unsigned)spryscale);
|
||||
|
||||
column = (column_t *)((UINT8 *)patch->columns + (patch->columnofs[texturecolumn]));
|
||||
|
||||
if (bmpatch)
|
||||
bmcol = (column_t *)((UINT8 *)bmpatch->columns + (bmpatch->columnofs[texturecolumn]));
|
||||
|
||||
localcolfunc (column, bmcol, baseclip);
|
||||
localcolfunc (&dc, column, bmcol, baseclip);
|
||||
}
|
||||
}
|
||||
else if (vis->cut & SC_SHEAR)
|
||||
|
|
@ -1066,7 +1076,7 @@ static void R_DrawVisSprite(vissprite_t *vis)
|
|||
#endif
|
||||
|
||||
// Vertically sheared sprite
|
||||
for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, frac += vis->xiscale, dc_texturemid -= vis->shear.tan)
|
||||
for (dc.x = vis->x1; dc.x <= vis->x2; dc.x++, frac += vis->xiscale, dc.texturemid -= vis->shear.tan)
|
||||
{
|
||||
texturecolumn = std::clamp(frac >> FRACBITS, 0, patch->width - 1);
|
||||
|
||||
|
|
@ -1074,8 +1084,8 @@ static void R_DrawVisSprite(vissprite_t *vis)
|
|||
if (bmpatch)
|
||||
bmcol = (column_t *)((UINT8 *)bmpatch->columns + (bmpatch->columnofs[texturecolumn]));
|
||||
|
||||
sprtopscreen = (centeryfrac - FixedMul(dc_texturemid, spryscale));
|
||||
localcolfunc (column, bmcol, baseclip);
|
||||
sprtopscreen = (centeryfrac - FixedMul(dc.texturemid, spryscale));
|
||||
localcolfunc (&dc, column, bmcol, baseclip);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -1103,7 +1113,7 @@ static void R_DrawVisSprite(vissprite_t *vis)
|
|||
#endif // RANGECHECK
|
||||
|
||||
// Non-paper drawing loop
|
||||
for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, frac += vis->xiscale, sprtopscreen += vis->shear.tan)
|
||||
for (dc.x = vis->x1; dc.x <= vis->x2; dc.x++, frac += vis->xiscale, sprtopscreen += vis->shear.tan)
|
||||
{
|
||||
texturecolumn = std::clamp(frac >> FRACBITS, 0, patch->width - 1);
|
||||
|
||||
|
|
@ -1112,12 +1122,12 @@ static void R_DrawVisSprite(vissprite_t *vis)
|
|||
if (bmpatch)
|
||||
bmcol = (column_t *)((UINT8 *)bmpatch->columns + (bmpatch->columnofs[texturecolumn]));
|
||||
|
||||
localcolfunc (column, bmcol, baseclip);
|
||||
localcolfunc (&dc, column, bmcol, baseclip);
|
||||
}
|
||||
}
|
||||
|
||||
R_SetColumnFunc(BASEDRAWFUNC, false);
|
||||
dc_hires = 0;
|
||||
dc.hires = 0;
|
||||
|
||||
vis->x1 = x1;
|
||||
vis->x2 = x2;
|
||||
|
|
@ -1132,6 +1142,7 @@ static void R_DrawPrecipitationVisSprite(vissprite_t *vis)
|
|||
patch_t *patch;
|
||||
fixed_t this_scale = vis->thingscale;
|
||||
INT64 overflow_test;
|
||||
drawcolumndata_t dc {0};
|
||||
|
||||
//Fab : R_InitSprites now sets a wad lump number
|
||||
patch = vis->patch;
|
||||
|
|
@ -1146,26 +1157,26 @@ static void R_DrawPrecipitationVisSprite(vissprite_t *vis)
|
|||
if (vis->transmap)
|
||||
{
|
||||
R_SetColumnFunc(COLDRAWFUNC_FUZZY, false);
|
||||
dc_transmap = vis->transmap; //Fab : 29-04-98: translucency table
|
||||
dc.transmap = vis->transmap; //Fab : 29-04-98: translucency table
|
||||
}
|
||||
|
||||
dc_colormap = colormaps;
|
||||
dc_fullbright = colormaps;
|
||||
dc.colormap = colormaps;
|
||||
dc.fullbright = colormaps;
|
||||
if (encoremap)
|
||||
{
|
||||
dc_colormap += COLORMAP_REMAPOFFSET;
|
||||
dc_fullbright += COLORMAP_REMAPOFFSET;
|
||||
dc.colormap += COLORMAP_REMAPOFFSET;
|
||||
dc.fullbright += COLORMAP_REMAPOFFSET;
|
||||
}
|
||||
|
||||
dc_lightmap = colormaps;
|
||||
dc.lightmap = colormaps;
|
||||
|
||||
dc_iscale = FixedDiv(FRACUNIT, vis->scale);
|
||||
dc_texturemid = FixedDiv(vis->texturemid, this_scale);
|
||||
dc_texheight = 0;
|
||||
dc.iscale = FixedDiv(FRACUNIT, vis->scale);
|
||||
dc.texturemid = FixedDiv(vis->texturemid, this_scale);
|
||||
dc.texheight = 0;
|
||||
|
||||
frac = vis->startfrac;
|
||||
spryscale = vis->scale;
|
||||
sprtopscreen = centeryfrac - FixedMul(dc_texturemid,spryscale);
|
||||
sprtopscreen = centeryfrac - FixedMul(dc.texturemid,spryscale);
|
||||
windowtop = windowbottom = sprbotscreen = INT32_MAX;
|
||||
|
||||
if (vis->x1 < 0)
|
||||
|
|
@ -1174,7 +1185,7 @@ static void R_DrawPrecipitationVisSprite(vissprite_t *vis)
|
|||
if (vis->x2 >= vid.width)
|
||||
vis->x2 = vid.width-1;
|
||||
|
||||
for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, frac += vis->xiscale)
|
||||
for (dc.x = vis->x1; dc.x <= vis->x2; dc.x++, frac += vis->xiscale)
|
||||
{
|
||||
texturecolumn = frac>>FRACBITS;
|
||||
|
||||
|
|
@ -1185,7 +1196,7 @@ static void R_DrawPrecipitationVisSprite(vissprite_t *vis)
|
|||
|
||||
column = (column_t *)((UINT8 *)patch->columns + (patch->columnofs[texturecolumn]));
|
||||
|
||||
R_DrawMaskedColumn(column, NULL, -1);
|
||||
R_DrawMaskedColumn(&dc, column, NULL, -1);
|
||||
}
|
||||
|
||||
R_SetColumnFunc(BASEDRAWFUNC, false);
|
||||
|
|
@ -3815,6 +3826,7 @@ boolean R_ThingIsFullDark(mobj_t *thing)
|
|||
//
|
||||
static void R_DrawMaskedList (drawnode_t* head)
|
||||
{
|
||||
ZoneScoped;
|
||||
drawnode_t *r2;
|
||||
drawnode_t *next;
|
||||
|
||||
|
|
@ -3822,8 +3834,9 @@ static void R_DrawMaskedList (drawnode_t* head)
|
|||
{
|
||||
if (r2->plane)
|
||||
{
|
||||
drawspandata_t ds = {0};
|
||||
next = r2->prev;
|
||||
R_DrawSinglePlane(r2->plane);
|
||||
R_DrawSinglePlane(&ds, r2->plane, false);
|
||||
R_DoneWithNode(r2);
|
||||
r2 = next;
|
||||
}
|
||||
|
|
@ -3848,9 +3861,13 @@ static void R_DrawMaskedList (drawnode_t* head)
|
|||
|
||||
// Tails 08-18-2002
|
||||
if (r2->sprite->cut & SC_PRECIP)
|
||||
{
|
||||
R_DrawPrecipitationSprite(r2->sprite);
|
||||
}
|
||||
else if (!r2->sprite->linkdraw)
|
||||
{
|
||||
R_DrawSprite(r2->sprite);
|
||||
}
|
||||
else // unbundle linkdraw
|
||||
{
|
||||
vissprite_t *ds = r2->sprite->linkdraw;
|
||||
|
|
@ -3858,12 +3875,16 @@ static void R_DrawMaskedList (drawnode_t* head)
|
|||
for (;
|
||||
(ds != NULL && r2->sprite->dispoffset > ds->dispoffset);
|
||||
ds = ds->next)
|
||||
{
|
||||
R_DrawSprite(ds);
|
||||
}
|
||||
|
||||
R_DrawSprite(r2->sprite);
|
||||
|
||||
for (; ds != NULL; ds = ds->next)
|
||||
{
|
||||
R_DrawSprite(ds);
|
||||
}
|
||||
}
|
||||
|
||||
R_DoneWithNode(r2);
|
||||
|
|
@ -3874,6 +3895,7 @@ static void R_DrawMaskedList (drawnode_t* head)
|
|||
|
||||
void R_DrawMasked(maskcount_t* masks, INT32 nummasks)
|
||||
{
|
||||
ZoneScoped;
|
||||
drawnode_t *heads; /**< Drawnode lists; as many as number of views/portals. */
|
||||
INT32 i;
|
||||
|
||||
|
|
|
|||
|
|
@ -51,8 +51,8 @@ extern fixed_t windowtop;
|
|||
extern fixed_t windowbottom;
|
||||
extern INT32 lengthcol;
|
||||
|
||||
void R_DrawMaskedColumn(column_t *column, column_t *brightmap, INT32 baseclip);
|
||||
void R_DrawFlippedMaskedColumn(column_t *column, column_t *brightmap, INT32 baseclip);
|
||||
void R_DrawMaskedColumn(drawcolumndata_t* dc, column_t *column, column_t *brightmap, INT32 baseclip);
|
||||
void R_DrawFlippedMaskedColumn(drawcolumndata_t* dc, column_t *column, column_t *brightmap, INT32 baseclip);
|
||||
|
||||
// ----------------
|
||||
// SPRITE RENDERING
|
||||
|
|
|
|||
18
src/screen.c
18
src/screen.c
|
|
@ -48,24 +48,6 @@
|
|||
#define RUSEASM //MSC.NET can't patch itself
|
||||
#endif
|
||||
|
||||
// --------------------------------------------
|
||||
// assembly or c drawer routines for 8bpp/16bpp
|
||||
// --------------------------------------------
|
||||
void (*colfunc)(void);
|
||||
void (*colfuncs[COLDRAWFUNC_MAX])(void);
|
||||
#ifdef USE_COL_SPAN_ASM
|
||||
void (*colfuncs_asm[COLDRAWFUNC_MAX])(void);
|
||||
#endif
|
||||
int colfunctype;
|
||||
|
||||
void (*spanfunc)(void);
|
||||
void (*spanfuncs[SPANDRAWFUNC_MAX])(void);
|
||||
void (*spanfuncs_npo2[SPANDRAWFUNC_MAX])(void);
|
||||
#ifdef USE_COL_SPAN_ASM
|
||||
void (*spanfuncs_asm[SPANDRAWFUNC_MAX])(void);
|
||||
#endif
|
||||
void (*spanfuncs_flat[SPANDRAWFUNC_MAX])(void);
|
||||
|
||||
// ------------------
|
||||
// global video state
|
||||
// ------------------
|
||||
|
|
|
|||
63
src/screen.h
63
src/screen.h
|
|
@ -118,69 +118,6 @@ struct vmode_t
|
|||
#define NUMSPECIALMODES 4
|
||||
extern vmode_t specialmodes[NUMSPECIALMODES];
|
||||
|
||||
// ---------------------------------------------
|
||||
// color mode dependent drawer function pointers
|
||||
// ---------------------------------------------
|
||||
|
||||
#define USE_COL_SPAN_ASM 0
|
||||
|
||||
#define BASEDRAWFUNC 0
|
||||
|
||||
enum
|
||||
{
|
||||
COLDRAWFUNC_BASE = BASEDRAWFUNC,
|
||||
COLDRAWFUNC_FUZZY,
|
||||
COLDRAWFUNC_TRANS,
|
||||
COLDRAWFUNC_SHADE,
|
||||
COLDRAWFUNC_SHADOWED,
|
||||
COLDRAWFUNC_TRANSTRANS,
|
||||
COLDRAWFUNC_TWOSMULTIPATCH,
|
||||
COLDRAWFUNC_TWOSMULTIPATCHTRANS,
|
||||
COLDRAWFUNC_FOG,
|
||||
COLDRAWFUNC_DROPSHADOW,
|
||||
|
||||
COLDRAWFUNC_MAX
|
||||
};
|
||||
|
||||
extern void (*colfunc)(void);
|
||||
extern void (*colfuncs[COLDRAWFUNC_MAX])(void);
|
||||
#ifdef USE_COL_SPAN_ASM
|
||||
extern void (*colfuncs_asm[COLDRAWFUNC_MAX])(void);
|
||||
#endif
|
||||
extern int colfunctype;
|
||||
|
||||
enum
|
||||
{
|
||||
SPANDRAWFUNC_BASE = BASEDRAWFUNC,
|
||||
SPANDRAWFUNC_TRANS,
|
||||
SPANDRAWFUNC_TILTED,
|
||||
SPANDRAWFUNC_TILTEDTRANS,
|
||||
|
||||
SPANDRAWFUNC_SPLAT,
|
||||
SPANDRAWFUNC_TRANSSPLAT,
|
||||
SPANDRAWFUNC_TILTEDSPLAT,
|
||||
|
||||
SPANDRAWFUNC_SPRITE,
|
||||
SPANDRAWFUNC_TRANSSPRITE,
|
||||
SPANDRAWFUNC_TILTEDSPRITE,
|
||||
SPANDRAWFUNC_TILTEDTRANSSPRITE,
|
||||
|
||||
SPANDRAWFUNC_WATER,
|
||||
SPANDRAWFUNC_TILTEDWATER,
|
||||
|
||||
SPANDRAWFUNC_FOG,
|
||||
|
||||
SPANDRAWFUNC_MAX
|
||||
};
|
||||
|
||||
extern void (*spanfunc)(void);
|
||||
extern void (*spanfuncs[SPANDRAWFUNC_MAX])(void);
|
||||
extern void (*spanfuncs_npo2[SPANDRAWFUNC_MAX])(void);
|
||||
#ifdef USE_COL_SPAN_ASM
|
||||
extern void (*spanfuncs_asm[SPANDRAWFUNC_MAX])(void);
|
||||
#endif
|
||||
extern void (*spanfuncs_flat[SPANDRAWFUNC_MAX])(void);
|
||||
|
||||
// -----
|
||||
// CPUID
|
||||
// -----
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ target_sources(SRB2SDL2 PRIVATE
|
|||
rhi_gl3_core_platform.hpp
|
||||
i_threads.c
|
||||
i_net.c
|
||||
i_system.c
|
||||
i_system.cpp
|
||||
i_main.cpp
|
||||
i_video.cpp
|
||||
dosstr.c
|
||||
|
|
@ -92,6 +92,9 @@ endif()
|
|||
target_compile_definitions(SRB2SDL2 PRIVATE -DHAVE_MIXER -DSOUND=SOUND_MIXER)
|
||||
target_compile_definitions(SRB2SDL2 PRIVATE -DDIRECTFULLSCREEN -DHAVE_SDL)
|
||||
|
||||
# NOMUMBLE till WRITE* macros are fixed for C++ or mumble integration is rewritten
|
||||
target_compile_definitions(SRB2SDL2 PRIVATE -DNOMUMBLE)
|
||||
|
||||
#### Installation ####
|
||||
if("${CMAKE_SYSTEM_NAME}" MATCHES Darwin)
|
||||
install(TARGETS SRB2SDL2
|
||||
|
|
|
|||
|
|
@ -23,6 +23,10 @@
|
|||
/// \file
|
||||
/// \brief SRB2 system stuff for SDL
|
||||
|
||||
#include <thread>
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
|
|
@ -168,6 +172,8 @@ static char returnWadPath[256];
|
|||
#include "../d_net.h"
|
||||
#include "../g_game.h"
|
||||
#include "../filesrch.h"
|
||||
#include "../s_sound.h"
|
||||
#include "../core/thread_pool.h"
|
||||
#include "endtxt.h"
|
||||
#include "sdlmain.h"
|
||||
|
||||
|
|
@ -194,6 +200,8 @@ static char returnWadPath[256];
|
|||
#include "../byteptr.h"
|
||||
#endif
|
||||
|
||||
static std::thread::id g_main_thread_id;
|
||||
|
||||
/** \brief SDL info about joysticks
|
||||
*/
|
||||
SDLJoyInfo_t JoyInfo[MAXSPLITSCREENPLAYERS];
|
||||
|
|
@ -350,7 +358,7 @@ static void I_ShowErrorMessageBox(const char *messagefordevelopers, boolean dump
|
|||
// which should fail gracefully if it can't put a message box up
|
||||
// on the target system
|
||||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR,
|
||||
"Dr. Robotnik's Ring Racers "VERSIONSTRING" Error",
|
||||
"Dr. Robotnik's Ring Racers " VERSIONSTRING " Error",
|
||||
finalmessage, NULL);
|
||||
|
||||
// Note that SDL_ShowSimpleMessageBox does *not* require SDL to be
|
||||
|
|
@ -363,66 +371,65 @@ static void I_ShowErrorMessageBox(const char *messagefordevelopers, boolean dump
|
|||
static void I_ReportSignal(int num, int coredumped)
|
||||
{
|
||||
//static char msg[] = "oh no! back to reality!\r\n";
|
||||
const char * sigmsg;
|
||||
char msg[128];
|
||||
auto report = [coredumped](std::string sigmsg)
|
||||
{
|
||||
if (coredumped)
|
||||
{
|
||||
sigmsg += " (core dumped)";
|
||||
}
|
||||
|
||||
I_OutputMsg("\nProcess killed by signal: %s\n\n", sigmsg.c_str());
|
||||
|
||||
I_ShowErrorMessageBox(sigmsg.c_str(),
|
||||
#if defined (UNIXBACKTRACE)
|
||||
true
|
||||
#elif defined (_WIN32)
|
||||
!M_CheckParm("-noexchndl")
|
||||
#else
|
||||
false
|
||||
#endif
|
||||
);
|
||||
};
|
||||
|
||||
switch (num)
|
||||
{
|
||||
// case SIGINT:
|
||||
// sigmsg = "SIGINT - interrupted";
|
||||
// report("SIGINT - interrupted");
|
||||
// break;
|
||||
case SIGILL:
|
||||
sigmsg = "SIGILL - illegal instruction - invalid function image";
|
||||
report("SIGILL - illegal instruction - invalid function image");
|
||||
break;
|
||||
case SIGFPE:
|
||||
sigmsg = "SIGFPE - mathematical exception";
|
||||
report("SIGFPE - mathematical exception");
|
||||
break;
|
||||
case SIGSEGV:
|
||||
sigmsg = "SIGSEGV - segment violation";
|
||||
report("SIGSEGV - segment violation");
|
||||
break;
|
||||
// case SIGTERM:
|
||||
// sigmsg = "SIGTERM - Software termination signal from kill";
|
||||
// report("SIGTERM - Software termination signal from kill");
|
||||
// break;
|
||||
// case SIGBREAK:
|
||||
// sigmsg = "SIGBREAK - Ctrl-Break sequence";
|
||||
// report("SIGBREAK - Ctrl-Break sequence");
|
||||
// break;
|
||||
case SIGABRT:
|
||||
sigmsg = "SIGABRT - abnormal termination triggered by abort call";
|
||||
report("SIGABRT - abnormal termination triggered by abort call");
|
||||
break;
|
||||
default:
|
||||
sprintf(msg,"signal number %d", num);
|
||||
if (coredumped)
|
||||
sigmsg = 0;
|
||||
else
|
||||
sigmsg = msg;
|
||||
report(fmt::format("signal number {}", num));
|
||||
}
|
||||
|
||||
if (coredumped)
|
||||
{
|
||||
if (sigmsg)
|
||||
sprintf(msg, "%s (core dumped)", sigmsg);
|
||||
else
|
||||
strcat(msg, " (core dumped)");
|
||||
|
||||
sigmsg = msg;
|
||||
}
|
||||
|
||||
I_OutputMsg("\nProcess killed by signal: %s\n\n", sigmsg);
|
||||
|
||||
I_ShowErrorMessageBox(sigmsg,
|
||||
#if defined (UNIXBACKTRACE)
|
||||
true
|
||||
#elif defined (_WIN32)
|
||||
!M_CheckParm("-noexchndl")
|
||||
#else
|
||||
false
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
#ifndef NEWSIGNALHANDLER
|
||||
FUNCNORETURN static ATTRNORETURN void signal_handler(INT32 num)
|
||||
{
|
||||
if (g_main_thread_id != std::this_thread::get_id())
|
||||
{
|
||||
// Do not attempt any sort of recovery if this signal triggers off the main thread
|
||||
signal(num, SIG_DFL);
|
||||
raise(num);
|
||||
exit(-2);
|
||||
}
|
||||
|
||||
D_QuitNetGame(); // Fix server freezes
|
||||
CL_AbortDownloadResume();
|
||||
G_DirtyGameData();
|
||||
|
|
@ -567,8 +574,8 @@ static void I_StartupConsole(void)
|
|||
signal(SIGTTIN, SIG_IGN);
|
||||
signal(SIGTTOU, SIG_IGN);
|
||||
|
||||
consolevent = !M_CheckParm("-noconsole");
|
||||
framebuffer = M_CheckParm("-framebuffer");
|
||||
consolevent = static_cast<SDL_bool>(!M_CheckParm("-noconsole"));
|
||||
framebuffer = static_cast<SDL_bool>(M_CheckParm("-framebuffer"));
|
||||
|
||||
if (framebuffer)
|
||||
consolevent = SDL_FALSE;
|
||||
|
|
@ -608,7 +615,7 @@ static void I_StartupConsole(void)
|
|||
void I_GetConsoleEvents(void)
|
||||
{
|
||||
// we use this when sending back commands
|
||||
event_t ev = {0};
|
||||
event_t ev = {};
|
||||
char key = 0;
|
||||
ssize_t d;
|
||||
|
||||
|
|
@ -781,12 +788,12 @@ void I_GetConsoleEvents(void){}
|
|||
static inline void I_StartupConsole(void)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
consolevent = !M_CheckParm("-noconsole");
|
||||
consolevent = M_CheckParm("-noconsole") > 0 ? SDL_FALSE : SDL_TRUE;
|
||||
#else
|
||||
consolevent = M_CheckParm("-console");
|
||||
consolevent = M_CheckParm("-console") > 0 ? SDL_TRUE : SDL_FALSE;
|
||||
#endif
|
||||
|
||||
framebuffer = M_CheckParm("-framebuffer");
|
||||
framebuffer = M_CheckParm("-framebuffer") > 0 ? SDL_TRUE : SDL_FALSE;
|
||||
|
||||
if (framebuffer)
|
||||
consolevent = SDL_FALSE;
|
||||
|
|
@ -799,6 +806,8 @@ static inline void I_ShutdownConsole(void){}
|
|||
//
|
||||
static void I_RegisterSignals (void)
|
||||
{
|
||||
g_main_thread_id = std::this_thread::get_id();
|
||||
|
||||
#ifdef SIGINT
|
||||
signal(SIGINT , quit_handler);
|
||||
#endif
|
||||
|
|
@ -910,7 +919,7 @@ void I_OutputMsg(const char *fmt, ...)
|
|||
return;
|
||||
}
|
||||
|
||||
ReadConsoleOutputCharacter(co, oldLines, oldLength, coordNextWrite, &bytesWritten);
|
||||
ReadConsoleOutputCharacter(co, (LPSTR)oldLines, oldLength, coordNextWrite, &bytesWritten);
|
||||
|
||||
// Move to where we what to print - which is where we would've been,
|
||||
// had console input not been in the way,
|
||||
|
|
@ -1251,7 +1260,8 @@ const char *I_GetJoyName(INT32 joyindex)
|
|||
tempname = SDL_JoystickNameForIndex(joyindex);
|
||||
if (tempname)
|
||||
{
|
||||
strncpy(joyname, tempname, 255);
|
||||
strncpy(joyname, tempname, 254);
|
||||
joyname[254] = 0;
|
||||
}
|
||||
|
||||
return joyname;
|
||||
|
|
@ -1267,7 +1277,7 @@ const char *I_GetJoyName(INT32 joyindex)
|
|||
#define DEG2RAD (0.017453292519943295769236907684883l) // TAU/360 or PI/180
|
||||
#define MUMBLEUNIT (64.0f) // FRACUNITS in a Meter
|
||||
|
||||
static struct {
|
||||
static struct mumble_s {
|
||||
#ifdef WINMUMBLE
|
||||
UINT32 uiVersion;
|
||||
DWORD uiTick;
|
||||
|
|
@ -1300,7 +1310,7 @@ static void I_SetupMumble(void)
|
|||
if (!hMap)
|
||||
return;
|
||||
|
||||
mumble = MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(*mumble));
|
||||
mumble = static_cast<mumble_s*>(MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(*mumble)));
|
||||
if (!mumble)
|
||||
CloseHandle(hMap);
|
||||
#elif defined (HAVE_SHM)
|
||||
|
|
@ -1584,16 +1594,18 @@ INT32 I_StartupSystem(void)
|
|||
SDL_version SDLlinked;
|
||||
SDL_VERSION(&SDLcompiled)
|
||||
SDL_GetVersion(&SDLlinked);
|
||||
#ifdef HAVE_THREADS
|
||||
I_start_threads();
|
||||
I_AddExitFunc(I_stop_threads);
|
||||
#endif
|
||||
I_StartupConsole();
|
||||
#ifdef NEWSIGNALHANDLER
|
||||
// This is useful when debugging. It lets GDB attach to
|
||||
// the correct process easily.
|
||||
if (!M_CheckParm("-nofork"))
|
||||
I_Fork();
|
||||
#endif
|
||||
#ifdef HAVE_THREADS
|
||||
I_start_threads();
|
||||
I_AddExitFunc(I_stop_threads);
|
||||
I_ThreadPoolInit();
|
||||
I_AddExitFunc(I_ThreadPoolShutdown);
|
||||
#endif
|
||||
I_RegisterSignals();
|
||||
I_OutputMsg("Compiled for SDL version: %d.%d.%d\n",
|
||||
|
|
@ -1692,6 +1704,12 @@ void I_Error(const char *error, ...)
|
|||
va_list argptr;
|
||||
char buffer[8192];
|
||||
|
||||
if (std::this_thread::get_id() != g_main_thread_id)
|
||||
{
|
||||
// Do not attempt a graceful shutdown. Errors off the main thread are unresolvable.
|
||||
exit(-2);
|
||||
}
|
||||
|
||||
// recursive error detecting
|
||||
if (shutdowning)
|
||||
{
|
||||
|
|
@ -1727,7 +1745,7 @@ void I_Error(const char *error, ...)
|
|||
// on the target system
|
||||
if (!M_CheckParm("-dedicated"))
|
||||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR,
|
||||
"Dr. Robotnik's Ring Racers "VERSIONSTRING" Recursive Error",
|
||||
"Dr. Robotnik's Ring Racers " VERSIONSTRING " Recursive Error",
|
||||
buffer, NULL);
|
||||
|
||||
W_Shutdown();
|
||||
|
|
@ -2072,7 +2090,7 @@ const char *I_ClipboardPaste(void)
|
|||
*/
|
||||
static boolean isWadPathOk(const char *path)
|
||||
{
|
||||
char *wad3path = malloc(256);
|
||||
char *wad3path = static_cast<char*>(malloc(256));
|
||||
|
||||
if (!wad3path)
|
||||
return false;
|
||||
|
|
@ -2172,43 +2190,43 @@ static const char *locateWad(void)
|
|||
|
||||
// examine default dirs
|
||||
#ifdef DEFAULTWADLOCATION1
|
||||
I_OutputMsg(","DEFAULTWADLOCATION1);
|
||||
I_OutputMsg("," DEFAULTWADLOCATION1);
|
||||
strcpy(returnWadPath, DEFAULTWADLOCATION1);
|
||||
if (isWadPathOk(returnWadPath))
|
||||
return returnWadPath;
|
||||
#endif
|
||||
#ifdef DEFAULTWADLOCATION2
|
||||
I_OutputMsg(","DEFAULTWADLOCATION2);
|
||||
I_OutputMsg("," DEFAULTWADLOCATION2);
|
||||
strcpy(returnWadPath, DEFAULTWADLOCATION2);
|
||||
if (isWadPathOk(returnWadPath))
|
||||
return returnWadPath;
|
||||
#endif
|
||||
#ifdef DEFAULTWADLOCATION3
|
||||
I_OutputMsg(","DEFAULTWADLOCATION3);
|
||||
I_OutputMsg("," DEFAULTWADLOCATION3);
|
||||
strcpy(returnWadPath, DEFAULTWADLOCATION3);
|
||||
if (isWadPathOk(returnWadPath))
|
||||
return returnWadPath;
|
||||
#endif
|
||||
#ifdef DEFAULTWADLOCATION4
|
||||
I_OutputMsg(","DEFAULTWADLOCATION4);
|
||||
I_OutputMsg("," DEFAULTWADLOCATION4);
|
||||
strcpy(returnWadPath, DEFAULTWADLOCATION4);
|
||||
if (isWadPathOk(returnWadPath))
|
||||
return returnWadPath;
|
||||
#endif
|
||||
#ifdef DEFAULTWADLOCATION5
|
||||
I_OutputMsg(","DEFAULTWADLOCATION5);
|
||||
I_OutputMsg("," DEFAULTWADLOCATION5);
|
||||
strcpy(returnWadPath, DEFAULTWADLOCATION5);
|
||||
if (isWadPathOk(returnWadPath))
|
||||
return returnWadPath;
|
||||
#endif
|
||||
#ifdef DEFAULTWADLOCATION6
|
||||
I_OutputMsg(","DEFAULTWADLOCATION6);
|
||||
I_OutputMsg("," DEFAULTWADLOCATION6);
|
||||
strcpy(returnWadPath, DEFAULTWADLOCATION6);
|
||||
if (isWadPathOk(returnWadPath))
|
||||
return returnWadPath;
|
||||
#endif
|
||||
#ifdef DEFAULTWADLOCATION7
|
||||
I_OutputMsg(","DEFAULTWADLOCATION7);
|
||||
I_OutputMsg("," DEFAULTWADLOCATION7);
|
||||
strcpy(returnWadPath, DEFAULTWADLOCATION7);
|
||||
if (isWadPathOk(returnWadPath))
|
||||
return returnWadPath;
|
||||
|
|
@ -2225,21 +2243,21 @@ static const char *locateWad(void)
|
|||
#endif
|
||||
#ifdef DEFAULTSEARCHPATH1
|
||||
// find in /usr/local
|
||||
I_OutputMsg(", in:"DEFAULTSEARCHPATH1);
|
||||
I_OutputMsg(", in:" DEFAULTSEARCHPATH1);
|
||||
WadPath = searchWad(DEFAULTSEARCHPATH1);
|
||||
if (WadPath)
|
||||
return WadPath;
|
||||
#endif
|
||||
#ifdef DEFAULTSEARCHPATH2
|
||||
// find in /usr/games
|
||||
I_OutputMsg(", in:"DEFAULTSEARCHPATH2);
|
||||
I_OutputMsg(", in:" DEFAULTSEARCHPATH2);
|
||||
WadPath = searchWad(DEFAULTSEARCHPATH2);
|
||||
if (WadPath)
|
||||
return WadPath;
|
||||
#endif
|
||||
#ifdef DEFAULTSEARCHPATH3
|
||||
// find in ???
|
||||
I_OutputMsg(", in:"DEFAULTSEARCHPATH3);
|
||||
I_OutputMsg(", in:" DEFAULTSEARCHPATH3);
|
||||
WadPath = searchWad(DEFAULTSEARCHPATH3);
|
||||
if (WadPath)
|
||||
return WadPath;
|
||||
|
|
@ -2283,7 +2301,7 @@ const char *I_LocateWad(void)
|
|||
static long get_entry(const char* name, const char* buf)
|
||||
{
|
||||
long val;
|
||||
char* hit = strstr(buf, name);
|
||||
char* hit = strstr(const_cast<char*>(buf), name);
|
||||
if (hit == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -1,5 +1,15 @@
|
|||
#ifndef __MAC_RESOURCES_H__
|
||||
#define __MAC_RESOURCES_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
void OSX_GetResourcesPath(char * buffer);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -386,9 +386,6 @@ TYPEDEF (mprecipsecnode_t);
|
|||
TYPEDEF (lightmap_t);
|
||||
TYPEDEF (seg_t);
|
||||
|
||||
// r_draw.h
|
||||
TYPEDEF (floatv3_t);
|
||||
|
||||
// r_fps.h
|
||||
TYPEDEF (viewvars_t);
|
||||
TYPEDEF (interpmobjstate_t);
|
||||
|
|
|
|||
|
|
@ -156,6 +156,7 @@ void Z_Free2(void *ptr, const char *file, INT32 line)
|
|||
#endif
|
||||
block->prev->next = block->next;
|
||||
block->next->prev = block->prev;
|
||||
TracyCFree(block);
|
||||
free(block);
|
||||
}
|
||||
|
||||
|
|
@ -350,6 +351,7 @@ void *Z_Realloc2(void *ptr, size_t size, INT32 tag, void *user, INT32 alignbits,
|
|||
void Z_FreeTags(INT32 lowtag, INT32 hightag)
|
||||
{
|
||||
memblock_t *block, *next;
|
||||
TracyCZone(__zone, true);
|
||||
|
||||
Z_CheckHeap(420);
|
||||
for (block = head.next; block != &head; block = next)
|
||||
|
|
@ -358,6 +360,8 @@ void Z_FreeTags(INT32 lowtag, INT32 hightag)
|
|||
if (block->tag >= lowtag && block->tag <= hightag)
|
||||
Z_Free(MEMORY(block));
|
||||
}
|
||||
|
||||
TracyCZoneEnd(__zone);
|
||||
}
|
||||
|
||||
/** Iterates through all memory for a given set of tags.
|
||||
|
|
@ -369,6 +373,7 @@ void Z_FreeTags(INT32 lowtag, INT32 hightag)
|
|||
void Z_IterateTags(INT32 lowtag, INT32 hightag, boolean (*iterfunc)(void *))
|
||||
{
|
||||
memblock_t *block, *next;
|
||||
TracyCZone(__zone, true);
|
||||
|
||||
if (!iterfunc)
|
||||
I_Error("Z_IterateTags: no iterator function was given");
|
||||
|
|
@ -385,6 +390,8 @@ void Z_IterateTags(INT32 lowtag, INT32 hightag, boolean (*iterfunc)(void *))
|
|||
Z_Free(mem);
|
||||
}
|
||||
}
|
||||
|
||||
TracyCZoneEnd(__zone);
|
||||
}
|
||||
|
||||
// -----------------
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue