diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 515e1ce1d..968667ef8 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -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 diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index f4ee13e1f..a5d0b521a 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -1,3 +1,8 @@ target_sources(SRB2SDL2 PRIVATE + memory.cpp + memory.h + spmc_queue.hpp static_vec.hpp + thread_pool.cpp + thread_pool.h ) diff --git a/src/core/memory.cpp b/src/core/memory.cpp new file mode 100644 index 000000000..7aebb4768 --- /dev/null +++ b/src/core/memory.cpp @@ -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 +#include + +#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(); +} diff --git a/src/core/memory.h b/src/core/memory.h new file mode 100644 index 000000000..a1b479b21 --- /dev/null +++ b/src/core/memory.h @@ -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 + +#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__ diff --git a/src/core/spmc_queue.hpp b/src/core/spmc_queue.hpp new file mode 100644 index 000000000..9441422d9 --- /dev/null +++ b/src/core/spmc_queue.hpp @@ -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 +#include +#include +#include +#include + +#include + +#include "../cxxutil.hpp" + +namespace srb2 +{ + +template +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(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 _buff; + }; + + alignas(64) std::atomic bottom_; + alignas(64) std::atomic top_; + alignas(64) std::atomic buffer_; + + std::vector> 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(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 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 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__ diff --git a/src/core/thread_pool.cpp b/src/core/thread_pool.cpp new file mode 100644 index 000000000..30dbd5dad --- /dev/null +++ b/src/core/thread_pool.cpp @@ -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 +#include +#include +#include +#include +#include + +#include +#include + +#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> pool_alive, + std::shared_ptr worker_ready_mutex, + std::shared_ptr worker_ready_condvar, + std::shared_ptr my_wq, + std::vector> 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 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 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>(true); + + for (size_t i = 0; i < threads; i++) + { + std::shared_ptr wsq = std::make_shared(2048); + work_queues_.push_back(wsq); + + std::shared_ptr mutex = std::make_shared(); + worker_ready_mutexes_.push_back(std::move(mutex)); + std::shared_ptr condvar = std::make_shared(); + worker_ready_condvars_.push_back(std::move(condvar)); + } + + for (size_t i = 0; i < threads; i++) + { + std::shared_ptr my_queue = work_queues_[i]; + std::vector> 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 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 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 srb2::g_main_threadpool; + +void I_ThreadPoolInit(void) +{ + SRB2_ASSERT(g_main_threadpool == nullptr); + size_t thread_count = std::min(static_cast(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(); + } + else + { + g_main_threadpool = std::make_unique(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(); +} diff --git a/src/core/thread_pool.h b/src/core/thread_pool.h new file mode 100644 index 000000000..f6d8241ec --- /dev/null +++ b/src/core/thread_pool.h @@ -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 + +#ifdef __cplusplus + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "spmc_queue.hpp" + +namespace srb2 +{ + +class ThreadPool +{ +public: + struct Task + { + void (*thunk)(void*); + void (*deleter)(void*); + std::shared_ptr> pseudosema; + std::array>)> raw; + }; + + using Queue = SpMcQueue; + + class Sema + { + std::shared_ptr> pseudosema_; + + explicit Sema(std::shared_ptr> sema) : pseudosema_(sema) {} + + friend class ThreadPool; + public: + Sema() = default; + }; + +private: + std::shared_ptr> pool_alive_; + std::vector> worker_ready_mutexes_; + std::vector> worker_ready_condvars_; + std::vector> work_queues_; + std::vector threads_; + size_t next_queue_index_ = 0; + std::shared_ptr> 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 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 g_main_threadpool; + +template +void callable_caller(F* f) +{ + (*f)(); +} + +template +void callable_destroyer(F* f) +{ + f->~F(); +} + +template +void ThreadPool::schedule(T&& thunk) +{ + static_assert(sizeof(T) <= sizeof(std::declval().raw)); + + if (immediate_mode_) + { + (thunk)(); + return; + } + + if (sema_begun_) + { + if (cur_sema_ == nullptr) + { + cur_sema_ = std::make_shared>(0); + } + cur_sema_->fetch_add(1, std::memory_order_relaxed); + } + + size_t qi = next_queue_index_; + + { + std::shared_ptr q = work_queues_[qi]; + Task task; + task.thunk = reinterpret_cast(callable_caller); + task.deleter = reinterpret_cast(callable_destroyer); + task.pseudosema = cur_sema_; + new (reinterpret_cast(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__ diff --git a/src/d_main.cpp b/src/d_main.cpp index 8b258c7bc..732a4e82b 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -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()); diff --git a/src/deh_soc.c b/src/deh_soc.c index f91429ab2..9e32abb83 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -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") diff --git a/src/discord.c b/src/discord.c index df8f3cd85..516172a67 100644 --- a/src/discord.c +++ b/src/discord.c @@ -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" diff --git a/src/k_terrain.c b/src/k_terrain.c index f9114f75c..36edb5261 100644 --- a/src/k_terrain.c +++ b/src/k_terrain.c @@ -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; diff --git a/src/menus/play-online-join-ip.c b/src/menus/play-online-join-ip.c index 33d775f60..526665a9b 100644 --- a/src/menus/play-online-join-ip.c +++ b/src/menus/play-online-join-ip.c @@ -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[] = { diff --git a/src/r_defs.h b/src/r_defs.h index d22398f79..8fae73aec 100644 --- a/src/r_defs.h +++ b/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 diff --git a/src/r_draw.c b/src/r_draw.c index c335755f2..d07323752 100644 --- a/src/r_draw.c +++ b/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 // ========================================================================= diff --git a/src/r_draw.h b/src/r_draw.h index 62073a2fe..3cc1381e8 100644 --- a/src/r_draw.h +++ b/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); diff --git a/src/r_draw8.c b/src/r_draw8.c index e83eea875..8840106e9 100644 --- a/src/r_draw8.c +++ b/src/r_draw8.c @@ -11,6 +11,8 @@ /// \brief 8bpp span/column drawer functions /// \note no includes because this is included as part of r_draw.c +#include + // ========================================================================== // COLUMNS // ========================================================================== @@ -22,20 +24,20 @@ /** \brief The R_DrawColumn_8 function Experiment to make software go faster. Taken from the Boom source */ -void R_DrawColumn_8(void) +void R_DrawColumn_8(drawcolumndata_t* dc) { INT32 count; register UINT8 *dest; register fixed_t frac; fixed_t fracstep; - 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 @@ -44,24 +46,24 @@ void R_DrawColumn_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++; // Determine scaling, which is the only mapping to be done. - fracstep = dc_iscale; + fracstep = dc->iscale; //frac = dc_texturemid + (dc_yl - centery)*fracstep; - frac = (dc_texturemid + FixedMul((dc_yl << FRACBITS) - centeryfrac, fracstep))*(!dc_hires); + frac = (dc->texturemid + FixedMul((dc->yl << FRACBITS) - centeryfrac, fracstep))*(!dc->hires); // Inner loop that does the actual texture mapping, e.g. a DDA-like scaling. // This is as fast as it gets. { - register const UINT8 *source = dc_source; - register const UINT8 *brightmap = dc_brightmap; - register const lighttable_t *colormap = dc_colormap; - register const lighttable_t *fullbright = dc_fullbright; - register INT32 heightmask = dc_texheight-1; - if (dc_texheight & heightmask) // not a power of 2 -- killough + register const UINT8 *source = dc->source; + register const UINT8 *brightmap = dc->brightmap; + register const lighttable_t *colormap = dc->colormap; + register const lighttable_t *fullbright = dc->fullbright; + register INT32 heightmask = dc->texheight-1; + if (dc->texheight & heightmask) // not a power of 2 -- killough { heightmask++; heightmask <<= FRACBITS; @@ -141,20 +143,20 @@ void R_DrawColumn_8(void) } } -void R_Draw2sMultiPatchColumn_8(void) +void R_Draw2sMultiPatchColumn_8(drawcolumndata_t* dc) { INT32 count; register UINT8 *dest; register fixed_t frac; fixed_t fracstep; - 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 @@ -163,25 +165,25 @@ void R_Draw2sMultiPatchColumn_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++; // Determine scaling, which is the only mapping to be done. - fracstep = dc_iscale; + fracstep = dc->iscale; //frac = dc_texturemid + (dc_yl - centery)*fracstep; - frac = (dc_texturemid + FixedMul((dc_yl << FRACBITS) - centeryfrac, fracstep))*(!dc_hires); + frac = (dc->texturemid + FixedMul((dc->yl << FRACBITS) - centeryfrac, fracstep))*(!dc->hires); // Inner loop that does the actual texture mapping, e.g. a DDA-like scaling. // This is as fast as it gets. { - register const UINT8 *source = dc_source; - register const UINT8 *brightmap = dc_brightmap; - register const lighttable_t *colormap = dc_colormap; - register const lighttable_t *fullbright = dc_fullbright; - register INT32 heightmask = dc_texheight-1; + register const UINT8 *source = dc->source; + register const UINT8 *brightmap = dc->brightmap; + register const lighttable_t *colormap = dc->colormap; + register const lighttable_t *fullbright = dc->fullbright; + register INT32 heightmask = dc->texheight-1; register UINT8 val; - if (dc_texheight & heightmask) // not a power of 2 -- killough + if (dc->texheight & heightmask) // not a power of 2 -- killough { heightmask++; heightmask <<= FRACBITS; @@ -278,20 +280,20 @@ void R_Draw2sMultiPatchColumn_8(void) } } -void R_Draw2sMultiPatchTranslucentColumn_8(void) +void R_Draw2sMultiPatchTranslucentColumn_8(drawcolumndata_t* dc) { INT32 count; register UINT8 *dest; register fixed_t frac; fixed_t fracstep; - 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 @@ -300,26 +302,26 @@ void R_Draw2sMultiPatchTranslucentColumn_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++; // Determine scaling, which is the only mapping to be done. - fracstep = dc_iscale; + fracstep = dc->iscale; //frac = dc_texturemid + (dc_yl - centery)*fracstep; - frac = (dc_texturemid + FixedMul((dc_yl << FRACBITS) - centeryfrac, fracstep))*(!dc_hires); + frac = (dc->texturemid + FixedMul((dc->yl << FRACBITS) - centeryfrac, fracstep))*(!dc->hires); // Inner loop that does the actual texture mapping, e.g. a DDA-like scaling. // This is as fast as it gets. { - register const UINT8 *source = dc_source; - register const UINT8 *brightmap = dc_brightmap; - register const UINT8 *transmap = dc_transmap; - register const lighttable_t *colormap = dc_colormap; - register const lighttable_t *fullbright = dc_fullbright; - register INT32 heightmask = dc_texheight-1; + register const UINT8 *source = dc->source; + register const UINT8 *brightmap = dc->brightmap; + register const UINT8 *transmap = dc->transmap; + register const lighttable_t *colormap = dc->colormap; + register const lighttable_t *fullbright = dc->fullbright; + register INT32 heightmask = dc->texheight-1; register UINT8 val; - if (dc_texheight & heightmask) // not a power of 2 -- killough + if (dc->texheight & heightmask) // not a power of 2 -- killough { heightmask++; heightmask <<= FRACBITS; @@ -418,38 +420,38 @@ void R_Draw2sMultiPatchTranslucentColumn_8(void) /** \brief The R_DrawShadeColumn_8 function Experiment to make software go faster. Taken from the Boom source */ -void R_DrawShadeColumn_8(void) +void R_DrawShadeColumn_8(drawcolumndata_t* dc) { register INT32 count; register UINT8 *dest; register fixed_t frac, fracstep; // check out coords for src* - if ((dc_yl < 0) || (dc_x >= vid.width)) + if ((dc->yl < 0) || (dc->x >= vid.width)) return; - count = dc_yh - dc_yl; + count = dc->yh - dc->yl; if (count < 0) return; #ifdef RANGECHECK - if ((unsigned)dc_x >= (unsigned)vid.width || dc_yl < 0 || dc_yh >= vid.height) - I_Error("R_DrawShadeColumn_8: %d to %d at %d", dc_yl, dc_yh, dc_x); + if ((unsigned)dc->x >= (unsigned)vid.width || dc->yl < 0 || dc->yh >= vid.height) + I_Error("R_DrawShadeColumn_8: %d to %d at %d", dc->yl, dc->yh, dc->x); #endif // FIXME. As above. //dest = ylookup[dc_yl] + columnofs[dc_x]; - dest = &topleft[dc_yl*vid.width + dc_x]; + dest = &topleft[dc->yl * vid.width + dc->x]; // Looks familiar. - fracstep = dc_iscale; + fracstep = dc->iscale; //frac = dc_texturemid + (dc_yl - centery)*fracstep; - frac = (dc_texturemid + FixedMul((dc_yl << FRACBITS) - centeryfrac, fracstep))*(!dc_hires); + frac = (dc->texturemid + FixedMul((dc->yl << FRACBITS) - centeryfrac, fracstep))*(!dc->hires); // Here we do an additional index re-mapping. do { - *dest = colormaps[(dc_source[frac>>FRACBITS] <<8) + (*dest)]; + *dest = colormaps[(dc->source[frac>>FRACBITS] <<8) + (*dest)]; dest += vid.width; frac += fracstep; } while (count--); @@ -460,41 +462,41 @@ void R_DrawShadeColumn_8(void) a lot in 640x480 with big sprites (bfg on all screen, or transparent walls on fullscreen) */ -void R_DrawTranslucentColumn_8(void) +void R_DrawTranslucentColumn_8(drawcolumndata_t* dc) { register INT32 count; register UINT8 *dest; register fixed_t frac, fracstep; - count = dc_yh - dc_yl + 1; + count = dc->yh - dc->yl + 1; 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) - I_Error("R_DrawTranslucentColumn_8: %d to %d at %d", dc_yl, dc_yh, dc_x); + if ((unsigned)dc->x >= (unsigned)vid.width || dc->yl < 0 || dc->yh >= vid.height) + I_Error("R_DrawTranslucentColumn_8: %d to %d at %d", dc->yl, dc->yh, dc->x); #endif // FIXME. As above. //dest = ylookup[dc_yl] + columnofs[dc_x]; - dest = &topleft[dc_yl*vid.width + dc_x]; + dest = &topleft[dc->yl * vid.width + dc->x]; // Looks familiar. - fracstep = dc_iscale; + fracstep = dc->iscale; //frac = dc_texturemid + (dc_yl - centery)*fracstep; - frac = (dc_texturemid + FixedMul((dc_yl << FRACBITS) - centeryfrac, fracstep))*(!dc_hires); + frac = (dc->texturemid + FixedMul((dc->yl << FRACBITS) - centeryfrac, fracstep))*(!dc->hires); // Inner loop that does the actual texture mapping, e.g. a DDA-like scaling. // This is as fast as it gets. { - register const UINT8 *source = dc_source; - register const UINT8 *brightmap = dc_brightmap; - register const UINT8 *transmap = dc_transmap; - register const lighttable_t *colormap = dc_colormap; - register const lighttable_t *fullbright = dc_fullbright; - register INT32 heightmask = dc_texheight - 1; - if (dc_texheight & heightmask) + register const UINT8 *source = dc->source; + register const UINT8 *brightmap = dc->brightmap; + register const UINT8 *transmap = dc->transmap; + register const lighttable_t *colormap = dc->colormap; + register const lighttable_t *fullbright = dc->fullbright; + register INT32 heightmask = dc->texheight - 1; + if (dc->texheight & heightmask) { heightmask++; heightmask <<= FRACBITS; @@ -571,20 +573,20 @@ void R_DrawTranslucentColumn_8(void) // dc_texturemid and dc_iscale get wrong values for drop shadows, however those are not strictly // needed for the current design of the shadows, so this function bypasses the issue // by not using those variables at all. -void R_DrawDropShadowColumn_8(void) +void R_DrawDropShadowColumn_8(drawcolumndata_t* dc) { register INT32 count; register UINT8 *dest; - count = dc_yh - dc_yl + 1; + count = dc->yh - dc->yl + 1; if (count <= 0) // Zero length, column does not exceed a pixel. return; - dest = &topleft[dc_yl*vid.width + dc_x]; + dest = &topleft[dc->yl*vid.width + dc->x]; { - register const UINT8 *transmap_offset = dc_transmap + (dc_colormap[dc_shadowcolor] << 8); + register const UINT8 *transmap_offset = dc->transmap + (dc->shadowcolor << 8); while ((count -= 2) >= 0) { *dest = *(transmap_offset + (*dest)); @@ -601,31 +603,31 @@ void R_DrawDropShadowColumn_8(void) Spiffy function. Not only does it colormap a sprite, but does translucency as well. Uber-kudos to Cyan Helkaraxe */ -void R_DrawTranslatedTranslucentColumn_8(void) +void R_DrawTranslatedTranslucentColumn_8(drawcolumndata_t* dc) { register INT32 count; register UINT8 *dest; register fixed_t frac, fracstep; - count = dc_yh - dc_yl + 1; + count = dc->yh - dc->yl + 1; if (count <= 0) // Zero length, column does not exceed a pixel. return; // FIXME. As above. //dest = ylookup[dc_yl] + columnofs[dc_x]; - dest = &topleft[dc_yl*vid.width + dc_x]; + dest = &topleft[dc->yl * vid.width + dc->x]; // Looks familiar. - fracstep = dc_iscale; + fracstep = dc->iscale; //frac = dc_texturemid + (dc_yl - centery)*fracstep; - frac = (dc_texturemid + FixedMul((dc_yl << FRACBITS) - centeryfrac, fracstep))*(!dc_hires); + frac = (dc->texturemid + FixedMul((dc->yl << FRACBITS) - centeryfrac, fracstep))*(!dc->hires); // Inner loop that does the actual texture mapping, e.g. a DDA-like scaling. // This is as fast as it gets. { - register INT32 heightmask = dc_texheight - 1; - if (dc_texheight & heightmask) + register INT32 heightmask = dc->texheight - 1; + if (dc->texheight & heightmask) { heightmask++; heightmask <<= FRACBITS; @@ -643,13 +645,13 @@ void R_DrawTranslatedTranslucentColumn_8(void) // using a lighting/special effects LUT. // heightmask is the Tutti-Frutti fix - if (dc_brightmap != NULL && dc_brightmap[frac>>FRACBITS] == BRIGHTPIXEL) + if (dc->brightmap != NULL && dc->brightmap[frac>>FRACBITS] == BRIGHTPIXEL) { - *dest = *(dc_transmap + (dc_fullbright[dc_translation[dc_source[frac>>FRACBITS]]]<<8) + (*dest)); + *dest = *(dc->transmap + (dc->fullbright[dc->translation[dc->source[frac>>FRACBITS]]]<<8) + (*dest)); } else { - *dest = *(dc_transmap + (dc_colormap[dc_translation[dc_source[frac>>FRACBITS]]]<<8) + (*dest)); + *dest = *(dc->transmap + (dc->colormap[dc->translation[dc->source[frac>>FRACBITS]]]<<8) + (*dest)); } dest += vid.width; @@ -662,25 +664,25 @@ void R_DrawTranslatedTranslucentColumn_8(void) { while ((count -= 2) >= 0) // texture height is a power of 2 { - if (dc_brightmap != NULL && dc_brightmap[(frac>>FRACBITS)&heightmask] == BRIGHTPIXEL) + if (dc->brightmap != NULL && dc->brightmap[(frac>>FRACBITS)&heightmask] == BRIGHTPIXEL) { - *dest = *(dc_transmap + (dc_fullbright[dc_translation[dc_source[(frac>>FRACBITS)&heightmask]]]<<8) + (*dest)); + *dest = *(dc->transmap + (dc->fullbright[dc->translation[dc->source[(frac>>FRACBITS)&heightmask]]]<<8) + (*dest)); } else { - *dest = *(dc_transmap + (dc_colormap[dc_translation[dc_source[(frac>>FRACBITS)&heightmask]]]<<8) + (*dest)); + *dest = *(dc->transmap + (dc->colormap[dc->translation[dc->source[(frac>>FRACBITS)&heightmask]]]<<8) + (*dest)); } dest += vid.width; frac += fracstep; - if (dc_brightmap != NULL && dc_brightmap[(frac>>FRACBITS)&heightmask] == BRIGHTPIXEL) + if (dc->brightmap != NULL && dc->brightmap[(frac>>FRACBITS)&heightmask] == BRIGHTPIXEL) { - *dest = *(dc_transmap + (dc_fullbright[dc_translation[dc_source[(frac>>FRACBITS)&heightmask]]]<<8) + (*dest)); + *dest = *(dc->transmap + (dc->fullbright[dc->translation[dc->source[(frac>>FRACBITS)&heightmask]]]<<8) + (*dest)); } else { - *dest = *(dc_transmap + (dc_colormap[dc_translation[dc_source[(frac>>FRACBITS)&heightmask]]]<<8) + (*dest)); + *dest = *(dc->transmap + (dc->colormap[dc->translation[dc->source[(frac>>FRACBITS)&heightmask]]]<<8) + (*dest)); } dest += vid.width; @@ -688,13 +690,13 @@ void R_DrawTranslatedTranslucentColumn_8(void) } if (count & 1) { - if (dc_brightmap != NULL && dc_brightmap[(frac>>FRACBITS)&heightmask] == BRIGHTPIXEL) + if (dc->brightmap != NULL && dc->brightmap[(frac>>FRACBITS)&heightmask] == BRIGHTPIXEL) { - *dest = *(dc_transmap + (dc_fullbright[dc_translation[dc_source[(frac>>FRACBITS)&heightmask]]]<<8) + (*dest)); + *dest = *(dc->transmap + (dc->fullbright[dc->translation[dc->source[(frac>>FRACBITS)&heightmask]]]<<8) + (*dest)); } else { - *dest = *(dc_transmap + (dc_colormap[dc_translation[dc_source[(frac>>FRACBITS)&heightmask]]]<<8) + (*dest)); + *dest = *(dc->transmap + (dc->colormap[dc->translation[dc->source[(frac>>FRACBITS)&heightmask]]]<<8) + (*dest)); } } } @@ -706,29 +708,29 @@ void R_DrawTranslatedTranslucentColumn_8(void) \warning STILL NOT IN ASM, TO DO.. */ -void R_DrawTranslatedColumn_8(void) +void R_DrawTranslatedColumn_8(drawcolumndata_t* dc) { register INT32 count; register UINT8 *dest; register fixed_t frac, fracstep; - count = dc_yh - dc_yl; + count = dc->yh - dc->yl; if (count < 0) return; #ifdef RANGECHECK - if ((unsigned)dc_x >= (unsigned)vid.width || dc_yl < 0 || dc_yh >= vid.height) - I_Error("R_DrawTranslatedColumn_8: %d to %d at %d", dc_yl, dc_yh, dc_x); + if ((unsigned)dc->x >= (unsigned)vid.width || dc->yl < 0 || dc->yh >= vid.height) + I_Error("R_DrawTranslatedColumn_8: %d to %d at %d", dc->yl, dc->yh, dc->x); #endif // FIXME. As above. //dest = ylookup[dc_yl] + columnofs[dc_x]; - dest = &topleft[dc_yl*vid.width + dc_x]; + dest = &topleft[dc->yl*vid.width + dc->x]; // Looks familiar. - fracstep = dc_iscale; + fracstep = dc->iscale; //frac = dc_texturemid + (dc_yl-centery)*fracstep; - frac = (dc_texturemid + FixedMul((dc_yl << FRACBITS) - centeryfrac, fracstep))*(!dc_hires); + frac = (dc->texturemid + FixedMul((dc->yl << FRACBITS) - centeryfrac, fracstep))*(!dc->hires); // Here we do an additional index re-mapping. do @@ -738,13 +740,13 @@ void R_DrawTranslatedColumn_8(void) // used with PLAY sprites. // Thus the "green" ramp of the player 0 sprite // is mapped to gray, red, black/indigo. - if (dc_brightmap != NULL && dc_brightmap[frac>>FRACBITS] == BRIGHTPIXEL) + if (dc->brightmap != NULL && dc->brightmap[frac>>FRACBITS] == BRIGHTPIXEL) { - *dest = dc_fullbright[dc_translation[dc_source[frac>>FRACBITS]]]; + *dest = dc->fullbright[dc->translation[dc->source[frac>>FRACBITS]]]; } else { - *dest = dc_colormap[dc_translation[dc_source[frac>>FRACBITS]]]; + *dest = dc->colormap[dc->translation[dc->source[frac>>FRACBITS]]]; } dest += vid.width; @@ -766,7 +768,7 @@ void R_DrawTranslatedColumn_8(void) /** \brief The R_DrawSpan_8 function Draws the actual span. */ -void R_DrawSpan_8 (void) +void R_DrawSpan_8 (drawspandata_t* ds) { fixed_t xposition; fixed_t yposition; @@ -780,11 +782,11 @@ void R_DrawSpan_8 (void) UINT8 *dest; const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height; - size_t count = (ds_x2 - ds_x1 + 1); + size_t count = (ds->x2 - ds->x1 + 1); size_t i; - xposition = ds_xfrac; yposition = ds_yfrac; - xstep = ds_xstep; ystep = ds_ystep; + xposition = ds->xfrac; yposition = ds->yfrac; + xstep = ds->xstep; ystep = ds->ystep; // SoM: we only need 6 bits for the integer part (0 thru 63) so the rest // can be used for the fraction part. This allows calculation of the memory address in the @@ -793,14 +795,14 @@ void R_DrawSpan_8 (void) // bit per power of two (obviously) // Ok, because I was able to eliminate the variable spot below, this function is now FASTER // than the original span renderer. Whodathunkit? - xposition <<= nflatshiftup; yposition <<= nflatshiftup; - xstep <<= nflatshiftup; ystep <<= nflatshiftup; + xposition <<= ds->nflatshiftup; yposition <<= ds->nflatshiftup; + xstep <<= ds->nflatshiftup; ystep <<= ds->nflatshiftup; - source = ds_source; - brightmap = ds_brightmap; - colormap = ds_colormap; - fullbright = ds_fullbright; - dest = ylookup[ds_y] + columnofs[ds_x1]; + source = ds->source; + brightmap = ds->brightmap; + colormap = ds->colormap; + fullbright = ds->fullbright; + dest = ylookup[ds->y] + columnofs[ds->x1]; if (dest+8 > deststop) return; @@ -813,7 +815,7 @@ void R_DrawSpan_8 (void) for (i = 0; i < 8; i++) { - bit = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); + bit = (((UINT32)yposition >> ds->nflatyshift) & ds->nflatmask) | ((UINT32)xposition >> ds->nflatxshift); if (brightmap != NULL && brightmap[bit] == BRIGHTPIXEL) { dest[i] = fullbright[source[bit]]; @@ -831,7 +833,7 @@ void R_DrawSpan_8 (void) } while (count-- && dest <= deststop) { - bit = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); + bit = (((UINT32)yposition >> ds->nflatyshift) & ds->nflatmask) | ((UINT32)xposition >> ds->nflatxshift); if (brightmap != NULL && brightmap[bit] == BRIGHTPIXEL) { *dest = fullbright[source[bit]]; @@ -849,34 +851,33 @@ void R_DrawSpan_8 (void) // R_CalcTiltedLighting // Exactly what it says on the tin. I wish I wasn't too lazy to explain things properly. -INT32 tiltlighting[MAXVIDWIDTH]; -void R_CalcTiltedLighting(fixed_t start, fixed_t end) +void R_CalcTiltedLighting(INT32 *lightbuffer, INT32 x1, INT32 x2, fixed_t start, fixed_t end) { // ZDoom uses a different lighting setup to us, and I couldn't figure out how to adapt their version // of this function. Here's my own. - INT32 left = ds_x1, right = ds_x2; - fixed_t step = (end-start)/(ds_x2-ds_x1+1); + INT32 left = x1, right = x2; + fixed_t step = (end-start)/(x2 - x1 + 1); INT32 i; // I wanna do some optimizing by checking for out-of-range segments on either side to fill in all at once, // but I'm too bad at coding to not crash the game trying to do that. I guess this is fast enough for now... for (i = left; i <= right; i++) { - tiltlighting[i] = (start += step) >> FRACBITS; - if (tiltlighting[i] < 0) - tiltlighting[i] = 0; - else if (tiltlighting[i] >= MAXLIGHTSCALE) - tiltlighting[i] = MAXLIGHTSCALE-1; + lightbuffer[i] = (start += step) >> FRACBITS; + if (lightbuffer[i] < 0) + lightbuffer[i] = 0; + else if (lightbuffer[i] >= MAXLIGHTSCALE) + lightbuffer[i] = MAXLIGHTSCALE-1; } } /** \brief The R_DrawTiltedSpan_8 function Draw slopes! Holy sheit! */ -void R_DrawTiltedSpan_8(void) +void R_DrawTiltedSpan_8(drawspandata_t* ds) { // x1, x2 = ds_x1, ds_x2 - int width = ds_x2 - ds_x1; + int width = ds->x2 - ds->x1; double iz, uz, vz; UINT32 u, v; int i; @@ -892,30 +893,31 @@ void R_DrawTiltedSpan_8(void) double endz, endu, endv; UINT32 stepu, stepv; UINT32 bit; + INT32 tiltlighting[MAXVIDWIDTH]; - iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); + iz = ds->szp.z + ds->szp.y*(centery-ds->y) + ds->szp.x*(ds->x1-centerx); // 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); } - uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx); - vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx); + uz = ds->sup.z + ds->sup.y*(centery-ds->y) + ds->sup.x*(ds->x1-centerx); + vz = ds->svp.z + ds->svp.y*(centery-ds->y) + ds->svp.x*(ds->x1-centerx); - dest = ylookup[ds_y] + columnofs[ds_x1]; + dest = ylookup[ds->y] + columnofs[ds->x1]; - source = ds_source; - brightmap = ds_brightmap; + source = ds->source; + brightmap = ds->brightmap; //colormap = ds_colormap; - fullbright = ds_fullbright; + fullbright = ds->fullbright; #if 0 // The "perfect" reference version of this routine. Pretty slow. // Use it only to see how things are supposed to look. @@ -946,9 +948,9 @@ void R_DrawTiltedSpan_8(void) startu = uz*startz; startv = vz*startz; - izstep = ds_szp->x * SPANSIZE; - uzstep = ds_sup->x * SPANSIZE; - vzstep = ds_svp->x * SPANSIZE; + izstep = ds->szp.x * SPANSIZE; + uzstep = ds->sup.x * SPANSIZE; + vzstep = ds->svp.x * SPANSIZE; //x1 = 0; width++; @@ -968,18 +970,18 @@ void R_DrawTiltedSpan_8(void) for (i = SPANSIZE-1; i >= 0; i--) { - bit = ((v >> nflatyshift) & nflatmask) | (u >> nflatxshift); + bit = ((v >> ds->nflatyshift) & ds->nflatmask) | (u >> ds->nflatxshift); if (brightmap != NULL && brightmap[bit] == BRIGHTPIXEL) { *dest = fullbright[source[bit]]; } else { - colormap = planezlight[tiltlighting[ds_x1]] + (ds_colormap - colormaps); + colormap = ds->planezlight[tiltlighting[ds->x1]] + (ds->colormap - colormaps); *dest = colormap[source[bit]]; } dest++; - ds_x1++; + ds->x1++; u += stepu; v += stepv; } @@ -993,24 +995,24 @@ void R_DrawTiltedSpan_8(void) { u = (INT64)(startu); v = (INT64)(startv); - bit = ((v >> nflatyshift) & nflatmask) | (u >> nflatxshift); + bit = ((v >> ds->nflatyshift) & ds->nflatmask) | (u >> ds->nflatxshift); if (brightmap != NULL && brightmap[bit] == BRIGHTPIXEL) { *dest = fullbright[source[bit]]; } else { - colormap = planezlight[tiltlighting[ds_x1]] + (ds_colormap - colormaps); + colormap = ds->planezlight[tiltlighting[ds->x1]] + (ds->colormap - colormaps); *dest = colormap[source[bit]]; } - ds_x1++; + ds->x1++; } else { double left = width; - iz += ds_szp->x * left; - uz += ds_sup->x * left; - vz += ds_svp->x * left; + iz += ds->szp.x * left; + uz += ds->sup.x * left; + vz += ds->svp.x * left; endz = 1.f/iz; endu = uz*endz; @@ -1023,18 +1025,18 @@ void R_DrawTiltedSpan_8(void) for (; width != 0; width--) { - bit = ((v >> nflatyshift) & nflatmask) | (u >> nflatxshift); + bit = ((v >> ds->nflatyshift) & ds->nflatmask) | (u >> ds->nflatxshift); if (brightmap != NULL && brightmap[bit] == BRIGHTPIXEL) { *dest = fullbright[source[bit]]; } else { - colormap = planezlight[tiltlighting[ds_x1]] + (ds_colormap - colormaps); + colormap = ds->planezlight[tiltlighting[ds->x1]] + (ds->colormap - colormaps); *dest = colormap[source[bit]]; } dest++; - ds_x1++; + ds->x1++; u += stepu; v += stepv; } @@ -1046,10 +1048,11 @@ void R_DrawTiltedSpan_8(void) /** \brief The R_DrawTiltedTranslucentSpan_8 function Like DrawTiltedSpan, but translucent */ -void R_DrawTiltedTranslucentSpan_8(void) +void R_DrawTiltedTranslucentSpan_8(drawspandata_t* ds) { + TracyCZone(__zone, true); // x1, x2 = ds_x1, ds_x2 - int width = ds_x2 - ds_x1; + int width = ds->x2 - ds->x1; double iz, uz, vz; UINT32 u, v; int i; @@ -1065,30 +1068,39 @@ void R_DrawTiltedTranslucentSpan_8(void) double endz, endu, endv; UINT32 stepu, stepv; UINT32 bit; + INT32 tiltlighting[MAXVIDWIDTH]; - iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); + INT32 x1 = ds->x1; + const INT32 nflatxshift = ds->nflatxshift; + const INT32 nflatyshift = ds->nflatyshift; + const INT32 nflatmask = ds->nflatmask; + UINT8 *transmap = ds->transmap; + lighttable_t **planezlight = ds->planezlight; + lighttable_t *ds_colormap = ds->colormap; + + iz = ds->szp.z + ds->szp.y*(centery-ds->y) + ds->szp.x*(ds->x1-centerx); // 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); } - uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx); - vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx); + uz = ds->sup.z + ds->sup.y*(centery-ds->y) + ds->sup.x*(ds->x1-centerx); + vz = ds->svp.z + ds->svp.y*(centery-ds->y) + ds->svp.x*(ds->x1-centerx); - dest = ylookup[ds_y] + columnofs[ds_x1]; + dest = ylookup[ds->y] + columnofs[ds->x1]; - source = ds_source; - brightmap = ds_brightmap; + source = ds->source; + brightmap = ds->brightmap; //colormap = ds_colormap; - fullbright = ds_fullbright; + fullbright = ds->fullbright; #if 0 // The "perfect" reference version of this routine. Pretty slow. // Use it only to see how things are supposed to look. @@ -1120,9 +1132,9 @@ void R_DrawTiltedTranslucentSpan_8(void) startu = uz*startz; startv = vz*startz; - izstep = ds_szp->x * SPANSIZE; - uzstep = ds_sup->x * SPANSIZE; - vzstep = ds_svp->x * SPANSIZE; + izstep = ds->szp.x * SPANSIZE; + uzstep = ds->sup.x * SPANSIZE; + vzstep = ds->svp.x * SPANSIZE; //x1 = 0; width++; @@ -1140,23 +1152,23 @@ void R_DrawTiltedTranslucentSpan_8(void) u = (INT64)(startu); v = (INT64)(startv); - for (i = SPANSIZE-1; i >= 0; i--) + x1 = ds->x1; + + for (i = 0; i < SPANSIZE; i++) { - bit = ((v >> nflatyshift) & nflatmask) | (u >> nflatxshift); + bit = (((v + stepv * i) >> nflatyshift) & nflatmask) | ((u + stepu * i) >> nflatxshift); if (brightmap != NULL && brightmap[bit] == BRIGHTPIXEL) { - *dest = *(ds_transmap + (fullbright[source[bit]] << 8) + *dest); + dest[i] = *(transmap + (fullbright[source[bit]] << 8) + dest[i]); } else { - colormap = planezlight[tiltlighting[ds_x1]] + (ds_colormap - colormaps); - *dest = *(ds_transmap + (colormap[source[bit]] << 8) + *dest); + colormap = planezlight[tiltlighting[x1 + i]] + (ds_colormap - colormaps); + dest[i] = *(transmap + (colormap[source[bit]] << 8) + dest[i]); } - dest++; - ds_x1++; - u += stepu; - v += stepv; } + ds->x1 += SPANSIZE; + dest += SPANSIZE; startu = endu; startv = endv; width -= SPANSIZE; @@ -1170,21 +1182,21 @@ void R_DrawTiltedTranslucentSpan_8(void) bit = ((v >> nflatyshift) & nflatmask) | (u >> nflatxshift); if (brightmap != NULL && brightmap[bit] == BRIGHTPIXEL) { - *dest = *(ds_transmap + (fullbright[source[bit]] << 8) + *dest); + *dest = *(transmap + (fullbright[source[bit]] << 8) + *dest); } else { - colormap = planezlight[tiltlighting[ds_x1]] + (ds_colormap - colormaps); - *dest = *(ds_transmap + (colormap[source[bit]] << 8) + *dest); + colormap = planezlight[tiltlighting[ds->x1]] + (ds_colormap - colormaps); + *dest = *(transmap + (colormap[source[bit]] << 8) + *dest); } - ds_x1++; + ds->x1++; } else { double left = width; - iz += ds_szp->x * left; - uz += ds_sup->x * left; - vz += ds_svp->x * left; + iz += ds->szp.x * left; + uz += ds->sup.x * left; + vz += ds->svp.x * left; endz = 1.f/iz; endu = uz*endz; @@ -1197,33 +1209,35 @@ void R_DrawTiltedTranslucentSpan_8(void) for (; width != 0; width--) { - bit = ((v >> nflatyshift) & nflatmask) | (u >> nflatxshift); + bit = ((v >> nflatyshift) & nflatmask) | (u >> nflatxshift);; if (brightmap != NULL && brightmap[bit] == BRIGHTPIXEL) { - *dest = *(ds_transmap + (fullbright[source[bit]] << 8) + *dest); + *dest = *(transmap + (fullbright[source[bit]] << 8) + *dest); } else { - colormap = planezlight[tiltlighting[ds_x1]] + (ds_colormap - colormaps); - *dest = *(ds_transmap + (colormap[source[bit]] << 8) + *dest); + colormap = planezlight[tiltlighting[ds->x1]] + (ds_colormap - colormaps); + *dest = *(transmap + (colormap[source[bit]] << 8) + *dest); } dest++; - ds_x1++; + ds->x1++; u += stepu; v += stepv; } } } #endif + TracyCZoneEnd(__zone); } /** \brief The R_DrawTiltedTranslucentWaterSpan_8 function Like DrawTiltedTranslucentSpan, but for water */ -void R_DrawTiltedTranslucentWaterSpan_8(void) +void R_DrawTiltedTranslucentWaterSpan_8(drawspandata_t* ds) { + TracyCZone(__zone, true); // x1, x2 = ds_x1, ds_x2 - int width = ds_x2 - ds_x1; + int width = ds->x2 - ds->x1; double iz, uz, vz; UINT32 u, v; int i; @@ -1240,30 +1254,39 @@ void R_DrawTiltedTranslucentWaterSpan_8(void) double endz, endu, endv; UINT32 stepu, stepv; UINT32 bit; + INT32 tiltlighting[MAXVIDWIDTH]; - iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); + INT32 x1 = ds->x1; + const INT32 nflatxshift = ds->nflatxshift; + const INT32 nflatyshift = ds->nflatyshift; + const INT32 nflatmask = ds->nflatmask; + UINT8 *transmap = ds->transmap; + lighttable_t **planezlight = ds->planezlight; + lighttable_t *ds_colormap = ds->colormap; + + iz = ds->szp.z + ds->szp.y*(centery-ds->y) + ds->szp.x*(ds->x1-centerx); // 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); } - uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx); - vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx); + uz = ds->sup.z + ds->sup.y*(centery-ds->y) + ds->sup.x*(ds->x1-centerx); + vz = ds->svp.z + ds->svp.y*(centery-ds->y) + ds->svp.x*(ds->x1-centerx); - dest = ylookup[ds_y] + columnofs[ds_x1]; - dsrc = screens[1] + (ds_y+ds_bgofs)*vid.width + ds_x1; - source = ds_source; - brightmap = ds_brightmap; + dest = ylookup[ds->y] + columnofs[ds->x1]; + dsrc = screens[1] + (ds->y+ds->bgofs)*vid.width + ds->x1; + source = ds->source; + brightmap = ds->brightmap; //colormap = ds_colormap; - fullbright = ds_fullbright; + fullbright = ds->fullbright; #if 0 // The "perfect" reference version of this routine. Pretty slow. // Use it only to see how things are supposed to look. @@ -1296,9 +1319,9 @@ void R_DrawTiltedTranslucentWaterSpan_8(void) startu = uz*startz; startv = vz*startz; - izstep = ds_szp->x * SPANSIZE; - uzstep = ds_sup->x * SPANSIZE; - vzstep = ds_svp->x * SPANSIZE; + izstep = ds->szp.x * SPANSIZE; + uzstep = ds->sup.x * SPANSIZE; + vzstep = ds->svp.x * SPANSIZE; //x1 = 0; width++; @@ -1316,24 +1339,24 @@ void R_DrawTiltedTranslucentWaterSpan_8(void) u = (INT64)(startu); v = (INT64)(startv); - for (i = SPANSIZE-1; i >= 0; i--) + x1 = ds->x1; + + for (i = 0; i < SPANSIZE; i++) { - bit = ((v >> nflatyshift) & nflatmask) | (u >> nflatxshift); + bit = (((v + stepv * i) >> nflatyshift) & nflatmask) | ((u + stepu * i) >> nflatxshift); if (brightmap != NULL && brightmap[bit] == BRIGHTPIXEL) { - *dest = *(ds_transmap + (fullbright[source[bit]] << 8) + *dsrc); + dest[i] = transmap[(fullbright[source[bit]] << 8) + dsrc[i]]; } else { - colormap = planezlight[tiltlighting[ds_x1]] + (ds_colormap - colormaps); - *dest = *(ds_transmap + (colormap[source[bit]] << 8) + *dsrc); + colormap = planezlight[tiltlighting[x1 + i]] + (ds_colormap - colormaps); + dest[i] = transmap[(colormap[source[bit]] << 8) + dsrc[i]]; } - dest++; - ds_x1++; - dsrc++; - u += stepu; - v += stepv; } + ds->x1 += SPANSIZE; + dest += SPANSIZE; + dsrc += SPANSIZE; startu = endu; startv = endv; width -= SPANSIZE; @@ -1347,21 +1370,21 @@ void R_DrawTiltedTranslucentWaterSpan_8(void) bit = ((v >> nflatyshift) & nflatmask) | (u >> nflatxshift); if (brightmap != NULL && brightmap[bit] == BRIGHTPIXEL) { - *dest = *(ds_transmap + (fullbright[source[bit]] << 8) + *dsrc); + *dest = *(transmap + (fullbright[source[bit]] << 8) + *dsrc); } else { - colormap = planezlight[tiltlighting[ds_x1]] + (ds_colormap - colormaps); - *dest = *(ds_transmap + (colormap[source[bit]] << 8) + *dsrc); + colormap = planezlight[tiltlighting[ds->x1]] + (ds_colormap - colormaps); + *dest = *(transmap + (colormap[source[bit]] << 8) + *dsrc); } - ds_x1++; + ds->x1++; } else { double left = width; - iz += ds_szp->x * left; - uz += ds_sup->x * left; - vz += ds_svp->x * left; + iz += ds->szp.x * left; + uz += ds->sup.x * left; + vz += ds->svp.x * left; endz = 1.f/iz; endu = uz*endz; @@ -1377,15 +1400,15 @@ void R_DrawTiltedTranslucentWaterSpan_8(void) bit = ((v >> nflatyshift) & nflatmask) | (u >> nflatxshift); if (brightmap != NULL && brightmap[bit] == BRIGHTPIXEL) { - *dest = *(ds_transmap + (fullbright[source[bit]] << 8) + *dsrc); + *dest = *(transmap + (fullbright[source[bit]] << 8) + *dsrc); } else { - colormap = planezlight[tiltlighting[ds_x1]] + (ds_colormap - colormaps); - *dest = *(ds_transmap + (colormap[source[bit]] << 8) + *dsrc); + colormap = planezlight[tiltlighting[ds->x1]] + (ds_colormap - colormaps); + *dest = *(transmap + (colormap[source[bit]] << 8) + *dsrc); } dest++; - ds_x1++; + ds->x1++; dsrc++; u += stepu; v += stepv; @@ -1393,12 +1416,13 @@ void R_DrawTiltedTranslucentWaterSpan_8(void) } } #endif + TracyCZoneEnd(__zone); } -void R_DrawTiltedSplat_8(void) +void R_DrawTiltedSplat_8(drawspandata_t* ds) { // x1, x2 = ds_x1, ds_x2 - int width = ds_x2 - ds_x1; + int width = ds->x2 - ds->x1; double iz, uz, vz; UINT32 u, v; int i; @@ -1416,30 +1440,31 @@ void R_DrawTiltedSplat_8(void) double endz, endu, endv; UINT32 stepu, stepv; UINT32 bit; + INT32 tiltlighting[MAXVIDWIDTH]; - iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); + iz = ds->szp.z + ds->szp.y*(centery-ds->y) + ds->szp.x*(ds->x1-centerx); // 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); } - uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx); - vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx); + uz = ds->sup.z + ds->sup.y*(centery-ds->y) + ds->sup.x*(ds->x1-centerx); + vz = ds->svp.z + ds->svp.y*(centery-ds->y) + ds->svp.x*(ds->x1-centerx); - dest = ylookup[ds_y] + columnofs[ds_x1]; + dest = ylookup[ds->y] + columnofs[ds->x1]; - source = ds_source; - brightmap = ds_brightmap; + source = ds->source; + brightmap = ds->brightmap; //colormap = ds_colormap; - fullbright = ds_fullbright; + fullbright = ds->fullbright; #if 0 // The "perfect" reference version of this routine. Pretty slow. // Use it only to see how things are supposed to look. @@ -1476,9 +1501,9 @@ void R_DrawTiltedSplat_8(void) startu = uz*startz; startv = vz*startz; - izstep = ds_szp->x * SPANSIZE; - uzstep = ds_sup->x * SPANSIZE; - vzstep = ds_svp->x * SPANSIZE; + izstep = ds->szp.x * SPANSIZE; + uzstep = ds->sup.x * SPANSIZE; + vzstep = ds->svp.x * SPANSIZE; //x1 = 0; width++; @@ -1498,7 +1523,7 @@ void R_DrawTiltedSplat_8(void) for (i = SPANSIZE-1; i >= 0; i--) { - bit = ((v >> nflatyshift) & nflatmask) | (u >> nflatxshift); + bit = ((v >> ds->nflatyshift) & ds->nflatmask) | (u >> ds->nflatxshift); val = source[bit]; if (val != TRANSPARENTPIXEL) { @@ -1508,12 +1533,12 @@ void R_DrawTiltedSplat_8(void) } else { - colormap = planezlight[tiltlighting[ds_x1]] + (ds_colormap - colormaps); + colormap = ds->planezlight[tiltlighting[ds->x1]] + (ds->colormap - colormaps); *dest = colormap[val]; } } dest++; - ds_x1++; + ds->x1++; u += stepu; v += stepv; } @@ -1527,7 +1552,7 @@ void R_DrawTiltedSplat_8(void) { u = (INT64)(startu); v = (INT64)(startv); - bit = ((v >> nflatyshift) & nflatmask) | (u >> nflatxshift); + bit = ((v >> ds->nflatyshift) & ds->nflatmask) | (u >> ds->nflatxshift); val = source[bit]; if (val != TRANSPARENTPIXEL) { @@ -1537,18 +1562,18 @@ void R_DrawTiltedSplat_8(void) } else { - colormap = planezlight[tiltlighting[ds_x1]] + (ds_colormap - colormaps); + colormap = ds->planezlight[tiltlighting[ds->x1]] + (ds->colormap - colormaps); *dest = colormap[val]; } - ds_x1++; + ds->x1++; } } else { double left = width; - iz += ds_szp->x * left; - uz += ds_sup->x * left; - vz += ds_svp->x * left; + iz += ds->szp.x * left; + uz += ds->sup.x * left; + vz += ds->svp.x * left; endz = 1.f/iz; endu = uz*endz; @@ -1561,7 +1586,7 @@ void R_DrawTiltedSplat_8(void) for (; width != 0; width--) { - bit = ((v >> nflatyshift) & nflatmask) | (u >> nflatxshift); + bit = ((v >> ds->nflatyshift) & ds->nflatmask) | (u >> ds->nflatxshift); val = source[bit]; if (val != TRANSPARENTPIXEL) { @@ -1571,12 +1596,12 @@ void R_DrawTiltedSplat_8(void) } else { - colormap = planezlight[tiltlighting[ds_x1]] + (ds_colormap - colormaps); + colormap = ds->planezlight[tiltlighting[ds->x1]] + (ds->colormap - colormaps); *dest = colormap[val]; } } dest++; - ds_x1++; + ds->x1++; u += stepu; v += stepv; } @@ -1588,7 +1613,7 @@ void R_DrawTiltedSplat_8(void) /** \brief The R_DrawSplat_8 function Just like R_DrawSpan_8, but skips transparent pixels. */ -void R_DrawSplat_8 (void) +void R_DrawSplat_8 (drawspandata_t* ds) { fixed_t xposition; fixed_t yposition; @@ -1602,12 +1627,12 @@ void R_DrawSplat_8 (void) UINT8 *dest; const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height; - size_t count = (ds_x2 - ds_x1 + 1); + size_t count = (ds->x2 - ds->x1 + 1); size_t i; UINT32 val; - xposition = ds_xfrac; yposition = ds_yfrac; - xstep = ds_xstep; ystep = ds_ystep; + xposition = ds->xfrac; yposition = ds->yfrac; + xstep = ds->xstep; ystep = ds->ystep; // SoM: we only need 6 bits for the integer part (0 thru 63) so the rest // can be used for the fraction part. This allows calculation of the memory address in the @@ -1616,14 +1641,14 @@ void R_DrawSplat_8 (void) // bit per power of two (obviously) // Ok, because I was able to eliminate the variable spot below, this function is now FASTER // than the original span renderer. Whodathunkit? - xposition <<= nflatshiftup; yposition <<= nflatshiftup; - xstep <<= nflatshiftup; ystep <<= nflatshiftup; + xposition <<= ds->nflatshiftup; yposition <<= ds->nflatshiftup; + xstep <<= ds->nflatshiftup; ystep <<= ds->nflatshiftup; - source = ds_source; - brightmap = ds_brightmap; - colormap = ds_colormap; - fullbright = ds_fullbright; - dest = ylookup[ds_y] + columnofs[ds_x1]; + source = ds->source; + brightmap = ds->brightmap; + colormap = ds->colormap; + fullbright = ds->fullbright; + dest = ylookup[ds->y] + columnofs[ds->x1]; while (count >= 8) { @@ -1632,7 +1657,7 @@ void R_DrawSplat_8 (void) // need! for (i = 0; i < 8; i++) { - bit = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); + bit = (((UINT32)yposition >> ds->nflatyshift) & ds->nflatmask) | ((UINT32)xposition >> ds->nflatxshift); bit &= MAXFLATBYTES; val = source[bit]; if (val != TRANSPARENTPIXEL) @@ -1655,7 +1680,7 @@ void R_DrawSplat_8 (void) } while (count-- && dest <= deststop) { - bit = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); + bit = (((UINT32)yposition >> ds->nflatyshift) & ds->nflatmask) | ((UINT32)xposition >> ds->nflatxshift); val = source[bit]; if (val != TRANSPARENTPIXEL) { @@ -1677,7 +1702,7 @@ void R_DrawSplat_8 (void) /** \brief The R_DrawTranslucentSplat_8 function Just like R_DrawSplat_8, but is translucent! */ -void R_DrawTranslucentSplat_8 (void) +void R_DrawTranslucentSplat_8 (drawspandata_t* ds) { fixed_t xposition; fixed_t yposition; @@ -1691,12 +1716,12 @@ void R_DrawTranslucentSplat_8 (void) UINT8 *dest; const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height; - size_t count = (ds_x2 - ds_x1 + 1); + size_t count = (ds->x2 - ds->x1 + 1); size_t i; UINT32 val; - xposition = ds_xfrac; yposition = ds_yfrac; - xstep = ds_xstep; ystep = ds_ystep; + xposition = ds->xfrac; yposition = ds->yfrac; + xstep = ds->xstep; ystep = ds->ystep; // SoM: we only need 6 bits for the integer part (0 thru 63) so the rest // can be used for the fraction part. This allows calculation of the memory address in the @@ -1705,14 +1730,14 @@ void R_DrawTranslucentSplat_8 (void) // bit per power of two (obviously) // Ok, because I was able to eliminate the variable spot below, this function is now FASTER // than the original span renderer. Whodathunkit? - xposition <<= nflatshiftup; yposition <<= nflatshiftup; - xstep <<= nflatshiftup; ystep <<= nflatshiftup; + xposition <<= ds->nflatshiftup; yposition <<= ds->nflatshiftup; + xstep <<= ds->nflatshiftup; ystep <<= ds->nflatshiftup; - source = ds_source; - brightmap = ds_brightmap; - colormap = ds_colormap; - fullbright = ds_fullbright; - dest = ylookup[ds_y] + columnofs[ds_x1]; + source = ds->source; + brightmap = ds->brightmap; + colormap = ds->colormap; + fullbright = ds->fullbright; + dest = ylookup[ds->y] + columnofs[ds->x1]; while (count >= 8) { @@ -1721,19 +1746,19 @@ void R_DrawTranslucentSplat_8 (void) // need! for (i = 0; i < 8; i++) { - bit = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); + bit = (((UINT32)yposition >> ds->nflatyshift) & ds->nflatmask) | ((UINT32)xposition >> ds->nflatxshift); val = source[bit]; if (val != TRANSPARENTPIXEL) { if (brightmap != NULL && brightmap[bit] == BRIGHTPIXEL) { - dest[i] = *(ds_transmap + (fullbright[val] << 8) + dest[i]); + dest[i] = *(ds->transmap + (fullbright[val] << 8) + dest[i]); } else { - dest[i] = *(ds_transmap + (colormap[val] << 8) + dest[i]); + dest[i] = *(ds->transmap + (colormap[val] << 8) + dest[i]); } - + } xposition += xstep; yposition += ystep; @@ -1744,19 +1769,19 @@ void R_DrawTranslucentSplat_8 (void) } while (count-- && dest <= deststop) { - bit = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); + bit = (((UINT32)yposition >> ds->nflatyshift) & ds->nflatmask) | ((UINT32)xposition >> ds->nflatxshift); val = source[bit]; if (val != TRANSPARENTPIXEL) { if (brightmap != NULL && brightmap[bit] == BRIGHTPIXEL) { - *dest = *(ds_transmap + (fullbright[val] << 8) + *dest); + *dest = *(ds->transmap + (fullbright[val] << 8) + *dest); } else { - *dest = *(ds_transmap + (colormap[val] << 8) + *dest); + *dest = *(ds->transmap + (colormap[val] << 8) + *dest); } - + } dest++; xposition += xstep; @@ -1767,7 +1792,7 @@ void R_DrawTranslucentSplat_8 (void) /** \brief The R_DrawFloorSprite_8 function Just like R_DrawSplat_8, but for floor sprites. */ -void R_DrawFloorSprite_8 (void) +void R_DrawFloorSprite_8 (drawspandata_t* ds) { fixed_t xposition; fixed_t yposition; @@ -1782,12 +1807,12 @@ void R_DrawFloorSprite_8 (void) UINT8 *dest; const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height; - size_t count = (ds_x2 - ds_x1 + 1); + size_t count = (ds->x2 - ds->x1 + 1); size_t i; UINT32 val; - xposition = ds_xfrac; yposition = ds_yfrac; - xstep = ds_xstep; ystep = ds_ystep; + xposition = ds->xfrac; yposition = ds->yfrac; + xstep = ds->xstep; ystep = ds->ystep; // SoM: we only need 6 bits for the integer part (0 thru 63) so the rest // can be used for the fraction part. This allows calculation of the memory address in the @@ -1796,15 +1821,15 @@ void R_DrawFloorSprite_8 (void) // bit per power of two (obviously) // Ok, because I was able to eliminate the variable spot below, this function is now FASTER // than the original span renderer. Whodathunkit? - xposition <<= nflatshiftup; yposition <<= nflatshiftup; - xstep <<= nflatshiftup; ystep <<= nflatshiftup; + xposition <<= ds->nflatshiftup; yposition <<= ds->nflatshiftup; + xstep <<= ds->nflatshiftup; ystep <<= ds->nflatshiftup; - source = (UINT16 *)ds_source; - brightmap = (UINT16 *)ds_brightmap; - colormap = ds_colormap; - fullbright = ds_fullbright; - translation = ds_translation; - dest = ylookup[ds_y] + columnofs[ds_x1]; + source = (UINT16 *)ds->source; + brightmap = (UINT16 *)ds->brightmap; + colormap = ds->colormap; + fullbright = ds->fullbright; + translation = ds->translation; + dest = ylookup[ds->y] + columnofs[ds->x1]; while (count >= 8) { @@ -1813,7 +1838,7 @@ void R_DrawFloorSprite_8 (void) // need! for (i = 0; i < 8; i++) { - bit = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); + bit = (((UINT32)yposition >> ds->nflatyshift) & ds->nflatmask) | ((UINT32)xposition >> ds->nflatxshift); val = source[bit]; if (val & 0xFF00) { @@ -1835,7 +1860,7 @@ void R_DrawFloorSprite_8 (void) } while (count-- && dest <= deststop) { - bit = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); + bit = (((UINT32)yposition >> ds->nflatyshift) & ds->nflatmask) | ((UINT32)xposition >> ds->nflatxshift); val = source[bit]; if (val & 0xFF00) { @@ -1857,7 +1882,7 @@ void R_DrawFloorSprite_8 (void) /** \brief The R_DrawTranslucentFloorSplat_8 function Just like R_DrawFloorSprite_8, but is translucent! */ -void R_DrawTranslucentFloorSprite_8 (void) +void R_DrawTranslucentFloorSprite_8 (drawspandata_t* ds) { fixed_t xposition; fixed_t yposition; @@ -1872,12 +1897,12 @@ void R_DrawTranslucentFloorSprite_8 (void) UINT8 *dest; const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height; - size_t count = (ds_x2 - ds_x1 + 1); + size_t count = (ds->x2 - ds->x1 + 1); size_t i; UINT32 val; - xposition = ds_xfrac; yposition = ds_yfrac; - xstep = ds_xstep; ystep = ds_ystep; + xposition = ds->xfrac; yposition = ds->yfrac; + xstep = ds->xstep; ystep = ds->ystep; // SoM: we only need 6 bits for the integer part (0 thru 63) so the rest // can be used for the fraction part. This allows calculation of the memory address in the @@ -1886,15 +1911,15 @@ void R_DrawTranslucentFloorSprite_8 (void) // bit per power of two (obviously) // Ok, because I was able to eliminate the variable spot below, this function is now FASTER // than the original span renderer. Whodathunkit? - xposition <<= nflatshiftup; yposition <<= nflatshiftup; - xstep <<= nflatshiftup; ystep <<= nflatshiftup; + xposition <<= ds->nflatshiftup; yposition <<= ds->nflatshiftup; + xstep <<= ds->nflatshiftup; ystep <<= ds->nflatshiftup; - source = (UINT16 *)ds_source; - brightmap = (UINT16 *)ds_brightmap; - colormap = ds_colormap; - fullbright = ds_fullbright; - translation = ds_translation; - dest = ylookup[ds_y] + columnofs[ds_x1]; + source = (UINT16 *)ds->source; + brightmap = (UINT16 *)ds->brightmap; + colormap = ds->colormap; + fullbright = ds->fullbright; + translation = ds->translation; + dest = ylookup[ds->y] + columnofs[ds->x1]; while (count >= 8) { @@ -1903,17 +1928,17 @@ void R_DrawTranslucentFloorSprite_8 (void) // need! for (i = 0; i < 8; i++) { - bit = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); + bit = (((UINT32)yposition >> ds->nflatyshift) & ds->nflatmask) | ((UINT32)xposition >> ds->nflatxshift); val = source[bit]; if (val & 0xFF00) { if (brightmap != NULL && brightmap[bit] == BRIGHTPIXEL) { - dest[i] = *(ds_transmap + (fullbright[translation[val & 0xFF]] << 8) + dest[i]); + dest[i] = *(ds->transmap + (fullbright[translation[val & 0xFF]] << 8) + dest[i]); } else { - dest[i] = *(ds_transmap + (colormap[translation[val & 0xFF]] << 8) + dest[i]); + dest[i] = *(ds->transmap + (colormap[translation[val & 0xFF]] << 8) + dest[i]); } } xposition += xstep; @@ -1925,17 +1950,17 @@ void R_DrawTranslucentFloorSprite_8 (void) } while (count-- && dest <= deststop) { - bit = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); + bit = (((UINT32)yposition >> ds->nflatyshift) & ds->nflatmask) | ((UINT32)xposition >> ds->nflatxshift); val = source[bit]; if (val & 0xFF00) { if (brightmap != NULL && brightmap[bit] == BRIGHTPIXEL) { - *dest = *(ds_transmap + (fullbright[translation[val & 0xFF]] << 8) + *dest); + *dest = *(ds->transmap + (fullbright[translation[val & 0xFF]] << 8) + *dest); } else { - *dest = *(ds_transmap + (colormap[translation[val & 0xFF]] << 8) + *dest); + *dest = *(ds->transmap + (colormap[translation[val & 0xFF]] << 8) + *dest); } } dest++; @@ -1947,10 +1972,10 @@ void R_DrawTranslucentFloorSprite_8 (void) /** \brief The R_DrawTiltedFloorSprite_8 function Draws a tilted floor sprite. */ -void R_DrawTiltedFloorSprite_8(void) +void R_DrawTiltedFloorSprite_8(drawspandata_t* ds) { // x1, x2 = ds_x1, ds_x2 - int width = ds_x2 - ds_x1; + int width = ds->x2 - ds->x1; double iz, uz, vz; UINT32 u, v; int i; @@ -1969,24 +1994,24 @@ void R_DrawTiltedFloorSprite_8(void) UINT32 stepu, stepv; UINT32 bit; - iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); - uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx); - vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx); + iz = ds->szp.z + ds->szp.y*(centery-ds->y) + ds->szp.x*(ds->x1-centerx); + uz = ds->sup.z + ds->sup.y*(centery-ds->y) + ds->sup.x*(ds->x1-centerx); + vz = ds->svp.z + ds->svp.y*(centery-ds->y) + ds->svp.x*(ds->x1-centerx); - dest = ylookup[ds_y] + columnofs[ds_x1]; - source = (UINT16 *)ds_source; - brightmap = (UINT16 *)ds_brightmap; - colormap = ds_colormap; - fullbright = ds_fullbright; - translation = ds_translation; + dest = ylookup[ds->y] + columnofs[ds->x1]; + source = (UINT16 *)ds->source; + brightmap = (UINT16 *)ds->brightmap; + colormap = ds->colormap; + fullbright = ds->fullbright; + translation = ds->translation; startz = 1.f/iz; startu = uz*startz; startv = vz*startz; - izstep = ds_szp->x * SPANSIZE; - uzstep = ds_sup->x * SPANSIZE; - vzstep = ds_svp->x * SPANSIZE; + izstep = ds->szp.x * SPANSIZE; + uzstep = ds->sup.x * SPANSIZE; + vzstep = ds->svp.x * SPANSIZE; //x1 = 0; width++; @@ -2006,7 +2031,7 @@ void R_DrawTiltedFloorSprite_8(void) for (i = SPANSIZE-1; i >= 0; i--) { - bit = ((v >> nflatyshift) & nflatmask) | (u >> nflatxshift); + bit = ((v >> ds->nflatyshift) & ds->nflatmask) | (u >> ds->nflatxshift); val = source[bit]; if (val & 0xFF00) { @@ -2034,7 +2059,7 @@ void R_DrawTiltedFloorSprite_8(void) { u = (INT64)(startu); v = (INT64)(startv); - bit = ((v >> nflatyshift) & nflatmask) | (u >> nflatxshift); + bit = ((v >> ds->nflatyshift) & ds->nflatmask) | (u >> ds->nflatxshift); val = source[bit]; if (val & 0xFF00) { @@ -2051,9 +2076,9 @@ void R_DrawTiltedFloorSprite_8(void) else { double left = width; - iz += ds_szp->x * left; - uz += ds_sup->x * left; - vz += ds_svp->x * left; + iz += ds->szp.x * left; + uz += ds->sup.x * left; + vz += ds->svp.x * left; endz = 1.f/iz; endu = uz*endz; @@ -2066,7 +2091,7 @@ void R_DrawTiltedFloorSprite_8(void) for (; width != 0; width--) { - bit = ((v >> nflatyshift) & nflatmask) | (u >> nflatxshift); + bit = ((v >> ds->nflatyshift) & ds->nflatmask) | (u >> ds->nflatxshift); val = source[bit]; if (val & 0xFF00) { @@ -2091,10 +2116,10 @@ void R_DrawTiltedFloorSprite_8(void) /** \brief The R_DrawTiltedTranslucentFloorSprite_8 function Draws a tilted, translucent, floor sprite. */ -void R_DrawTiltedTranslucentFloorSprite_8(void) +void R_DrawTiltedTranslucentFloorSprite_8(drawspandata_t* ds) { // x1, x2 = ds_x1, ds_x2 - int width = ds_x2 - ds_x1; + int width = ds->x2 - ds->x1; double iz, uz, vz; UINT32 u, v; int i; @@ -2113,24 +2138,29 @@ void R_DrawTiltedTranslucentFloorSprite_8(void) UINT32 stepu, stepv; UINT32 bit; - iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); - uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx); - vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx); + const INT32 nflatxshift = ds->nflatxshift; + const INT32 nflatyshift = ds->nflatyshift; + const INT32 nflatmask = ds->nflatmask; + UINT8 *transmap = ds->transmap; - dest = ylookup[ds_y] + columnofs[ds_x1]; - source = (UINT16 *)ds_source; - brightmap = (UINT16 *)ds_brightmap; - colormap = ds_colormap; - fullbright = ds_fullbright; - translation = ds_translation; + iz = ds->szp.z + ds->szp.y*(centery-ds->y) + ds->szp.x*(ds->x1-centerx); + uz = ds->sup.z + ds->sup.y*(centery-ds->y) + ds->sup.x*(ds->x1-centerx); + vz = ds->svp.z + ds->svp.y*(centery-ds->y) + ds->svp.x*(ds->x1-centerx); + + dest = ylookup[ds->y] + columnofs[ds->x1]; + source = (UINT16 *)ds->source; + brightmap = (UINT16 *)ds->brightmap; + colormap = ds->colormap; + fullbright = ds->fullbright; + translation = ds->translation; startz = 1.f/iz; startu = uz*startz; startv = vz*startz; - izstep = ds_szp->x * SPANSIZE; - uzstep = ds_sup->x * SPANSIZE; - vzstep = ds_svp->x * SPANSIZE; + izstep = ds->szp.x * SPANSIZE; + uzstep = ds->sup.x * SPANSIZE; + vzstep = ds->svp.x * SPANSIZE; //x1 = 0; width++; @@ -2148,25 +2178,21 @@ void R_DrawTiltedTranslucentFloorSprite_8(void) u = (INT64)(startu); v = (INT64)(startv); - for (i = SPANSIZE-1; i >= 0; i--) + for (i = 0; i < SPANSIZE; i++) { - bit = ((v >> nflatyshift) & nflatmask) | (u >> nflatxshift); + bit = (((v + stepv * i) >> nflatyshift) & nflatmask) | ((u + stepu * i) >> nflatxshift); val = source[bit]; if (val & 0xFF00) { if (brightmap != NULL && brightmap[bit] == BRIGHTPIXEL) { - *dest = *(ds_transmap + (fullbright[translation[val & 0xFF]] << 8) + *dest); + dest[i] = *(transmap + (fullbright[translation[val & 0xFF]] << 8) + dest[i]); } else { - *dest = *(ds_transmap + (colormap[translation[val & 0xFF]] << 8) + *dest); + dest[i] = *(transmap + (colormap[translation[val & 0xFF]] << 8) + dest[i]); } } - dest++; - - u += stepu; - v += stepv; } startu = endu; startv = endv; @@ -2184,20 +2210,20 @@ void R_DrawTiltedTranslucentFloorSprite_8(void) { if (brightmap != NULL && brightmap[bit] == BRIGHTPIXEL) { - *dest = *(ds_transmap + (fullbright[translation[val & 0xFF]] << 8) + *dest); + *dest = *(transmap + (fullbright[translation[val & 0xFF]] << 8) + *dest); } else { - *dest = *(ds_transmap + (colormap[translation[val & 0xFF]] << 8) + *dest); + *dest = *(transmap + (colormap[translation[val & 0xFF]] << 8) + *dest); } } } else { double left = width; - iz += ds_szp->x * left; - uz += ds_sup->x * left; - vz += ds_svp->x * left; + iz += ds->szp.x * left; + uz += ds->sup.x * left; + vz += ds->svp.x * left; endz = 1.f/iz; endu = uz*endz; @@ -2216,11 +2242,11 @@ void R_DrawTiltedTranslucentFloorSprite_8(void) { if (brightmap != NULL && brightmap[bit] == BRIGHTPIXEL) { - *dest = *(ds_transmap + (fullbright[translation[val & 0xFF]] << 8) + *dest); + *dest = *(transmap + (fullbright[translation[val & 0xFF]] << 8) + *dest); } else { - *dest = *(ds_transmap + (colormap[translation[val & 0xFF]] << 8) + *dest); + *dest = *(transmap + (colormap[translation[val & 0xFF]] << 8) + *dest); } } dest++; @@ -2235,7 +2261,7 @@ void R_DrawTiltedTranslucentFloorSprite_8(void) /** \brief The R_DrawTranslucentSpan_8 function Draws the actual span with translucency. */ -void R_DrawTranslucentSpan_8 (void) +void R_DrawTranslucentSpan_8 (drawspandata_t* ds) { fixed_t xposition; fixed_t yposition; @@ -2249,11 +2275,11 @@ void R_DrawTranslucentSpan_8 (void) UINT8 *dest; const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height; - size_t count = (ds_x2 - ds_x1 + 1); + size_t count = (ds->x2 - ds->x1 + 1); size_t i; - xposition = ds_xfrac; yposition = ds_yfrac; - xstep = ds_xstep; ystep = ds_ystep; + xposition = ds->xfrac; yposition = ds->yfrac; + xstep = ds->xstep; ystep = ds->ystep; // SoM: we only need 6 bits for the integer part (0 thru 63) so the rest // can be used for the fraction part. This allows calculation of the memory address in the @@ -2262,14 +2288,14 @@ void R_DrawTranslucentSpan_8 (void) // bit per power of two (obviously) // Ok, because I was able to eliminate the variable spot below, this function is now FASTER // than the original span renderer. Whodathunkit? - xposition <<= nflatshiftup; yposition <<= nflatshiftup; - xstep <<= nflatshiftup; ystep <<= nflatshiftup; + xposition <<= ds->nflatshiftup; yposition <<= ds->nflatshiftup; + xstep <<= ds->nflatshiftup; ystep <<= ds->nflatshiftup; - source = ds_source; - brightmap = ds_brightmap; - colormap = ds_colormap; - fullbright = ds_fullbright; - dest = ylookup[ds_y] + columnofs[ds_x1]; + source = ds->source; + brightmap = ds->brightmap; + colormap = ds->colormap; + fullbright = ds->fullbright; + dest = ylookup[ds->y] + columnofs[ds->x1]; while (count >= 8) { @@ -2278,14 +2304,14 @@ void R_DrawTranslucentSpan_8 (void) // need! for (i = 0; i < 8; i++) { - bit = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); + bit = (((UINT32)yposition >> ds->nflatyshift) & ds->nflatmask) | ((UINT32)xposition >> ds->nflatxshift); if (brightmap != NULL && brightmap[bit] == BRIGHTPIXEL) { - dest[i] = *(ds_transmap + (fullbright[source[bit]] << 8) + dest[i]); + dest[i] = *(ds->transmap + (fullbright[source[bit]] << 8) + dest[i]); } else { - dest[i] = *(ds_transmap + (colormap[source[bit]] << 8) + dest[i]); + dest[i] = *(ds->transmap + (colormap[source[bit]] << 8) + dest[i]); } xposition += xstep; yposition += ystep; @@ -2296,14 +2322,14 @@ void R_DrawTranslucentSpan_8 (void) } while (count-- && dest <= deststop) { - bit = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); + bit = (((UINT32)yposition >> ds->nflatyshift) & ds->nflatmask) | ((UINT32)xposition >> ds->nflatxshift); if (brightmap != NULL && brightmap[bit] == BRIGHTPIXEL) { - *dest = *(ds_transmap + (fullbright[source[bit]] << 8) + *dest); + *dest = *(ds->transmap + (fullbright[source[bit]] << 8) + *dest); } else { - *dest = *(ds_transmap + (colormap[source[bit]] << 8) + *dest); + *dest = *(ds->transmap + (colormap[source[bit]] << 8) + *dest); } dest++; xposition += xstep; @@ -2311,7 +2337,7 @@ void R_DrawTranslucentSpan_8 (void) } } -void R_DrawTranslucentWaterSpan_8(void) +void R_DrawTranslucentWaterSpan_8(drawspandata_t* ds) { UINT32 xposition; UINT32 yposition; @@ -2335,16 +2361,16 @@ void R_DrawTranslucentWaterSpan_8(void) // bit per power of two (obviously) // Ok, because I was able to eliminate the variable spot below, this function is now FASTER // than the original span renderer. Whodathunkit? - xposition = ds_xfrac << nflatshiftup; yposition = (ds_yfrac + ds_waterofs) << nflatshiftup; - xstep = ds_xstep << nflatshiftup; ystep = ds_ystep << nflatshiftup; + xposition = ds->xfrac << ds->nflatshiftup; yposition = (ds->yfrac + ds->waterofs) << ds->nflatshiftup; + xstep = ds->xstep << ds->nflatshiftup; ystep = ds->ystep << ds->nflatshiftup; - source = ds_source; - brightmap = ds_brightmap; - colormap = ds_colormap; - fullbright = ds_fullbright; - dest = ylookup[ds_y] + columnofs[ds_x1]; - dsrc = screens[1] + (ds_y+ds_bgofs)*vid.width + ds_x1; - count = ds_x2 - ds_x1 + 1; + source = ds->source; + brightmap = ds->brightmap; + colormap = ds->colormap; + fullbright = ds->fullbright; + dest = ylookup[ds->y] + columnofs[ds->x1]; + dsrc = screens[1] + (ds->y+ds->bgofs)*vid.width + ds->x1; + count = ds->x2 - ds->x1 + 1; while (count >= 8) { @@ -2353,14 +2379,14 @@ void R_DrawTranslucentWaterSpan_8(void) // need! for (i = 0; i < 8; i++) { - bit = ((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift); + bit = ((yposition >> ds->nflatyshift) & ds->nflatmask) | (xposition >> ds->nflatxshift); if (brightmap != NULL && brightmap[bit] == BRIGHTPIXEL) { - dest[i] = fullbright[*(ds_transmap + (source[bit] << 8) + dsrc[i])]; + dest[i] = fullbright[*(ds->transmap + (source[bit] << 8) + dsrc[i])]; } else { - dest[i] = colormap[*(ds_transmap + (source[bit] << 8) + dsrc[i])]; + dest[i] = colormap[*(ds->transmap + (source[bit] << 8) + dsrc[i])]; } xposition += xstep; yposition += ystep; @@ -2372,14 +2398,14 @@ void R_DrawTranslucentWaterSpan_8(void) } while (count--) { - bit = ((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift); + bit = ((yposition >> ds->nflatyshift) & ds->nflatmask) | (xposition >> ds->nflatxshift); if (brightmap != NULL && brightmap[bit] == BRIGHTPIXEL) { - *dest = fullbright[*(ds_transmap + (source[bit] << 8) + *dsrc)]; + *dest = fullbright[*(ds->transmap + (source[bit] << 8) + *dsrc)]; } else { - *dest = colormap[*(ds_transmap + (source[bit] << 8) + *dsrc)]; + *dest = colormap[*(ds->transmap + (source[bit] << 8) + *dsrc)]; } dest++; dsrc++; @@ -2391,18 +2417,18 @@ void R_DrawTranslucentWaterSpan_8(void) /** \brief The R_DrawFogSpan_8 function Draws the actual span with fogging. */ -void R_DrawFogSpan_8(void) +void R_DrawFogSpan_8(drawspandata_t* ds) { UINT8 *colormap; UINT8 *dest; size_t count; - colormap = ds_colormap; + colormap = ds->colormap; //dest = ylookup[ds_y] + columnofs[ds_x1]; - dest = &topleft[ds_y *vid.width + ds_x1]; + dest = &topleft[ds->y *vid.width + ds->x1]; - count = ds_x2 - ds_x1 + 1; + count = ds->x2 - ds->x1 + 1; while (count >= 4) { @@ -2425,33 +2451,33 @@ void R_DrawFogSpan_8(void) /** \brief The R_DrawFogColumn_8 function Fog wall. */ -void R_DrawFogColumn_8(void) +void R_DrawFogColumn_8(drawcolumndata_t* dc) { INT32 count; UINT8 *dest; - count = dc_yh - dc_yl; + count = dc->yh - dc->yl; // Zero length, column does not exceed a pixel. if (count < 0) return; #ifdef RANGECHECK - if ((unsigned)dc_x >= (unsigned)vid.width || dc_yl < 0 || dc_yh >= vid.height) - I_Error("R_DrawFogColumn_8: %d to %d at %d", dc_yl, dc_yh, dc_x); + if ((unsigned)dc->x >= (unsigned)vid.width || dc->yl < 0 || dc->yh >= vid.height) + I_Error("R_DrawFogColumn_8: %d to %d at %d", dc->yl, dc->yh, dc->x); #endif // Framebuffer destination address. // Use ylookup LUT to avoid multiply with ScreenWidth. // 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]; // Determine scaling, which is the only mapping to be done. do { // Simple. Apply the colormap to what's already on the screen. - *dest = dc_colormap[*dest]; + *dest = dc->colormap[*dest]; dest += vid.width; } while (count--); } @@ -2461,34 +2487,34 @@ void R_DrawFogColumn_8(void) This function just cuts the column up into sections and calls R_DrawColumn_8 */ -void R_DrawColumnShadowed_8(void) +void R_DrawColumnShadowed_8(drawcolumndata_t* dc) { INT32 count, realyh, i, height, bheight = 0, solid = 0; - realyh = dc_yh; + realyh = dc->yh; - count = dc_yh - dc_yl; + count = dc->yh - dc->yl; // Zero length, column does not exceed a pixel. if (count < 0) return; #ifdef RANGECHECK - if ((unsigned)dc_x >= (unsigned)vid.width || dc_yl < 0 || dc_yh >= vid.height) - I_Error("R_DrawColumnShadowed_8: %d to %d at %d", dc_yl, dc_yh, dc_x); + if ((unsigned)dc->x >= (unsigned)vid.width || dc->yl < 0 || dc->yh >= vid.height) + I_Error("R_DrawColumnShadowed_8: %d to %d at %d", dc->yl, dc->yh, dc->x); #endif // This runs through the lightlist from top to bottom and cuts up the column accordingly. - for (i = 0; i < dc_numlights; i++) + for (i = 0; i < dc->numlights; i++) { // If the height of the light is above the column, get the colormap // anyway because the lighting of the top should be affected. - solid = dc_lightlist[i].flags & FOF_CUTSOLIDS; + solid = dc->lightlist[i].flags & FOF_CUTSOLIDS; - height = dc_lightlist[i].height >> LIGHTSCALESHIFT; + height = dc->lightlist[i].height >> LIGHTSCALESHIFT; if (solid) { - bheight = dc_lightlist[i].botheight >> LIGHTSCALESHIFT; + bheight = dc->lightlist[i].botheight >> LIGHTSCALESHIFT; if (bheight < height) { // confounded slopes sometimes allow partial invertedness, @@ -2500,39 +2526,39 @@ void R_DrawColumnShadowed_8(void) bheight = temp; } } - if (height <= dc_yl) + if (height <= dc->yl) { - dc_colormap = dc_lightlist[i].rcolormap; - dc_fullbright = colormaps; + dc->colormap = dc->lightlist[i].rcolormap; + dc->fullbright = colormaps; if (encoremap) { - dc_colormap += COLORMAP_REMAPOFFSET; - dc_fullbright += COLORMAP_REMAPOFFSET; + dc->colormap += COLORMAP_REMAPOFFSET; + dc->fullbright += COLORMAP_REMAPOFFSET; } - if (solid && dc_yl < bheight) - dc_yl = bheight; + if (solid && dc->yl < bheight) + dc->yl = bheight; continue; } // Found a break in the column! - dc_yh = height; + dc->yh = height; - if (dc_yh > realyh) - dc_yh = realyh; - (colfuncs[BASEDRAWFUNC])(); // R_DrawColumn_8 for the appropriate architecture + if (dc->yh > realyh) + dc->yh = realyh; + (colfuncs[BASEDRAWFUNC])(dc); // R_DrawColumn_8 for the appropriate architecture if (solid) - dc_yl = bheight; + dc->yl = bheight; else - dc_yl = dc_yh + 1; + dc->yl = dc->yh + 1; - dc_colormap = dc_lightlist[i].rcolormap; - dc_fullbright = colormaps; + dc->colormap = dc->lightlist[i].rcolormap; + dc->fullbright = colormaps; if (encoremap) { - dc_colormap += COLORMAP_REMAPOFFSET; - dc_fullbright += COLORMAP_REMAPOFFSET; + dc->colormap += COLORMAP_REMAPOFFSET; + dc->fullbright += COLORMAP_REMAPOFFSET; } } - dc_yh = realyh; - if (dc_yl <= realyh) - (colfuncs[BASEDRAWFUNC])(); // R_DrawWallColumn_8 for the appropriate architecture + dc->yh = realyh; + if (dc->yl <= realyh) + (colfuncs[BASEDRAWFUNC])(dc); // R_DrawWallColumn_8 for the appropriate architecture } diff --git a/src/r_draw8_flat.c b/src/r_draw8_flat.c index 20372d2c4..f6669b069 100644 --- a/src/r_draw8_flat.c +++ b/src/r_draw8_flat.c @@ -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++; } } diff --git a/src/r_draw8_npo2.c b/src/r_draw8_npo2.c index 6fd64e4ba..07adefdfe 100644 --- a/src/r_draw8_npo2.c +++ b/src/r_draw8_npo2.c @@ -21,7 +21,7 @@ /** \brief The R_DrawSpan_NPO2_8 function Draws the actual span. */ -void R_DrawSpan_NPO2_8 (void) +void R_DrawSpan_NPO2_8 (drawspandata_t* ds) { fixed_t xposition; fixed_t yposition; @@ -34,20 +34,20 @@ void R_DrawSpan_NPO2_8 (void) UINT8 *dest; const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height; - size_t count = (ds_x2 - ds_x1 + 1); + size_t count = (ds->x2 - ds->x1 + 1); - xposition = ds_xfrac; yposition = ds_yfrac; - xstep = ds_xstep; ystep = ds_ystep; + xposition = ds->xfrac; yposition = ds->yfrac; + xstep = ds->xstep; ystep = ds->ystep; - source = ds_source; - colormap = ds_colormap; - dest = ylookup[ds_y] + columnofs[ds_x1]; + source = ds->source; + colormap = ds->colormap; + dest = ylookup[ds->y] + columnofs[ds->x1]; if (dest+8 > deststop) return; - fixedwidth = ds_flatwidth << FRACBITS; - fixedheight = ds_flatheight << FRACBITS; + fixedwidth = ds->flatwidth << FRACBITS; + fixedheight = ds->flatheight << FRACBITS; // Fix xposition and yposition if they are out of bounds. if (xposition < 0) @@ -80,7 +80,7 @@ void R_DrawSpan_NPO2_8 (void) x = (xposition >> FRACBITS); y = (yposition >> FRACBITS); - *dest++ = colormap[source[((y * ds_flatwidth) + x)]]; + *dest++ = colormap[source[((y * ds->flatwidth) + x)]]; xposition += xstep; yposition += ystep; } @@ -89,10 +89,10 @@ void R_DrawSpan_NPO2_8 (void) /** \brief The R_DrawTiltedSpan_NPO2_8 function Draw slopes! Holy sheit! */ -void R_DrawTiltedSpan_NPO2_8(void) +void R_DrawTiltedSpan_NPO2_8(drawspandata_t* ds) { // x1, x2 = ds_x1, ds_x2 - int width = ds_x2 - ds_x1; + int width = ds->x2 - ds->x1; double iz, uz, vz; UINT32 u, v; int i; @@ -105,29 +105,30 @@ void R_DrawTiltedSpan_NPO2_8(void) double izstep, uzstep, vzstep; double endz, endu, endv; UINT32 stepu, stepv; + INT32 tiltlighting[MAXVIDWIDTH]; - struct libdivide_u32_t x_divider = libdivide_u32_gen(ds_flatwidth); - struct libdivide_u32_t y_divider = libdivide_u32_gen(ds_flatheight); + struct libdivide_u32_t x_divider = libdivide_u32_gen(ds->flatwidth); + struct libdivide_u32_t y_divider = libdivide_u32_gen(ds->flatheight); - iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); + iz = ds->szp.z + ds->szp.y*(centery-ds->y) + ds->szp.x*(ds->x1-centerx); // 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); } - uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx); - vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx); + uz = ds->sup.z + ds->sup.y*(centery-ds->y) + ds->sup.x*(ds->x1-centerx); + vz = ds->svp.z + ds->svp.y*(centery-ds->y) + ds->svp.x*(ds->x1-centerx); - dest = ylookup[ds_y] + columnofs[ds_x1]; - source = ds_source; + dest = ylookup[ds->y] + columnofs[ds->x1]; + source = ds->source; //colormap = ds_colormap; #if 0 // The "perfect" reference version of this routine. Pretty slow. @@ -168,9 +169,9 @@ void R_DrawTiltedSpan_NPO2_8(void) startu = uz*startz; startv = vz*startz; - izstep = ds_szp->x * SPANSIZE; - uzstep = ds_sup->x * SPANSIZE; - vzstep = ds_svp->x * SPANSIZE; + izstep = ds->szp.x * SPANSIZE; + uzstep = ds->sup.x * SPANSIZE; + vzstep = ds->svp.x * SPANSIZE; //x1 = 0; width++; @@ -190,7 +191,7 @@ void R_DrawTiltedSpan_NPO2_8(void) for (i = SPANSIZE-1; i >= 0; i--) { - colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + colormap = ds->planezlight[tiltlighting[ds->x1++]] + (ds->colormap - colormaps); // Lactozilla: Non-powers-of-two { fixed_t x = (((fixed_t)u) >> FRACBITS); @@ -198,15 +199,15 @@ void R_DrawTiltedSpan_NPO2_8(void) // Carefully align all of my Friends. if (x < 0) - x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds_flatwidth; + x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds->flatwidth; else - x -= libdivide_u32_do((UINT32)x, &x_divider) * ds_flatwidth; + x -= libdivide_u32_do((UINT32)x, &x_divider) * ds->flatwidth; if (y < 0) - y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds_flatheight; + y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds->flatheight; else - y -= libdivide_u32_do((UINT32)y, &y_divider) * ds_flatheight; + y -= libdivide_u32_do((UINT32)y, &y_divider) * ds->flatheight; - *dest = colormap[source[((y * ds_flatwidth) + x)]]; + *dest = colormap[source[((y * ds->flatwidth) + x)]]; } dest++; u += stepu; @@ -222,7 +223,7 @@ void R_DrawTiltedSpan_NPO2_8(void) { u = (INT64)(startu); v = (INT64)(startv); - colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + colormap = ds->planezlight[tiltlighting[ds->x1++]] + (ds->colormap - colormaps); // Lactozilla: Non-powers-of-two { fixed_t x = (((fixed_t)u) >> FRACBITS); @@ -230,23 +231,23 @@ void R_DrawTiltedSpan_NPO2_8(void) // Carefully align all of my Friends. if (x < 0) - x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds_flatwidth; + x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds->flatwidth; else - x -= libdivide_u32_do((UINT32)x, &x_divider) * ds_flatwidth; + x -= libdivide_u32_do((UINT32)x, &x_divider) * ds->flatwidth; if (y < 0) - y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds_flatheight; + y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds->flatheight; else - y -= libdivide_u32_do((UINT32)y, &y_divider) * ds_flatheight; + y -= libdivide_u32_do((UINT32)y, &y_divider) * ds->flatheight; - *dest = colormap[source[((y * ds_flatwidth) + x)]]; + *dest = colormap[source[((y * ds->flatwidth) + x)]]; } } else { double left = width; - iz += ds_szp->x * left; - uz += ds_sup->x * left; - vz += ds_svp->x * left; + iz += ds->szp.x * left; + uz += ds->sup.x * left; + vz += ds->svp.x * left; endz = 1.f/iz; endu = uz*endz; @@ -259,7 +260,7 @@ void R_DrawTiltedSpan_NPO2_8(void) for (; width != 0; width--) { - colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + colormap = ds->planezlight[tiltlighting[ds->x1++]] + (ds->colormap - colormaps); // Lactozilla: Non-powers-of-two { fixed_t x = (((fixed_t)u) >> FRACBITS); @@ -267,15 +268,15 @@ void R_DrawTiltedSpan_NPO2_8(void) // Carefully align all of my Friends. if (x < 0) - x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds_flatwidth; + x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds->flatwidth; else - x -= libdivide_u32_do((UINT32)x, &x_divider) * ds_flatwidth; + x -= libdivide_u32_do((UINT32)x, &x_divider) * ds->flatwidth; if (y < 0) - y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds_flatheight; + y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds->flatheight; else - y -= libdivide_u32_do((UINT32)y, &y_divider) * ds_flatheight; + y -= libdivide_u32_do((UINT32)y, &y_divider) * ds->flatheight; - *dest = colormap[source[((y * ds_flatwidth) + x)]]; + *dest = colormap[source[((y * ds->flatwidth) + x)]]; } dest++; u += stepu; @@ -289,10 +290,10 @@ void R_DrawTiltedSpan_NPO2_8(void) /** \brief The R_DrawTiltedTranslucentSpan_NPO2_8 function Like DrawTiltedSpan_NPO2, but translucent */ -void R_DrawTiltedTranslucentSpan_NPO2_8(void) +void R_DrawTiltedTranslucentSpan_NPO2_8(drawspandata_t* ds) { // x1, x2 = ds_x1, ds_x2 - int width = ds_x2 - ds_x1; + int width = ds->x2 - ds->x1; double iz, uz, vz; UINT32 u, v; int i; @@ -305,29 +306,30 @@ void R_DrawTiltedTranslucentSpan_NPO2_8(void) double izstep, uzstep, vzstep; double endz, endu, endv; UINT32 stepu, stepv; + INT32 tiltlighting[MAXVIDWIDTH]; - struct libdivide_u32_t x_divider = libdivide_u32_gen(ds_flatwidth); - struct libdivide_u32_t y_divider = libdivide_u32_gen(ds_flatheight); + struct libdivide_u32_t x_divider = libdivide_u32_gen(ds->flatwidth); + struct libdivide_u32_t y_divider = libdivide_u32_gen(ds->flatheight); - iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); + iz = ds->szp.z + ds->szp.y*(centery-ds->y) + ds->szp.x*(ds->x1-centerx); // 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); } - uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx); - vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx); + uz = ds->sup.z + ds->sup.y*(centery-ds->y) + ds->sup.x*(ds->x1-centerx); + vz = ds->svp.z + ds->svp.y*(centery-ds->y) + ds->svp.x*(ds->x1-centerx); - dest = ylookup[ds_y] + columnofs[ds_x1]; - source = ds_source; + dest = ylookup[ds->y] + columnofs[ds->x1]; + source = ds->source; //colormap = ds_colormap; #if 0 // The "perfect" reference version of this routine. Pretty slow. @@ -367,9 +369,9 @@ void R_DrawTiltedTranslucentSpan_NPO2_8(void) startu = uz*startz; startv = vz*startz; - izstep = ds_szp->x * SPANSIZE; - uzstep = ds_sup->x * SPANSIZE; - vzstep = ds_svp->x * SPANSIZE; + izstep = ds->szp.x * SPANSIZE; + uzstep = ds->sup.x * SPANSIZE; + vzstep = ds->svp.x * SPANSIZE; //x1 = 0; width++; @@ -389,7 +391,7 @@ void R_DrawTiltedTranslucentSpan_NPO2_8(void) for (i = SPANSIZE-1; i >= 0; i--) { - colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + colormap = ds->planezlight[tiltlighting[ds->x1++]] + (ds->colormap - colormaps); // Lactozilla: Non-powers-of-two { fixed_t x = (((fixed_t)u) >> FRACBITS); @@ -397,15 +399,15 @@ void R_DrawTiltedTranslucentSpan_NPO2_8(void) // Carefully align all of my Friends. if (x < 0) - x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds_flatwidth; + x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds->flatwidth; else - x -= libdivide_u32_do((UINT32)x, &x_divider) * ds_flatwidth; + x -= libdivide_u32_do((UINT32)x, &x_divider) * ds->flatwidth; if (y < 0) - y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds_flatheight; + y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds->flatheight; else - y -= libdivide_u32_do((UINT32)y, &y_divider) * ds_flatheight; + y -= libdivide_u32_do((UINT32)y, &y_divider) * ds->flatheight; - *dest = *(ds_transmap + (colormap[source[((y * ds_flatwidth) + x)]] << 8) + *dest); + *dest = *(ds->transmap + (colormap[source[((y * ds->flatwidth) + x)]] << 8) + *dest); } dest++; u += stepu; @@ -421,7 +423,7 @@ void R_DrawTiltedTranslucentSpan_NPO2_8(void) { u = (INT64)(startu); v = (INT64)(startv); - colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + colormap = ds->planezlight[tiltlighting[ds->x1++]] + (ds->colormap - colormaps); // Lactozilla: Non-powers-of-two { fixed_t x = (((fixed_t)u) >> FRACBITS); @@ -429,23 +431,23 @@ void R_DrawTiltedTranslucentSpan_NPO2_8(void) // Carefully align all of my Friends. if (x < 0) - x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds_flatwidth; + x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds->flatwidth; else - x -= libdivide_u32_do((UINT32)x, &x_divider) * ds_flatwidth; + x -= libdivide_u32_do((UINT32)x, &x_divider) * ds->flatwidth; if (y < 0) - y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds_flatheight; + y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds->flatheight; else - y -= libdivide_u32_do((UINT32)y, &y_divider) * ds_flatheight; + y -= libdivide_u32_do((UINT32)y, &y_divider) * ds->flatheight; - *dest = *(ds_transmap + (colormap[source[((y * ds_flatwidth) + x)]] << 8) + *dest); + *dest = *(ds->transmap + (colormap[source[((y * ds->flatwidth) + x)]] << 8) + *dest); } } else { double left = width; - iz += ds_szp->x * left; - uz += ds_sup->x * left; - vz += ds_svp->x * left; + iz += ds->szp.x * left; + uz += ds->sup.x * left; + vz += ds->svp.x * left; endz = 1.f/iz; endu = uz*endz; @@ -458,7 +460,7 @@ void R_DrawTiltedTranslucentSpan_NPO2_8(void) for (; width != 0; width--) { - colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + colormap = ds->planezlight[tiltlighting[ds->x1++]] + (ds->colormap - colormaps); // Lactozilla: Non-powers-of-two { fixed_t x = (((fixed_t)u) >> FRACBITS); @@ -466,15 +468,15 @@ void R_DrawTiltedTranslucentSpan_NPO2_8(void) // Carefully align all of my Friends. if (x < 0) - x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds_flatwidth; + x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds->flatwidth; else - x -= libdivide_u32_do((UINT32)x, &x_divider) * ds_flatwidth; + x -= libdivide_u32_do((UINT32)x, &x_divider) * ds->flatwidth; if (y < 0) - y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds_flatheight; + y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds->flatheight; else - y -= libdivide_u32_do((UINT32)y, &y_divider) * ds_flatheight; + y -= libdivide_u32_do((UINT32)y, &y_divider) * ds->flatheight; - *dest = *(ds_transmap + (colormap[source[((y * ds_flatwidth) + x)]] << 8) + *dest); + *dest = *(ds->transmap + (colormap[source[((y * ds->flatwidth) + x)]] << 8) + *dest); } dest++; u += stepu; @@ -485,10 +487,10 @@ void R_DrawTiltedTranslucentSpan_NPO2_8(void) #endif } -void R_DrawTiltedSplat_NPO2_8(void) +void R_DrawTiltedSplat_NPO2_8(drawspandata_t* ds) { // x1, x2 = ds_x1, ds_x2 - int width = ds_x2 - ds_x1; + int width = ds->x2 - ds->x1; double iz, uz, vz; UINT32 u, v; int i; @@ -503,29 +505,30 @@ void R_DrawTiltedSplat_NPO2_8(void) double izstep, uzstep, vzstep; double endz, endu, endv; UINT32 stepu, stepv; + INT32 tiltlighting[MAXVIDWIDTH]; - struct libdivide_u32_t x_divider = libdivide_u32_gen(ds_flatwidth); - struct libdivide_u32_t y_divider = libdivide_u32_gen(ds_flatheight); + struct libdivide_u32_t x_divider = libdivide_u32_gen(ds->flatwidth); + struct libdivide_u32_t y_divider = libdivide_u32_gen(ds->flatheight); - iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); + iz = ds->szp.z + ds->szp.y*(centery-ds->y) + ds->szp.x*(ds->x1-centerx); // 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); } - uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx); - vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx); + uz = ds->sup.z + ds->sup.y*(centery-ds->y) + ds->sup.x*(ds->x1-centerx); + vz = ds->svp.z + ds->svp.y*(centery-ds->y) + ds->svp.x*(ds->x1-centerx); - dest = ylookup[ds_y] + columnofs[ds_x1]; - source = ds_source; + dest = ylookup[ds->y] + columnofs[ds->x1]; + source = ds->source; //colormap = ds_colormap; #if 0 // The "perfect" reference version of this routine. Pretty slow. @@ -570,9 +573,9 @@ void R_DrawTiltedSplat_NPO2_8(void) startu = uz*startz; startv = vz*startz; - izstep = ds_szp->x * SPANSIZE; - uzstep = ds_sup->x * SPANSIZE; - vzstep = ds_svp->x * SPANSIZE; + izstep = ds->szp.x * SPANSIZE; + uzstep = ds->sup.x * SPANSIZE; + vzstep = ds->svp.x * SPANSIZE; //x1 = 0; width++; @@ -592,7 +595,7 @@ void R_DrawTiltedSplat_NPO2_8(void) for (i = SPANSIZE-1; i >= 0; i--) { - colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + colormap = ds->planezlight[tiltlighting[ds->x1++]] + (ds->colormap - colormaps); // Lactozilla: Non-powers-of-two { fixed_t x = (((fixed_t)u) >> FRACBITS); @@ -600,15 +603,15 @@ void R_DrawTiltedSplat_NPO2_8(void) // Carefully align all of my Friends. if (x < 0) - x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds_flatwidth; + x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds->flatwidth; else - x -= libdivide_u32_do((UINT32)x, &x_divider) * ds_flatwidth; + x -= libdivide_u32_do((UINT32)x, &x_divider) * ds->flatwidth; if (y < 0) - y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds_flatheight; + y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds->flatheight; else - y -= libdivide_u32_do((UINT32)y, &y_divider) * ds_flatheight; + y -= libdivide_u32_do((UINT32)y, &y_divider) * ds->flatheight; - val = source[((y * ds_flatwidth) + x)]; + val = source[((y * ds->flatwidth) + x)]; } if (val != TRANSPARENTPIXEL) *dest = colormap[val]; @@ -626,7 +629,7 @@ void R_DrawTiltedSplat_NPO2_8(void) { u = (INT64)(startu); v = (INT64)(startv); - colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + colormap = ds->planezlight[tiltlighting[ds->x1++]] + (ds->colormap - colormaps); // Lactozilla: Non-powers-of-two { fixed_t x = (((fixed_t)u) >> FRACBITS); @@ -634,15 +637,15 @@ void R_DrawTiltedSplat_NPO2_8(void) // Carefully align all of my Friends. if (x < 0) - x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds_flatwidth; + x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds->flatwidth; else - x -= libdivide_u32_do((UINT32)x, &x_divider) * ds_flatwidth; + x -= libdivide_u32_do((UINT32)x, &x_divider) * ds->flatwidth; if (y < 0) - y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds_flatheight; + y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds->flatheight; else - y -= libdivide_u32_do((UINT32)y, &y_divider) * ds_flatheight; + y -= libdivide_u32_do((UINT32)y, &y_divider) * ds->flatheight; - val = source[((y * ds_flatwidth) + x)]; + val = source[((y * ds->flatwidth) + x)]; } if (val != TRANSPARENTPIXEL) *dest = colormap[val]; @@ -650,9 +653,9 @@ void R_DrawTiltedSplat_NPO2_8(void) else { double left = width; - iz += ds_szp->x * left; - uz += ds_sup->x * left; - vz += ds_svp->x * left; + iz += ds->szp.x * left; + uz += ds->sup.x * left; + vz += ds->svp.x * left; endz = 1.f/iz; endu = uz*endz; @@ -665,7 +668,7 @@ void R_DrawTiltedSplat_NPO2_8(void) for (; width != 0; width--) { - colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + colormap = ds->planezlight[tiltlighting[ds->x1++]] + (ds->colormap - colormaps); // Lactozilla: Non-powers-of-two { fixed_t x = (((fixed_t)u) >> FRACBITS); @@ -673,15 +676,15 @@ void R_DrawTiltedSplat_NPO2_8(void) // Carefully align all of my Friends. if (x < 0) - x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds_flatwidth; + x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds->flatwidth; else - x -= libdivide_u32_do((UINT32)x, &x_divider) * ds_flatwidth; + x -= libdivide_u32_do((UINT32)x, &x_divider) * ds->flatwidth; if (y < 0) - y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds_flatheight; + y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds->flatheight; else - y -= libdivide_u32_do((UINT32)y, &y_divider) * ds_flatheight; + y -= libdivide_u32_do((UINT32)y, &y_divider) * ds->flatheight; - val = source[((y * ds_flatwidth) + x)]; + val = source[((y * ds->flatwidth) + x)]; } if (val != TRANSPARENTPIXEL) *dest = colormap[val]; @@ -697,7 +700,7 @@ void R_DrawTiltedSplat_NPO2_8(void) /** \brief The R_DrawSplat_NPO2_8 function Just like R_DrawSpan_NPO2_8, but skips transparent pixels. */ -void R_DrawSplat_NPO2_8 (void) +void R_DrawSplat_NPO2_8 (drawspandata_t* ds) { fixed_t xposition; fixed_t yposition; @@ -710,18 +713,18 @@ void R_DrawSplat_NPO2_8 (void) UINT8 *dest; const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height; - size_t count = (ds_x2 - ds_x1 + 1); + size_t count = (ds->x2 - ds->x1 + 1); UINT32 val; - xposition = ds_xfrac; yposition = ds_yfrac; - xstep = ds_xstep; ystep = ds_ystep; + xposition = ds->xfrac; yposition = ds->yfrac; + xstep = ds->xstep; ystep = ds->ystep; - source = ds_source; - colormap = ds_colormap; - dest = ylookup[ds_y] + columnofs[ds_x1]; + source = ds->source; + colormap = ds->colormap; + dest = ylookup[ds->y] + columnofs[ds->x1]; - fixedwidth = ds_flatwidth << FRACBITS; - fixedheight = ds_flatheight << FRACBITS; + fixedwidth = ds->flatwidth << FRACBITS; + fixedheight = ds->flatheight << FRACBITS; // Fix xposition and yposition if they are out of bounds. if (xposition < 0) @@ -753,7 +756,7 @@ void R_DrawSplat_NPO2_8 (void) x = (xposition >> FRACBITS); y = (yposition >> FRACBITS); - val = source[((y * ds_flatwidth) + x)]; + val = source[((y * ds->flatwidth) + x)]; if (val != TRANSPARENTPIXEL) *dest = colormap[val]; dest++; @@ -765,7 +768,7 @@ void R_DrawSplat_NPO2_8 (void) /** \brief The R_DrawTranslucentSplat_NPO2_8 function Just like R_DrawSplat_NPO2_8, but is translucent! */ -void R_DrawTranslucentSplat_NPO2_8 (void) +void R_DrawTranslucentSplat_NPO2_8 (drawspandata_t* ds) { fixed_t xposition; fixed_t yposition; @@ -778,18 +781,18 @@ void R_DrawTranslucentSplat_NPO2_8 (void) UINT8 *dest; const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height; - size_t count = (ds_x2 - ds_x1 + 1); + size_t count = (ds->x2 - ds->x1 + 1); UINT32 val; - xposition = ds_xfrac; yposition = ds_yfrac; - xstep = ds_xstep; ystep = ds_ystep; + xposition = ds->xfrac; yposition = ds->yfrac; + xstep = ds->xstep; ystep = ds->ystep; - source = ds_source; - colormap = ds_colormap; - dest = ylookup[ds_y] + columnofs[ds_x1]; + source = ds->source; + colormap = ds->colormap; + dest = ylookup[ds->y] + columnofs[ds->x1]; - fixedwidth = ds_flatwidth << FRACBITS; - fixedheight = ds_flatheight << FRACBITS; + fixedwidth = ds->flatwidth << FRACBITS; + fixedheight = ds->flatheight << FRACBITS; // Fix xposition and yposition if they are out of bounds. if (xposition < 0) @@ -821,9 +824,9 @@ void R_DrawTranslucentSplat_NPO2_8 (void) x = (xposition >> FRACBITS); y = (yposition >> FRACBITS); - val = source[((y * ds_flatwidth) + x)]; + val = source[((y * ds->flatwidth) + x)]; if (val != TRANSPARENTPIXEL) - *dest = *(ds_transmap + (colormap[val] << 8) + *dest); + *dest = *(ds->transmap + (colormap[val] << 8) + *dest); dest++; xposition += xstep; yposition += ystep; @@ -833,7 +836,7 @@ void R_DrawTranslucentSplat_NPO2_8 (void) /** \brief The R_DrawFloorSprite_NPO2_8 function Just like R_DrawSplat_NPO2_8, but for floor sprites. */ -void R_DrawFloorSprite_NPO2_8 (void) +void R_DrawFloorSprite_NPO2_8 (drawspandata_t* ds) { fixed_t xposition; fixed_t yposition; @@ -847,19 +850,19 @@ void R_DrawFloorSprite_NPO2_8 (void) UINT8 *dest; const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height; - size_t count = (ds_x2 - ds_x1 + 1); + size_t count = (ds->x2 - ds->x1 + 1); UINT32 val; - xposition = ds_xfrac; yposition = ds_yfrac; - xstep = ds_xstep; ystep = ds_ystep; + xposition = ds->xfrac; yposition = ds->yfrac; + xstep = ds->xstep; ystep = ds->ystep; - source = (UINT16 *)ds_source; - colormap = ds_colormap; - translation = ds_translation; - dest = ylookup[ds_y] + columnofs[ds_x1]; + source = (UINT16 *)ds->source; + colormap = ds->colormap; + translation = ds->translation; + dest = ylookup[ds->y] + columnofs[ds->x1]; - fixedwidth = ds_flatwidth << FRACBITS; - fixedheight = ds_flatheight << FRACBITS; + fixedwidth = ds->flatwidth << FRACBITS; + fixedheight = ds->flatheight << FRACBITS; // Fix xposition and yposition if they are out of bounds. if (xposition < 0) @@ -891,7 +894,7 @@ void R_DrawFloorSprite_NPO2_8 (void) x = (xposition >> FRACBITS); y = (yposition >> FRACBITS); - val = source[((y * ds_flatwidth) + x)]; + val = source[((y * ds->flatwidth) + x)]; if (val & 0xFF00) *dest = colormap[translation[val & 0xFF]]; dest++; @@ -903,7 +906,7 @@ void R_DrawFloorSprite_NPO2_8 (void) /** \brief The R_DrawTranslucentFloorSprite_NPO2_8 function Just like R_DrawFloorSprite_NPO2_8, but is translucent! */ -void R_DrawTranslucentFloorSprite_NPO2_8 (void) +void R_DrawTranslucentFloorSprite_NPO2_8 (drawspandata_t* ds) { fixed_t xposition; fixed_t yposition; @@ -917,19 +920,19 @@ void R_DrawTranslucentFloorSprite_NPO2_8 (void) UINT8 *dest; const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height; - size_t count = (ds_x2 - ds_x1 + 1); + size_t count = (ds->x2 - ds->x1 + 1); UINT32 val; - xposition = ds_xfrac; yposition = ds_yfrac; - xstep = ds_xstep; ystep = ds_ystep; + xposition = ds->xfrac; yposition = ds->yfrac; + xstep = ds->xstep; ystep = ds->ystep; - source = (UINT16 *)ds_source; - colormap = ds_colormap; - translation = ds_translation; - dest = ylookup[ds_y] + columnofs[ds_x1]; + source = (UINT16 *)ds->source; + colormap = ds->colormap; + translation = ds->translation; + dest = ylookup[ds->y] + columnofs[ds->x1]; - fixedwidth = ds_flatwidth << FRACBITS; - fixedheight = ds_flatheight << FRACBITS; + fixedwidth = ds->flatwidth << FRACBITS; + fixedheight = ds->flatheight << FRACBITS; // Fix xposition and yposition if they are out of bounds. if (xposition < 0) @@ -961,9 +964,9 @@ void R_DrawTranslucentFloorSprite_NPO2_8 (void) x = (xposition >> FRACBITS); y = (yposition >> FRACBITS); - val = source[((y * ds_flatwidth) + x)]; + val = source[((y * ds->flatwidth) + x)]; if (val & 0xFF00) - *dest = *(ds_transmap + (colormap[translation[val & 0xFF]] << 8) + *dest); + *dest = *(ds->transmap + (colormap[translation[val & 0xFF]] << 8) + *dest); dest++; xposition += xstep; yposition += ystep; @@ -973,10 +976,10 @@ void R_DrawTranslucentFloorSprite_NPO2_8 (void) /** \brief The R_DrawTiltedFloorSprite_NPO2_8 function Draws a tilted floor sprite. */ -void R_DrawTiltedFloorSprite_NPO2_8(void) +void R_DrawTiltedFloorSprite_NPO2_8(drawspandata_t* ds) { // x1, x2 = ds_x1, ds_x2 - int width = ds_x2 - ds_x1; + int width = ds->x2 - ds->x1; double iz, uz, vz; UINT32 u, v; int i; @@ -992,25 +995,25 @@ void R_DrawTiltedFloorSprite_NPO2_8(void) double endz, endu, endv; UINT32 stepu, stepv; - struct libdivide_u32_t x_divider = libdivide_u32_gen(ds_flatwidth); - struct libdivide_u32_t y_divider = libdivide_u32_gen(ds_flatheight); + struct libdivide_u32_t x_divider = libdivide_u32_gen(ds->flatwidth); + struct libdivide_u32_t y_divider = libdivide_u32_gen(ds->flatheight); - iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); - uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx); - vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx); + iz = ds->szp.z + ds->szp.y*(centery-ds->y) + ds->szp.x*(ds->x1-centerx); + uz = ds->sup.z + ds->sup.y*(centery-ds->y) + ds->sup.x*(ds->x1-centerx); + vz = ds->svp.z + ds->svp.y*(centery-ds->y) + ds->svp.x*(ds->x1-centerx); - dest = ylookup[ds_y] + columnofs[ds_x1]; - source = (UINT16 *)ds_source; - colormap = ds_colormap; - translation = ds_translation; + dest = ylookup[ds->y] + columnofs[ds->x1]; + source = (UINT16 *)ds->source; + colormap = ds->colormap; + translation = ds->translation; startz = 1.f/iz; startu = uz*startz; startv = vz*startz; - izstep = ds_szp->x * SPANSIZE; - uzstep = ds_sup->x * SPANSIZE; - vzstep = ds_svp->x * SPANSIZE; + izstep = ds->szp.x * SPANSIZE; + uzstep = ds->sup.x * SPANSIZE; + vzstep = ds->svp.x * SPANSIZE; //x1 = 0; width++; @@ -1036,15 +1039,15 @@ void R_DrawTiltedFloorSprite_NPO2_8(void) // Carefully align all of my Friends. if (x < 0) - x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds_flatwidth; + x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds->flatwidth; else - x -= libdivide_u32_do((UINT32)x, &x_divider) * ds_flatwidth; + x -= libdivide_u32_do((UINT32)x, &x_divider) * ds->flatwidth; if (y < 0) - y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds_flatheight; + y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds->flatheight; else - y -= libdivide_u32_do((UINT32)y, &y_divider) * ds_flatheight; + y -= libdivide_u32_do((UINT32)y, &y_divider) * ds->flatheight; - val = source[((y * ds_flatwidth) + x)]; + val = source[((y * ds->flatwidth) + x)]; if (val & 0xFF00) *dest = colormap[translation[val & 0xFF]]; dest++; @@ -1069,15 +1072,15 @@ void R_DrawTiltedFloorSprite_NPO2_8(void) // Carefully align all of my Friends. if (x < 0) - x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds_flatwidth; + x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds->flatwidth; else - x -= libdivide_u32_do((UINT32)x, &x_divider) * ds_flatwidth; + x -= libdivide_u32_do((UINT32)x, &x_divider) * ds->flatwidth; if (y < 0) - y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds_flatheight; + y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds->flatheight; else - y -= libdivide_u32_do((UINT32)y, &y_divider) * ds_flatheight; + y -= libdivide_u32_do((UINT32)y, &y_divider) * ds->flatheight; - val = source[((y * ds_flatwidth) + x)]; + val = source[((y * ds->flatwidth) + x)]; if (val & 0xFF00) *dest = colormap[translation[val & 0xFF]]; } @@ -1085,9 +1088,9 @@ void R_DrawTiltedFloorSprite_NPO2_8(void) else { double left = width; - iz += ds_szp->x * left; - uz += ds_sup->x * left; - vz += ds_svp->x * left; + iz += ds->szp.x * left; + uz += ds->sup.x * left; + vz += ds->svp.x * left; endz = 1.f/iz; endu = uz*endz; @@ -1106,15 +1109,15 @@ void R_DrawTiltedFloorSprite_NPO2_8(void) // Carefully align all of my Friends. if (x < 0) - x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds_flatwidth; + x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds->flatwidth; else - x -= libdivide_u32_do((UINT32)x, &x_divider) * ds_flatwidth; + x -= libdivide_u32_do((UINT32)x, &x_divider) * ds->flatwidth; if (y < 0) - y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds_flatheight; + y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds->flatheight; else - y -= libdivide_u32_do((UINT32)y, &y_divider) * ds_flatheight; + y -= libdivide_u32_do((UINT32)y, &y_divider) * ds->flatheight; - val = source[((y * ds_flatwidth) + x)]; + val = source[((y * ds->flatwidth) + x)]; if (val & 0xFF00) *dest = colormap[translation[val & 0xFF]]; dest++; @@ -1129,10 +1132,10 @@ void R_DrawTiltedFloorSprite_NPO2_8(void) /** \brief The R_DrawTiltedTranslucentFloorSprite_NPO2_8 function Draws a tilted, translucent, floor sprite. */ -void R_DrawTiltedTranslucentFloorSprite_NPO2_8(void) +void R_DrawTiltedTranslucentFloorSprite_NPO2_8(drawspandata_t* ds) { // x1, x2 = ds_x1, ds_x2 - int width = ds_x2 - ds_x1; + int width = ds->x2 - ds->x1; double iz, uz, vz; UINT32 u, v; int i; @@ -1148,25 +1151,25 @@ void R_DrawTiltedTranslucentFloorSprite_NPO2_8(void) double endz, endu, endv; UINT32 stepu, stepv; - struct libdivide_u32_t x_divider = libdivide_u32_gen(ds_flatwidth); - struct libdivide_u32_t y_divider = libdivide_u32_gen(ds_flatheight); + struct libdivide_u32_t x_divider = libdivide_u32_gen(ds->flatwidth); + struct libdivide_u32_t y_divider = libdivide_u32_gen(ds->flatheight); - iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); - uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx); - vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx); + iz = ds->szp.z + ds->szp.y*(centery-ds->y) + ds->szp.x*(ds->x1-centerx); + uz = ds->sup.z + ds->sup.y*(centery-ds->y) + ds->sup.x*(ds->x1-centerx); + vz = ds->svp.z + ds->svp.y*(centery-ds->y) + ds->svp.x*(ds->x1-centerx); - dest = ylookup[ds_y] + columnofs[ds_x1]; - source = (UINT16 *)ds_source; - colormap = ds_colormap; - translation = ds_translation; + dest = ylookup[ds->y] + columnofs[ds->x1]; + source = (UINT16 *)ds->source; + colormap = ds->colormap; + translation = ds->translation; startz = 1.f/iz; startu = uz*startz; startv = vz*startz; - izstep = ds_szp->x * SPANSIZE; - uzstep = ds_sup->x * SPANSIZE; - vzstep = ds_svp->x * SPANSIZE; + izstep = ds->szp.x * SPANSIZE; + uzstep = ds->sup.x * SPANSIZE; + vzstep = ds->svp.x * SPANSIZE; //x1 = 0; width++; @@ -1192,17 +1195,17 @@ void R_DrawTiltedTranslucentFloorSprite_NPO2_8(void) // Carefully align all of my Friends. if (x < 0) - x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds_flatwidth; + x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds->flatwidth; else - x -= libdivide_u32_do((UINT32)x, &x_divider) * ds_flatwidth; + x -= libdivide_u32_do((UINT32)x, &x_divider) * ds->flatwidth; if (y < 0) - y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds_flatheight; + y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds->flatheight; else - y -= libdivide_u32_do((UINT32)y, &y_divider) * ds_flatheight; + y -= libdivide_u32_do((UINT32)y, &y_divider) * ds->flatheight; - val = source[((y * ds_flatwidth) + x)]; + val = source[((y * ds->flatwidth) + x)]; if (val & 0xFF00) - *dest = *(ds_transmap + (colormap[translation[val & 0xFF]] << 8) + *dest); + *dest = *(ds->transmap + (colormap[translation[val & 0xFF]] << 8) + *dest); dest++; u += stepu; @@ -1225,25 +1228,25 @@ void R_DrawTiltedTranslucentFloorSprite_NPO2_8(void) // Carefully align all of my Friends. if (x < 0) - x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds_flatwidth; + x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds->flatwidth; else - x -= libdivide_u32_do((UINT32)x, &x_divider) * ds_flatwidth; + x -= libdivide_u32_do((UINT32)x, &x_divider) * ds->flatwidth; if (y < 0) - y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds_flatheight; + y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds->flatheight; else - y -= libdivide_u32_do((UINT32)y, &y_divider) * ds_flatheight; + y -= libdivide_u32_do((UINT32)y, &y_divider) * ds->flatheight; - val = source[((y * ds_flatwidth) + x)]; + val = source[((y * ds->flatwidth) + x)]; if (val & 0xFF00) - *dest = *(ds_transmap + (colormap[translation[val & 0xFF]] << 8) + *dest); + *dest = *(ds->transmap + (colormap[translation[val & 0xFF]] << 8) + *dest); } } else { double left = width; - iz += ds_szp->x * left; - uz += ds_sup->x * left; - vz += ds_svp->x * left; + iz += ds->szp.x * left; + uz += ds->sup.x * left; + vz += ds->svp.x * left; endz = 1.f/iz; endu = uz*endz; @@ -1262,17 +1265,17 @@ void R_DrawTiltedTranslucentFloorSprite_NPO2_8(void) // Carefully align all of my Friends. if (x < 0) - x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds_flatwidth; + x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds->flatwidth; else - x -= libdivide_u32_do((UINT32)x, &x_divider) * ds_flatwidth; + x -= libdivide_u32_do((UINT32)x, &x_divider) * ds->flatwidth; if (y < 0) - y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds_flatheight; + y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds->flatheight; else - y -= libdivide_u32_do((UINT32)y, &y_divider) * ds_flatheight; + y -= libdivide_u32_do((UINT32)y, &y_divider) * ds->flatheight; - val = source[((y * ds_flatwidth) + x)]; + val = source[((y * ds->flatwidth) + x)]; if (val & 0xFF00) - *dest = *(ds_transmap + (colormap[translation[val & 0xFF]] << 8) + *dest); + *dest = *(ds->transmap + (colormap[translation[val & 0xFF]] << 8) + *dest); dest++; u += stepu; @@ -1285,7 +1288,7 @@ void R_DrawTiltedTranslucentFloorSprite_NPO2_8(void) /** \brief The R_DrawTranslucentSpan_NPO2_8 function Draws the actual span with translucency. */ -void R_DrawTranslucentSpan_NPO2_8 (void) +void R_DrawTranslucentSpan_NPO2_8 (drawspandata_t* ds) { fixed_t xposition; fixed_t yposition; @@ -1298,18 +1301,18 @@ void R_DrawTranslucentSpan_NPO2_8 (void) UINT8 *dest; const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height; - size_t count = (ds_x2 - ds_x1 + 1); + size_t count = (ds->x2 - ds->x1 + 1); UINT32 val; - xposition = ds_xfrac; yposition = ds_yfrac; - xstep = ds_xstep; ystep = ds_ystep; + xposition = ds->xfrac; yposition = ds->yfrac; + xstep = ds->xstep; ystep = ds->ystep; - source = ds_source; - colormap = ds_colormap; - dest = ylookup[ds_y] + columnofs[ds_x1]; + source = ds->source; + colormap = ds->colormap; + dest = ylookup[ds->y] + columnofs[ds->x1]; - fixedwidth = ds_flatwidth << FRACBITS; - fixedheight = ds_flatheight << FRACBITS; + fixedwidth = ds->flatwidth << FRACBITS; + fixedheight = ds->flatheight << FRACBITS; // Fix xposition and yposition if they are out of bounds. if (xposition < 0) @@ -1341,15 +1344,15 @@ void R_DrawTranslucentSpan_NPO2_8 (void) x = (xposition >> FRACBITS); y = (yposition >> FRACBITS); - val = ((y * ds_flatwidth) + x); - *dest = *(ds_transmap + (colormap[source[val]] << 8) + *dest); + val = ((y * ds->flatwidth) + x); + *dest = *(ds->transmap + (colormap[source[val]] << 8) + *dest); dest++; xposition += xstep; yposition += ystep; } } -void R_DrawTranslucentWaterSpan_NPO2_8(void) +void R_DrawTranslucentWaterSpan_NPO2_8(drawspandata_t* ds) { fixed_t xposition; fixed_t yposition; @@ -1363,18 +1366,18 @@ void R_DrawTranslucentWaterSpan_NPO2_8(void) UINT8 *dsrc; const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height; - size_t count = (ds_x2 - ds_x1 + 1); + size_t count = (ds->x2 - ds->x1 + 1); - xposition = ds_xfrac; yposition = (ds_yfrac + ds_waterofs); - xstep = ds_xstep; ystep = ds_ystep; + xposition = ds->xfrac; yposition = (ds->yfrac + ds->waterofs); + xstep = ds->xstep; ystep = ds->ystep; - source = ds_source; - colormap = ds_colormap; - dest = ylookup[ds_y] + columnofs[ds_x1]; - dsrc = screens[1] + (ds_y+ds_bgofs)*vid.width + ds_x1; + source = ds->source; + colormap = ds->colormap; + dest = ylookup[ds->y] + columnofs[ds->x1]; + dsrc = screens[1] + (ds->y+ds->bgofs)*vid.width + ds->x1; - fixedwidth = ds_flatwidth << FRACBITS; - fixedheight = ds_flatheight << FRACBITS; + fixedwidth = ds->flatwidth << FRACBITS; + fixedheight = ds->flatheight << FRACBITS; // Fix xposition and yposition if they are out of bounds. if (xposition < 0) @@ -1406,7 +1409,7 @@ void R_DrawTranslucentWaterSpan_NPO2_8(void) x = (xposition >> FRACBITS); y = (yposition >> FRACBITS); - *dest++ = colormap[*(ds_transmap + (source[((y * ds_flatwidth) + x)] << 8) + *dsrc++)]; + *dest++ = colormap[*(ds->transmap + (source[((y * ds->flatwidth) + x)] << 8) + *dsrc++)]; xposition += xstep; yposition += ystep; } @@ -1415,10 +1418,10 @@ void R_DrawTranslucentWaterSpan_NPO2_8(void) /** \brief The R_DrawTiltedTranslucentWaterSpan_NPO2_8 function Like DrawTiltedTranslucentSpan_NPO2, but for water */ -void R_DrawTiltedTranslucentWaterSpan_NPO2_8(void) +void R_DrawTiltedTranslucentWaterSpan_NPO2_8(drawspandata_t* ds) { // x1, x2 = ds_x1, ds_x2 - int width = ds_x2 - ds_x1; + int width = ds->x2 - ds->x1; double iz, uz, vz; UINT32 u, v; int i; @@ -1432,31 +1435,32 @@ void R_DrawTiltedTranslucentWaterSpan_NPO2_8(void) double izstep, uzstep, vzstep; double endz, endu, endv; UINT32 stepu, stepv; + INT32 tiltlighting[MAXVIDWIDTH]; - struct libdivide_u32_t x_divider = libdivide_u32_gen(ds_flatwidth); - struct libdivide_u32_t y_divider = libdivide_u32_gen(ds_flatheight); + struct libdivide_u32_t x_divider = libdivide_u32_gen(ds->flatwidth); + struct libdivide_u32_t y_divider = libdivide_u32_gen(ds->flatheight); - iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); + iz = ds->szp.z + ds->szp.y*(centery-ds->y) + ds->szp.x*(ds->x1-centerx); // 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); } - uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx); - vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx); + uz = ds->sup.z + ds->sup.y*(centery-ds->y) + ds->sup.x*(ds->x1-centerx); + vz = ds->svp.z + ds->svp.y*(centery-ds->y) + ds->svp.x*(ds->x1-centerx); - dest = ylookup[ds_y] + columnofs[ds_x1]; - dsrc = screens[1] + (ds_y+ds_bgofs)*vid.width + ds_x1; - source = ds_source; - //colormap = ds_colormap; + dest = ylookup[ds->y] + columnofs[ds->x1]; + dsrc = screens[1] + (ds->y+ds->bgofs)*vid.width + ds->x1; + source = ds->source; + //colormap = ds->colormap; #if 0 // The "perfect" reference version of this routine. Pretty slow. // Use it only to see how things are supposed to look. @@ -1495,9 +1499,9 @@ void R_DrawTiltedTranslucentWaterSpan_NPO2_8(void) startu = uz*startz; startv = vz*startz; - izstep = ds_szp->x * SPANSIZE; - uzstep = ds_sup->x * SPANSIZE; - vzstep = ds_svp->x * SPANSIZE; + izstep = ds->szp.x * SPANSIZE; + uzstep = ds->sup.x * SPANSIZE; + vzstep = ds->svp.x * SPANSIZE; //x1 = 0; width++; @@ -1517,7 +1521,7 @@ void R_DrawTiltedTranslucentWaterSpan_NPO2_8(void) for (i = SPANSIZE-1; i >= 0; i--) { - colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + colormap = ds->planezlight[tiltlighting[ds->x1++]] + (ds->colormap - colormaps); // Lactozilla: Non-powers-of-two { fixed_t x = (((fixed_t)u) >> FRACBITS); @@ -1525,15 +1529,15 @@ void R_DrawTiltedTranslucentWaterSpan_NPO2_8(void) // Carefully align all of my Friends. if (x < 0) - x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds_flatwidth; + x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds->flatwidth; else - x -= libdivide_u32_do((UINT32)x, &x_divider) * ds_flatwidth; + x -= libdivide_u32_do((UINT32)x, &x_divider) * ds->flatwidth; if (y < 0) - y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds_flatheight; + y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds->flatheight; else - y -= libdivide_u32_do((UINT32)y, &y_divider) * ds_flatheight; + y -= libdivide_u32_do((UINT32)y, &y_divider) * ds->flatheight; - *dest = *(ds_transmap + (colormap[source[((y * ds_flatwidth) + x)]] << 8) + *dsrc++); + *dest = *(ds->transmap + (colormap[source[((y * ds->flatwidth) + x)]] << 8) + *dsrc++); } dest++; u += stepu; @@ -1549,7 +1553,7 @@ void R_DrawTiltedTranslucentWaterSpan_NPO2_8(void) { u = (INT64)(startu); v = (INT64)(startv); - colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + colormap = ds->planezlight[tiltlighting[ds->x1++]] + (ds->colormap - colormaps); // Lactozilla: Non-powers-of-two { fixed_t x = (((fixed_t)u) >> FRACBITS); @@ -1557,23 +1561,23 @@ void R_DrawTiltedTranslucentWaterSpan_NPO2_8(void) // Carefully align all of my Friends. if (x < 0) - x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds_flatwidth; + x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds->flatwidth; else - x -= libdivide_u32_do((UINT32)x, &x_divider) * ds_flatwidth; + x -= libdivide_u32_do((UINT32)x, &x_divider) * ds->flatwidth; if (y < 0) - y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds_flatheight; + y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds->flatheight; else - y -= libdivide_u32_do((UINT32)y, &y_divider) * ds_flatheight; + y -= libdivide_u32_do((UINT32)y, &y_divider) * ds->flatheight; - *dest = *(ds_transmap + (colormap[source[((y * ds_flatwidth) + x)]] << 8) + *dsrc++); + *dest = *(ds->transmap + (colormap[source[((y * ds->flatwidth) + x)]] << 8) + *dsrc++); } } else { double left = width; - iz += ds_szp->x * left; - uz += ds_sup->x * left; - vz += ds_svp->x * left; + iz += ds->szp.x * left; + uz += ds->sup.x * left; + vz += ds->svp.x * left; endz = 1.f/iz; endu = uz*endz; @@ -1586,7 +1590,7 @@ void R_DrawTiltedTranslucentWaterSpan_NPO2_8(void) for (; width != 0; width--) { - colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + colormap = ds->planezlight[tiltlighting[ds->x1++]] + (ds->colormap - colormaps); // Lactozilla: Non-powers-of-two { fixed_t x = (((fixed_t)u) >> FRACBITS); @@ -1594,15 +1598,15 @@ void R_DrawTiltedTranslucentWaterSpan_NPO2_8(void) // Carefully align all of my Friends. if (x < 0) - x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds_flatwidth; + x += (libdivide_u32_do((UINT32)(-x-1), &x_divider) + 1) * ds->flatwidth; else - x -= libdivide_u32_do((UINT32)x, &x_divider) * ds_flatwidth; + x -= libdivide_u32_do((UINT32)x, &x_divider) * ds->flatwidth; if (y < 0) - y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds_flatheight; + y += (libdivide_u32_do((UINT32)(-y-1), &y_divider) + 1) * ds->flatheight; else - y -= libdivide_u32_do((UINT32)y, &y_divider) * ds_flatheight; + y -= libdivide_u32_do((UINT32)y, &y_divider) * ds->flatheight; - *dest = *(ds_transmap + (colormap[source[((y * ds_flatwidth) + x)]] << 8) + *dsrc++); + *dest = *(ds->transmap + (colormap[source[((y * ds->flatwidth) + x)]] << 8) + *dsrc++); } dest++; u += stepu; diff --git a/src/r_fps.c b/src/r_fps.c index 09c94e2a5..1418b2a22 100644 --- a/src/r_fps.c +++ b/src/r_fps.c @@ -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 diff --git a/src/r_main.c b/src/r_main.cpp similarity index 94% rename from src/r_main.c rename to src/r_main.cpp index a8bf00d4e..7277c2ace 100644 --- a/src/r_main.c +++ b/src/r_main.cpp @@ -13,6 +13,8 @@ /// utility functions (BSP, geometry, trigonometry). /// See tables.c, too. +#include + #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(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_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_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(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(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(portal->floorclip[i]), viewheight); for (; yl < yh; ++yl) { diff --git a/src/r_plane.cpp b/src/r_plane.cpp index 1ddcd4b21..b936f5a04 100644 --- a/src/r_plane.cpp +++ b/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(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(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; diff --git a/src/r_plane.h b/src/r_plane.h index 2d2f5b04e..6f116b0c1 100644 --- a/src/r_plane.h +++ b/src/r_plane.h @@ -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); diff --git a/src/r_segs.cpp b/src/r_segs.cpp index 9e0a27042..fc6715bbf 100644 --- a/src/r_segs.cpp +++ b/src/r_segs.cpp @@ -30,6 +30,8 @@ #include "console.h" // con_clipviewtop #include "taglist.h" #include "r_draw.h" +#include "core/memory.h" +#include "core/thread_pool.h" extern "C" consvar_t cv_debugfinishline; @@ -93,49 +95,55 @@ static fixed_t *maskedtextureheight = NULL; // multi-patch textures. They are not normally needed as multi-patch // textures don't have holes in it. At least not for now. -static void R_Render2sidedMultiPatchColumn(column_t *column, column_t *brightmap, INT32 baseclip) +static void R_Render2sidedMultiPatchColumn(drawcolumndata_t* dc, column_t *column, column_t *brightmap, INT32 baseclip) { INT32 topscreen, bottomscreen; topscreen = sprtopscreen; // + spryscale*column->topdelta; topdelta is 0 for the wall bottomscreen = topscreen + spryscale * lengthcol; - dc_yl = (sprtopscreen+FRACUNIT-1)>>FRACBITS; - dc_yh = (bottomscreen-1)>>FRACBITS; + dc->yl = (sprtopscreen+FRACUNIT-1)>>FRACBITS; + dc->yh = (bottomscreen-1)>>FRACBITS; - dc_brightmap = NULL; + dc->brightmap = NULL; if (windowtop != INT32_MAX && windowbottom != INT32_MAX) { - dc_yl = ((windowtop + FRACUNIT)>>FRACBITS); - dc_yh = (windowbottom - 1)>>FRACBITS; + dc->yl = ((windowtop + FRACUNIT)>>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 >= vid.height || dc_yh < 0) + if (dc->yl >= vid.height || dc->yh < 0) return; - if (dc_yl <= dc_yh && dc_yh < vid.height && dc_yh > 0) + if (dc->yl <= dc->yh && dc->yh < vid.height && 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; } + drawcolumndata_t dc_copy = *dc; + coldrawfunc_t* colfunccopy = colfunc; if (R_CheckColumnFunc(BASEDRAWFUNC) == true) - (colfuncs[COLDRAWFUNC_TWOSMULTIPATCH])(); + { + colfunccopy = colfuncs[COLDRAWFUNC_TWOSMULTIPATCH]; + } else if (R_CheckColumnFunc(COLDRAWFUNC_FUZZY) == true) - (colfuncs[COLDRAWFUNC_TWOSMULTIPATCHTRANS])(); - else - colfunc(); + { + colfunccopy = colfuncs[COLDRAWFUNC_TWOSMULTIPATCHTRANS]; + } + + colfunccopy(const_cast(&dc_copy)); } } @@ -155,17 +163,17 @@ transnum_t R_GetLinedefTransTable(fixed_t alpha) } } -static inline boolean R_OverflowTest(void) +static inline boolean R_OverflowTest(drawcolumndata_t* dc) { INT64 overflow_test; - overflow_test = (INT64)centeryfrac - (((INT64)dc_texturemid*spryscale)>>FRACBITS); + overflow_test = (INT64)centeryfrac - (((INT64)dc->texturemid*spryscale)>>FRACBITS); if (overflow_test < 0) overflow_test = -overflow_test; if ((UINT64)overflow_test&0xFFFFFFFF80000000ULL) return true; return false; } -static void R_RenderMaskedSegLoop(drawseg_t *ds, INT32 x1, INT32 x2, INT32 texnum, void (*colfunc_2s)(column_t *, column_t *, INT32)) +static void R_RenderMaskedSegLoop(drawcolumndata_t* dc, drawseg_t *drawseg, INT32 x1, INT32 x2, INT32 texnum, void (*colfunc_2s)(drawcolumndata_t*, column_t *, column_t *, INT32)) { size_t pindex; column_t *col, *bmCol = NULL; @@ -183,34 +191,38 @@ static void R_RenderMaskedSegLoop(drawseg_t *ds, INT32 x1, INT32 x2, INT32 texnu ldef = curline->linedef; tripwire = P_IsLineTripWire(ldef); - range = std::max(ds->x2-ds->x1, 1); + range = std::max(drawseg->x2-drawseg->x1, 1); // Setup lighting based on the presence/lack-of 3D floors. - dc_numlights = 0; + dc->numlights = 0; if (tripwire == false && frontsector->numlights) { - dc_numlights = frontsector->numlights; - if (dc_numlights >= dc_maxlights) + dc->numlights = frontsector->numlights; + if (dc->numlights >= dc->maxlights) { - dc_maxlights = dc_numlights; - dc_lightlist = static_cast( - Z_Realloc(dc_lightlist, sizeof (*dc_lightlist) * dc_maxlights, PU_STATIC, NULL) - ); + r_lightlist_t* old_lightlist = dc->lightlist; + INT32 old_maxlights = dc->maxlights; + dc->maxlights = dc->numlights; + dc->lightlist = static_cast(Z_Frame_Alloc(sizeof (*dc->lightlist) * dc->maxlights)); + if (old_lightlist != nullptr) + { + M_Memcpy(dc->lightlist, old_lightlist, sizeof (*dc->lightlist) * old_maxlights); + } } - for (i = 0; i < dc_numlights; i++) + for (i = 0; i < dc->numlights; i++) { fixed_t leftheight, rightheight; light = &frontsector->lightlist[i]; - rlight = &dc_lightlist[i]; - leftheight = P_GetLightZAt(light, ds-> leftpos.x, ds-> leftpos.y); - rightheight = P_GetLightZAt(light, ds->rightpos.x, ds->rightpos.y); + rlight = &dc->lightlist[i]; + leftheight = P_GetLightZAt(light, drawseg-> leftpos.x, drawseg-> leftpos.y); + rightheight = P_GetLightZAt(light, drawseg->rightpos.x, drawseg->rightpos.y); leftheight -= viewz; rightheight -= viewz; - rlight->height = (centeryfrac) - FixedMul(leftheight , ds->scale1); - rlight->heightstep = (centeryfrac) - FixedMul(rightheight, ds->scale2); + rlight->height = (centeryfrac) - FixedMul(leftheight , drawseg->scale1); + rlight->heightstep = (centeryfrac) - FixedMul(rightheight, drawseg->scale2); rlight->heightstep = (rlight->heightstep-rlight->height)/(range); //if (x1 > ds->x1) //rlight->height -= (x1 - ds->x1)*rlight->heightstep; @@ -275,8 +287,8 @@ static void R_RenderMaskedSegLoop(drawseg_t *ds, INT32 x1, INT32 x2, INT32 texnu else back = backsector; - if (ds->curline->sidedef->repeatcnt) - repeats = 1 + ds->curline->sidedef->repeatcnt; + if (drawseg->curline->sidedef->repeatcnt) + repeats = 1 + drawseg->curline->sidedef->repeatcnt; else if (ldef->flags & ML_WRAPMIDTEX) { fixed_t high, low; @@ -302,41 +314,41 @@ static void R_RenderMaskedSegLoop(drawseg_t *ds, INT32 x1, INT32 x2, INT32 texnu { if (times > 0) { - rw_scalestep = ds->scalestep; - spryscale = ds->scale1 + (x1 - ds->x1)*rw_scalestep; - if (dc_numlights) + rw_scalestep = drawseg->scalestep; + spryscale = drawseg->scale1 + (x1 - drawseg->x1)*rw_scalestep; + if (dc->numlights) { // reset all lights to their starting heights - for (i = 0; i < dc_numlights; i++) + for (i = 0; i < dc->numlights; i++) { - rlight = &dc_lightlist[i]; + rlight = &dc->lightlist[i]; rlight->height = rlight->startheight; } } } - dc_texheight = textureheight[texnum]>>FRACBITS; + dc->texheight = textureheight[texnum]>>FRACBITS; // draw the columns - for (dc_x = x1; dc_x <= x2; dc_x++) + for (dc->x = x1; dc->x <= x2; dc->x++) { - dc_texturemid = ds->maskedtextureheight[dc_x]; + dc->texturemid = drawseg->maskedtextureheight[dc->x]; if (curline->linedef->flags & ML_MIDPEG) - dc_texturemid += (textureheight[texnum])*times + textureheight[texnum]; + dc->texturemid += (textureheight[texnum])*times + textureheight[texnum]; else - dc_texturemid -= (textureheight[texnum])*times; + dc->texturemid -= (textureheight[texnum])*times; // calculate lighting - if (maskedtexturecol[dc_x] != INT16_MAX) + if (maskedtexturecol[dc->x] != INT16_MAX) { // Check for overflows first - if (R_OverflowTest()) + if (R_OverflowTest(dc)) { // Eh, no, go away, don't waste our time - if (dc_numlights) + if (dc->numlights) { - for (i = 0; i < dc_numlights; i++) + for (i = 0; i < dc->numlights; i++) { - rlight = &dc_lightlist[i]; + rlight = &dc->lightlist[i]; rlight->height += rlight->heightstep; } } @@ -344,27 +356,27 @@ static void R_RenderMaskedSegLoop(drawseg_t *ds, INT32 x1, INT32 x2, INT32 texnu continue; } - if (dc_numlights) + if (dc->numlights) { lighttable_t **xwalllights; sprbotscreen = INT32_MAX; - sprtopscreen = windowtop = (centeryfrac - FixedMul(dc_texturemid, spryscale)); + sprtopscreen = windowtop = (centeryfrac - FixedMul(dc->texturemid, spryscale)); realbot = windowbottom = FixedMul(textureheight[texnum], spryscale) + sprtopscreen; - dc_iscale = 0xffffffffu / (unsigned)spryscale; + dc->iscale = 0xffffffffu / (unsigned)spryscale; // draw the texture - col = (column_t *)((UINT8 *)R_GetColumn(texnum, maskedtexturecol[dc_x]) - 3); + col = (column_t *)((UINT8 *)R_GetColumn(texnum, maskedtexturecol[dc->x]) - 3); if (brightmapped) { - bmCol = (column_t *)((UINT8 *)R_GetBrightmapColumn(texnum, maskedtexturecol[dc_x]) - 3); + bmCol = (column_t *)((UINT8 *)R_GetBrightmapColumn(texnum, maskedtexturecol[dc->x]) - 3); } - for (i = 0; i < dc_numlights; i++) + for (i = 0; i < dc->numlights; i++) { - rlight = &dc_lightlist[i]; + rlight = &dc->lightlist[i]; if ((rlight->flags & FOF_NOSHADE)) continue; @@ -393,13 +405,13 @@ static void R_RenderMaskedSegLoop(drawseg_t *ds, INT32 x1, INT32 x2, INT32 texnu if (height <= windowtop) { - dc_colormap = rlight->rcolormap; - dc_lightmap = xwalllights[pindex]; - dc_fullbright = colormaps; + dc->colormap = rlight->rcolormap; + dc->lightmap = xwalllights[pindex]; + dc->fullbright = colormaps; if (encoremap && !(ldef->flags & ML_TFERLINE)) { - dc_colormap += COLORMAP_REMAPOFFSET; - dc_fullbright += COLORMAP_REMAPOFFSET; + dc->colormap += COLORMAP_REMAPOFFSET; + dc->fullbright += COLORMAP_REMAPOFFSET; } continue; } @@ -408,29 +420,29 @@ static void R_RenderMaskedSegLoop(drawseg_t *ds, INT32 x1, INT32 x2, INT32 texnu if (windowbottom >= realbot) { windowbottom = realbot; - colfunc_2s(col, bmCol, -1); - for (i++; i < dc_numlights; i++) + colfunc_2s(dc, col, bmCol, -1); + for (i++; i < dc->numlights; i++) { - rlight = &dc_lightlist[i]; + rlight = &dc->lightlist[i]; rlight->height += rlight->heightstep; } continue; } - colfunc_2s(col, bmCol, -1); + colfunc_2s(dc, col, bmCol, -1); windowtop = windowbottom + 1; - dc_colormap = rlight->rcolormap; - dc_lightmap = xwalllights[pindex]; - dc_fullbright = colormaps; + dc->colormap = rlight->rcolormap; + dc->lightmap = xwalllights[pindex]; + dc->fullbright = colormaps; if (encoremap && !(ldef->flags & ML_TFERLINE)) { - dc_colormap += COLORMAP_REMAPOFFSET; - dc_fullbright += COLORMAP_REMAPOFFSET; + dc->colormap += COLORMAP_REMAPOFFSET; + dc->fullbright += COLORMAP_REMAPOFFSET; } } windowbottom = realbot; if (windowtop < windowbottom) - colfunc_2s(col, bmCol, -1); + colfunc_2s(dc, col, bmCol, -1); spryscale += rw_scalestep; continue; @@ -442,27 +454,27 @@ static void R_RenderMaskedSegLoop(drawseg_t *ds, INT32 x1, INT32 x2, INT32 texnu if (pindex >= MAXLIGHTSCALE) pindex = MAXLIGHTSCALE - 1; - dc_colormap = walllights[pindex]; - dc_lightmap = walllights[pindex]; - dc_fullbright = colormaps; + dc->colormap = walllights[pindex]; + dc->lightmap = walllights[pindex]; + dc->fullbright = colormaps; if (encoremap && !(ldef->flags & ML_TFERLINE)) { - dc_colormap += COLORMAP_REMAPOFFSET; - dc_fullbright += COLORMAP_REMAPOFFSET; + dc->colormap += COLORMAP_REMAPOFFSET; + dc->fullbright += COLORMAP_REMAPOFFSET; } if (frontsector->extra_colormap) - dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps); + dc->colormap = frontsector->extra_colormap->colormap + (dc->colormap - colormaps); - sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale); - dc_iscale = 0xffffffffu / (unsigned)spryscale; + sprtopscreen = centeryfrac - FixedMul(dc->texturemid, spryscale); + dc->iscale = 0xffffffffu / (unsigned)spryscale; // draw the texture - col = (column_t *)((UINT8 *)R_GetColumn(texnum, maskedtexturecol[dc_x]) - 3); + col = (column_t *)((UINT8 *)R_GetColumn(texnum, maskedtexturecol[dc->x]) - 3); if (brightmapped) { - bmCol = (column_t *)((UINT8 *)R_GetBrightmapColumn(texnum, maskedtexturecol[dc_x]) - 3); + bmCol = (column_t *)((UINT8 *)R_GetBrightmapColumn(texnum, maskedtexturecol[dc->x]) - 3); } #if 0 // Disabling this allows inside edges to render below the planes, for until the clipping is fixed to work right when POs are near the camera. -Red @@ -518,37 +530,37 @@ static void R_RenderMaskedSegLoop(drawseg_t *ds, INT32 x1, INT32 x2, INT32 texnu } else #endif - colfunc_2s(col, bmCol, -1); + colfunc_2s(dc, col, bmCol, -1); } spryscale += rw_scalestep; } } } -static void R_RenderMaskedSegLoopDebug(drawseg_t *ds, INT32 x1, INT32 x2, void (*colfunc_2s)(column_t *, column_t *, INT32)) +static void R_RenderMaskedSegLoopDebug(drawcolumndata_t* dc, drawseg_t *ds, INT32 x1, INT32 x2, void (*colfunc_2s)(drawcolumndata_t*, column_t *, column_t *, INT32)) { column_t *col; - dc_lightmap = scalelight[LIGHTLEVELS - 1][0]; // max brightness + dc->lightmap = scalelight[LIGHTLEVELS - 1][0]; // max brightness // draw the columns - for (dc_x = x1; dc_x <= x2; dc_x++) + for (dc->x = x1; dc->x <= x2; dc->x++) { - if (maskedtexturecol[dc_x] != INT16_MAX) + if (maskedtexturecol[dc->x] != INT16_MAX) { - dc_texturemid = ds->maskedtextureheight[dc_x]; + dc->texturemid = ds->maskedtextureheight[dc->x]; - if (R_OverflowTest()) + if (R_OverflowTest(dc)) { spryscale += rw_scalestep; continue; } - sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale); - dc_iscale = 0xffffffffu / (unsigned)spryscale; + sprtopscreen = centeryfrac - FixedMul(dc->texturemid, spryscale); + dc->iscale = 0xffffffffu / (unsigned)spryscale; - col = (column_t *)((UINT8 *)R_GetColumn(g_texturenum_dbgline, maskedtexturecol[dc_x]) - 3); - colfunc_2s(col, NULL, -1); + col = (column_t *)((UINT8 *)R_GetColumn(g_texturenum_dbgline, maskedtexturecol[dc->x]) - 3); + colfunc_2s(dc, col, NULL, -1); } spryscale += rw_scalestep; @@ -571,7 +583,7 @@ static INT32 R_GetTwoSidedMidTexture(seg_t *line) return R_GetTextureNum(texture); } -static boolean R_CheckBlendMode(const line_t *ldef, boolean brightmapped) +static boolean R_CheckBlendMode(drawcolumndata_t* dc, const line_t *ldef, boolean brightmapped) { transnum_t transtable = NUMTRANSMAPS; patchalphastyle_t blendmode = AST_COPY; @@ -598,7 +610,7 @@ static boolean R_CheckBlendMode(const line_t *ldef, boolean brightmapped) } else if (transtable != NUMTRANSMAPS && (blendmode || transtable)) { - dc_transmap = R_GetBlendTable(blendmode, transtable); + dc->transmap = R_GetBlendTable(blendmode, transtable); R_SetColumnFunc(COLDRAWFUNC_FUZZY, brightmapped); } else @@ -611,25 +623,26 @@ static boolean R_CheckBlendMode(const line_t *ldef, boolean brightmapped) if (curline->polyseg->translucency >= NUMTRANSMAPS) return false; - dc_transmap = R_GetTranslucencyTable(curline->polyseg->translucency); + dc->transmap = R_GetTranslucencyTable(curline->polyseg->translucency); R_SetColumnFunc(COLDRAWFUNC_FUZZY, brightmapped); } return true; } -void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) +void R_RenderMaskedSegRange(drawseg_t *drawseg, INT32 x1, INT32 x2) { INT32 texnum; - void (*colfunc_2s)(column_t *, column_t *, INT32); + void (*colfunc_2s)(drawcolumndata_t*, column_t *, column_t *, INT32); line_t *ldef; - const boolean debug = R_IsDebugLine(ds->curline); + const boolean debug = R_IsDebugLine(drawseg->curline); + drawcolumndata_t *dc = &g_dc; // Calculate light table. // Use different light tables // for horizontal / vertical / diagonal. Diagonal? // OPTIMIZE: get rid of LIGHTSEGSHIFT globally - curline = ds->curline; + curline = drawseg->curline; frontsector = curline->frontsector; backsector = curline->backsector; @@ -640,13 +653,13 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) R_CheckDebugHighlight(SW_HI_MIDTEXTURES); - if (debug == false && R_CheckBlendMode(ldef, R_TextureHasBrightmap(texnum)) == false) + if (debug == false && R_CheckBlendMode(dc, ldef, R_TextureHasBrightmap(texnum)) == false) { return; // does not render } - rw_scalestep = ds->scalestep; - spryscale = ds->scale1 + (x1 - ds->x1)*rw_scalestep; + rw_scalestep = drawseg->scalestep; + spryscale = drawseg->scale1 + (x1 - drawseg->x1)*rw_scalestep; // Texture must be cached before setting colfunc_2s, // otherwise texture[texnum]->holes may be false when it shouldn't be @@ -670,43 +683,43 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) lengthcol = textures[texnum]->height; } - maskedtexturecol = ds->maskedtexturecol; + maskedtexturecol = drawseg->maskedtexturecol; - mfloorclip = ds->sprbottomclip; - mceilingclip = ds->sprtopclip; + mfloorclip = drawseg->sprbottomclip; + mceilingclip = drawseg->sprtopclip; if (debug) { colfunc = R_DrawColumn_Flat_8; - r8_flatcolor = R_DebugLineColor(ldef); - R_RenderMaskedSegLoopDebug(ds, x1, x2, colfunc_2s); + dc->r8_flatcolor = R_DebugLineColor(ldef); + R_RenderMaskedSegLoopDebug(dc, drawseg, x1, x2, colfunc_2s); } else { - R_RenderMaskedSegLoop(ds, x1, x2, texnum, colfunc_2s); + R_RenderMaskedSegLoop(dc, drawseg, x1, x2, texnum, colfunc_2s); } R_SetColumnFunc(BASEDRAWFUNC, false); } // Loop through R_DrawMaskedColumn calls -static void R_DrawRepeatMaskedColumn(column_t *col, column_t *bm, INT32 baseclip) +static void R_DrawRepeatMaskedColumn(drawcolumndata_t* dc, column_t *col, column_t *bm, INT32 baseclip) { while (sprtopscreen < sprbotscreen) { - R_DrawMaskedColumn(col, bm, baseclip); - if ((INT64)sprtopscreen + dc_texheight*spryscale > (INT64)INT32_MAX) // prevent overflow + R_DrawMaskedColumn(dc, col, bm, baseclip); + if ((INT64)sprtopscreen + dc->texheight*spryscale > (INT64)INT32_MAX) // prevent overflow sprtopscreen = INT32_MAX; else - sprtopscreen += dc_texheight*spryscale; + sprtopscreen += dc->texheight*spryscale; } } -static void R_DrawRepeatFlippedMaskedColumn(column_t *col, column_t *bm, INT32 baseclip) +static void R_DrawRepeatFlippedMaskedColumn(drawcolumndata_t* dc, column_t *col, column_t *bm, INT32 baseclip) { do { - R_DrawFlippedMaskedColumn(col, bm, baseclip); - sprtopscreen += dc_texheight*spryscale; + R_DrawFlippedMaskedColumn(dc, col, bm, baseclip); + sprtopscreen += dc->texheight*spryscale; } while (sprtopscreen < sprbotscreen); } @@ -751,8 +764,9 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) INT32 oldx = -1; fixed_t left_top, left_bottom; // needed here for slope skewing pslope_t *skewslope = NULL; + drawcolumndata_t *dc = &g_dc; - void (*colfunc_2s) (column_t *, column_t *, INT32); + void (*colfunc_2s) (drawcolumndata_t*, column_t *, column_t *, INT32); // Calculate light table. // Use different light tables @@ -787,7 +801,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) INT32 trans = (10*((256+12) - pfloor->alpha))/255; if (trans >= 10) return; // Don't even draw it - if (!(dc_transmap = R_GetBlendTable(pfloor->blend, trans))) + if (!(dc->transmap = R_GetBlendTable(pfloor->blend, trans))) fuzzy = false; // Opaque } @@ -806,25 +820,29 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) rw_scalestep = ds->scalestep; spryscale = ds->scale1 + (x1 - ds->x1)*rw_scalestep; - dc_numlights = 0; + dc->numlights = 0; if (frontsector->numlights) { - dc_numlights = frontsector->numlights; - if (dc_numlights > dc_maxlights) + dc->numlights = frontsector->numlights; + if (dc->numlights > dc->maxlights) { - dc_maxlights = dc_numlights; - dc_lightlist = static_cast( - Z_Realloc(dc_lightlist, sizeof (*dc_lightlist) * dc_maxlights, PU_STATIC, NULL) - ); + r_lightlist_t* old_lightlist = dc->lightlist; + INT32 old_maxlights = dc->maxlights; + dc->maxlights = dc->numlights; + dc->lightlist = static_cast(Z_Frame_Alloc(sizeof (*dc->lightlist) * dc->maxlights)); + if (old_lightlist != nullptr) + { + M_Memcpy(dc->lightlist, old_lightlist, sizeof (*dc->lightlist) * old_maxlights); + } } - for (i = p = 0; i < dc_numlights; i++) + for (i = p = 0; i < dc->numlights; i++) { fixed_t leftheight, rightheight; fixed_t pfloorleft, pfloorright; INT64 overflow_test; light = &frontsector->lightlist[i]; - rlight = &dc_lightlist[p]; + rlight = &dc->lightlist[p]; #define SLOPEPARAMS(slope, end1, end2, normalheight) \ end1 = P_GetZAt(slope, ds-> leftpos.x, ds-> leftpos.y, normalheight); \ @@ -838,7 +856,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) SLOPEPARAMS(*pfloor->t_slope, pfloorleft, pfloorright, *pfloor->topheight) - if (leftheight > pfloorleft && rightheight > pfloorright && i+1 < dc_numlights) + if (leftheight > pfloorleft && rightheight > pfloorright && i+1 < dc->numlights) { lightlist_t *nextlight = &frontsector->lightlist[i+1]; if (P_GetZAt(nextlight->slope, ds-> leftpos.x, ds-> leftpos.y, nextlight->height) > pfloorleft @@ -900,7 +918,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) p++; } - dc_numlights = p; + dc->numlights = p; } else { @@ -934,7 +952,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) mfloorclip = ds->sprbottomclip; mceilingclip = ds->sprtopclip; - dc_texheight = textureheight[texnum]>>FRACBITS; + dc->texheight = textureheight[texnum]>>FRACBITS; // calculate both left ends left_top = P_GetFFloorTopZAt (pfloor, ds->leftpos.x, ds->leftpos.y) - viewz; @@ -950,9 +968,9 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) slopeskew = true; if (slopeskew) - dc_texturemid = left_top; + dc->texturemid = left_top; else - dc_texturemid = *pfloor->topheight - viewz; + dc->texturemid = *pfloor->topheight - viewz; if (newline) { @@ -961,7 +979,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) { skewslope = *pfloor->b_slope; // skew using bottom slope if (slopeskew) - dc_texturemid = left_bottom; + dc->texturemid = left_bottom; else offsetvalue -= *pfloor->topheight - *pfloor->bottomheight; } @@ -973,7 +991,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) { skewslope = *pfloor->b_slope; // skew using bottom slope if (slopeskew) - dc_texturemid = left_bottom; + dc->texturemid = left_bottom; else offsetvalue -= *pfloor->topheight - *pfloor->bottomheight; } @@ -987,7 +1005,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) ffloortextureslide = FixedMul(skewslope->zdelta, FINECOSINE((lineangle-skewslope->xydirection)>>ANGLETOFINESHIFT)); } - dc_texturemid += offsetvalue; + dc->texturemid += offsetvalue; // Texture must be cached before setting colfunc_2s, // otherwise texture[texnum]->holes may be false when it shouldn't be @@ -1033,14 +1051,14 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) } // draw the columns - for (dc_x = x1; dc_x <= x2; dc_x++) + for (dc->x = x1; dc->x <= x2; dc->x++) { - if (maskedtexturecol[dc_x] != INT16_MAX) + if (maskedtexturecol[dc->x] != INT16_MAX) { if (ffloortextureslide) { // skew FOF walls if (oldx != -1) - dc_texturemid += FixedMul(ffloortextureslide, (maskedtexturecol[oldx]-maskedtexturecol[dc_x])<texturemid += FixedMul(ffloortextureslide, (maskedtexturecol[oldx]-maskedtexturecol[dc->x])<x; } // Calculate bounds // clamp the values if necessary to avoid overflows and rendering glitches caused by them @@ -1058,11 +1076,11 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) // SoM: If column is out of range, why bother with it?? if (windowbottom < topbounds || windowtop > bottombounds) { - if (dc_numlights) + if (dc->numlights) { - for (i = 0; i < dc_numlights; i++) + for (i = 0; i < dc->numlights; i++) { - rlight = &dc_lightlist[i]; + rlight = &dc->lightlist[i]; rlight->height += rlight->heightstep; if (rlight->flags & FOF_CUTLEVEL) rlight->botheight += rlight->botheightstep; @@ -1072,31 +1090,31 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) continue; } - dc_iscale = 0xffffffffu / (unsigned)spryscale; + dc->iscale = 0xffffffffu / (unsigned)spryscale; // Get data for the column - col = (column_t *)((UINT8 *)R_GetColumn(texnum,maskedtexturecol[dc_x]) - 3); + col = (column_t *)((UINT8 *)R_GetColumn(texnum,maskedtexturecol[dc->x]) - 3); if (brightmapped) { - bmCol = (column_t *)((UINT8 *)R_GetBrightmapColumn(texnum, maskedtexturecol[dc_x]) - 3); + bmCol = (column_t *)((UINT8 *)R_GetBrightmapColumn(texnum, maskedtexturecol[dc->x]) - 3); } // SoM: New code does not rely on R_DrawColumnShadowed_8 which // will (hopefully) put less strain on the stack. - if (dc_numlights) + if (dc->numlights) { lighttable_t **xwalllights; fixed_t height; fixed_t bheight = 0; INT32 solid = 0; - for (i = 0; i < dc_numlights; i++) + for (i = 0; i < dc->numlights; i++) { // Check if the current light effects the colormap/lightlevel - rlight = &dc_lightlist[i]; + rlight = &dc->lightlist[i]; xwalllights = NULL; - if (!(dc_lightlist[i].flags & FOF_NOSHADE)) + if (!(dc->lightlist[i].flags & FOF_NOSHADE)) { lightnum = R_AdjustLightLevel(rlight->lightnum); @@ -1161,13 +1179,13 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) { if (xwalllights) { - dc_colormap = rlight->rcolormap; - dc_lightmap = xwalllights[pindex]; - dc_fullbright = colormaps; + dc->colormap = rlight->rcolormap; + dc->lightmap = xwalllights[pindex]; + dc->fullbright = colormaps; if (encoremap && !(curline->linedef->flags & ML_TFERLINE)) { - dc_colormap += COLORMAP_REMAPOFFSET; - dc_fullbright += COLORMAP_REMAPOFFSET; + dc->colormap += COLORMAP_REMAPOFFSET; + dc->fullbright += COLORMAP_REMAPOFFSET; } } if (solid && windowtop < bheight) @@ -1180,10 +1198,10 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) { windowbottom = sprbotscreen; // draw the texture - colfunc_2s (col, bmCol, -1); - for (i++; i < dc_numlights; i++) + colfunc_2s (dc, col, bmCol, -1); + for (i++; i < dc->numlights; i++) { - rlight = &dc_lightlist[i]; + rlight = &dc->lightlist[i]; rlight->height += rlight->heightstep; if (rlight->flags & FOF_CUTLEVEL) rlight->botheight += rlight->botheightstep; @@ -1191,27 +1209,27 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) continue; } // draw the texture - colfunc_2s (col, bmCol, -1); + colfunc_2s (dc, col, bmCol, -1); if (solid) windowtop = bheight; else windowtop = windowbottom + 1; if (xwalllights) { - dc_colormap = rlight->rcolormap; - dc_lightmap = xwalllights[pindex]; - dc_fullbright = colormaps; + dc->colormap = rlight->rcolormap; + dc->lightmap = xwalllights[pindex]; + dc->fullbright = colormaps; if (encoremap && !(curline->linedef->flags & ML_TFERLINE)) { - dc_colormap += COLORMAP_REMAPOFFSET; - dc_fullbright += COLORMAP_REMAPOFFSET; + dc->colormap += COLORMAP_REMAPOFFSET; + dc->fullbright += COLORMAP_REMAPOFFSET; } } } windowbottom = sprbotscreen; // draw the texture, if there is any space left if (windowtop < windowbottom) - colfunc_2s (col, bmCol, -1); + colfunc_2s (dc, col, bmCol, -1); spryscale += rw_scalestep; continue; @@ -1223,23 +1241,23 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) if (pindex >= MAXLIGHTSCALE) pindex = MAXLIGHTSCALE - 1; - dc_colormap = walllights[pindex]; - dc_lightmap = walllights[pindex]; - dc_fullbright = colormaps; + dc->colormap = walllights[pindex]; + dc->lightmap = walllights[pindex]; + dc->fullbright = colormaps; if (encoremap && !(curline->linedef->flags & ML_TFERLINE)) { - dc_colormap += COLORMAP_REMAPOFFSET; - dc_fullbright += COLORMAP_REMAPOFFSET; + dc->colormap += COLORMAP_REMAPOFFSET; + dc->fullbright += COLORMAP_REMAPOFFSET; } if (pfloor->fofflags & FOF_FOG && pfloor->master->frontsector->extra_colormap) - dc_colormap = pfloor->master->frontsector->extra_colormap->colormap + (dc_colormap - colormaps); + dc->colormap = pfloor->master->frontsector->extra_colormap->colormap + (dc->colormap - colormaps); else if (frontsector->extra_colormap) - dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps); + dc->colormap = frontsector->extra_colormap->colormap + (dc->colormap - colormaps); // draw the texture - colfunc_2s (col, bmCol, -1); + colfunc_2s (dc, col, bmCol, -1); spryscale += rw_scalestep; } } @@ -1291,19 +1309,21 @@ UINT32 nombre = 100000; #endif //profile stuff --------------------------------------------------------- -static void R_DrawWallColumn(INT32 yl, INT32 yh, fixed_t mid, fixed_t texturecolumn, INT32 texture, boolean brightmapped) +static void R_DrawWallColumn(drawcolumndata_t* dc, INT32 yl, INT32 yh, fixed_t mid, fixed_t texturecolumn, INT32 texture, boolean brightmapped) { - dc_yl = yl; - dc_yh = yh; - dc_texturemid = mid; - dc_source = R_GetColumn(texture, texturecolumn); - dc_brightmap = (brightmapped ? R_GetBrightmapColumn(texture, texturecolumn) : NULL); - dc_texheight = textureheight[texture] >> FRACBITS; - R_SetColumnFunc(colfunctype, dc_brightmap != NULL); - colfunc(); + dc->yl = yl; + dc->yh = yh; + dc->texturemid = mid; + dc->source = R_GetColumn(texture, texturecolumn); + dc->brightmap = (brightmapped ? R_GetBrightmapColumn(texture, texturecolumn) : NULL); + dc->texheight = textureheight[texture] >> FRACBITS; + R_SetColumnFunc(colfunctype, dc->brightmap != NULL); + coldrawfunc_t* colfunccopy = colfunc; + drawcolumndata_t dc_copy = *dc; + colfunccopy(const_cast(&dc_copy)); } -static void R_RenderSegLoop (void) +static void R_RenderSegLoop (drawcolumndata_t* dc) { angle_t angle; size_t pindex; @@ -1501,30 +1521,30 @@ static void R_RenderSegLoop (void) if (pindex >= MAXLIGHTSCALE) pindex = MAXLIGHTSCALE-1; - dc_colormap = walllights[pindex]; - dc_lightmap = walllights[pindex]; - dc_fullbright = colormaps; + dc->colormap = walllights[pindex]; + dc->lightmap = walllights[pindex]; + dc->fullbright = colormaps; if (encoremap && !(curline->linedef->flags & ML_TFERLINE)) { - dc_colormap += COLORMAP_REMAPOFFSET; - dc_fullbright += COLORMAP_REMAPOFFSET; + dc->colormap += COLORMAP_REMAPOFFSET; + dc->fullbright += COLORMAP_REMAPOFFSET; } - dc_x = rw_x; - dc_iscale = 0xffffffffu / (unsigned)rw_scale; + dc->x = rw_x; + dc->iscale = 0xffffffffu / (unsigned)rw_scale; if (frontsector->extra_colormap) - dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps); + dc->colormap = frontsector->extra_colormap->colormap + (dc->colormap - colormaps); } - if (dc_numlights) + if (dc->numlights) { lighttable_t **xwalllights; - for (i = 0; i < dc_numlights; i++) + for (i = 0; i < dc->numlights; i++) { INT32 lightnum; - lightnum = (dc_lightlist[i].lightlevel >> LIGHTSEGSHIFT); + lightnum = (dc->lightlist[i].lightlevel >> LIGHTSEGSHIFT); - if (dc_lightlist[i].extra_colormap) + if (dc->lightlist[i].extra_colormap) ; else if (P_ApplyLightOffset(lightnum, curline->frontsector)) lightnum += curline->lightOffset; @@ -1543,10 +1563,10 @@ static void R_RenderSegLoop (void) if (pindex >= MAXLIGHTSCALE) pindex = MAXLIGHTSCALE-1; - if (dc_lightlist[i].extra_colormap) - dc_lightlist[i].rcolormap = dc_lightlist[i].extra_colormap->colormap + (xwalllights[pindex] - colormaps); + if (dc->lightlist[i].extra_colormap) + dc->lightlist[i].rcolormap = dc->lightlist[i].extra_colormap->colormap + (xwalllights[pindex] - colormaps); else - dc_lightlist[i].rcolormap = xwalllights[pindex]; + dc->lightlist[i].rcolormap = xwalllights[pindex]; R_SetColumnFunc(COLDRAWFUNC_SHADOWED, false); } @@ -1575,7 +1595,7 @@ static void R_RenderSegLoop (void) // single sided line if (yl <= yh && yh >= 0 && yl < viewheight) { - R_DrawWallColumn(yl, yh, rw_midtexturemid, texturecolumn, midtexture, midbrightmapped); + R_DrawWallColumn(dc, yl, yh, rw_midtexturemid, texturecolumn, midtexture, midbrightmapped); // dont draw anything more for this column, since // a midtexture blocks the view @@ -1614,7 +1634,7 @@ static void R_RenderSegLoop (void) } else if (mid >= 0) // safe to draw top texture { - R_DrawWallColumn(yl, mid, rw_toptexturemid, texturecolumn, toptexture, topbrightmapped); + R_DrawWallColumn(dc, yl, mid, rw_toptexturemid, texturecolumn, toptexture, topbrightmapped); ceilingclip[rw_x] = (INT16)mid; } else if (!rw_ceilingmarked) // entirely off top of screen @@ -1645,7 +1665,7 @@ static void R_RenderSegLoop (void) } else if (mid < viewheight) // safe to draw bottom texture { - R_DrawWallColumn(mid, yh, rw_bottomtexturemid, texturecolumn, bottomtexture, bottombrightmapped); + R_DrawWallColumn(dc, mid, yh, rw_bottomtexturemid, texturecolumn, bottomtexture, bottombrightmapped); floorclip[rw_x] = (INT16)mid; } else if (!rw_floormarked) // entirely off bottom of screen @@ -1671,13 +1691,13 @@ static void R_RenderSegLoop (void) } } - if (dc_numlights) + if (dc->numlights) { - for (i = 0; i < dc_numlights; i++) + for (i = 0; i < dc->numlights; i++) { - dc_lightlist[i].height += dc_lightlist[i].heightstep; - if (dc_lightlist[i].flags & FOF_CUTSOLIDS) - dc_lightlist[i].botheight += dc_lightlist[i].botheightstep; + dc->lightlist[i].height += dc->lightlist[i].heightstep; + if (dc->lightlist[i].flags & FOF_CUTSOLIDS) + dc->lightlist[i].botheight += dc->lightlist[i].botheightstep; } } @@ -1741,6 +1761,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) fixed_t ceilingfrontslide, floorfrontslide, ceilingbackslide, floorbackslide; static size_t maxdrawsegs = 0; const INT32 twosidedmidtexture = R_GetTwoSidedMidTexture(curline); + drawcolumndata_t dc {0}; ZoneScoped; @@ -1755,6 +1776,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (ds_p == drawsegs+maxdrawsegs) { + TracyMessageL("Resizing drawsegs"); size_t curpos = curdrawsegs - drawsegs; size_t pos = ds_p - drawsegs; size_t newmax = maxdrawsegs ? maxdrawsegs*2 : 128; @@ -1800,6 +1822,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) size_t need = (rw_stopx - start)*4 + pos; if (need > maxopenings) { + TracyMessageL("Resizing openings"); drawseg_t *ds; //needed for fix from *cough* zdoom *cough* INT16 *oldopenings = openings; INT16 *oldlast = lastopening; @@ -2583,25 +2606,20 @@ void R_StoreWallRange(INT32 start, INT32 stop) } } - dc_numlights = 0; + dc.numlights = 0; if (frontsector->numlights) { - dc_numlights = frontsector->numlights; - if (dc_numlights >= dc_maxlights) - { - dc_maxlights = dc_numlights; - dc_lightlist = static_cast( - Z_Realloc(dc_lightlist, sizeof (*dc_lightlist) * dc_maxlights, PU_STATIC, NULL) - ); - } + dc.numlights = frontsector->numlights; + dc.maxlights = dc.numlights; + dc.lightlist = static_cast(Z_Frame_Alloc(sizeof(*dc.lightlist) * dc.maxlights)); - for (i = p = 0; i < dc_numlights; i++) + for (i = p = 0; i < dc.numlights; i++) { fixed_t leftheight, rightheight; light = &frontsector->lightlist[i]; - rlight = &dc_lightlist[p]; + rlight = &dc.lightlist[p]; leftheight = P_GetLightZAt(light, segleft.x, segleft.y); rightheight = P_GetLightZAt(light, segright.x, segright.y); @@ -2621,7 +2639,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (leftheight < worldbottom && rightheight < worldbottomslope) continue; - if (leftheight > worldtop && rightheight > worldtopslope && i+1 < dc_numlights && frontsector->lightlist[i+1].height > frontsector->ceilingheight) + if (leftheight > worldtop && rightheight > worldtopslope && i+1 < dc.numlights && frontsector->lightlist[i+1].height > frontsector->ceilingheight) continue; } @@ -2656,7 +2674,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) p++; } - dc_numlights = p; + dc.numlights = p; } if (numffloors) @@ -2941,7 +2959,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) rw_tsilheight = &(ds_p->tsilheight); rw_bsilheight = &(ds_p->bsilheight); - R_RenderSegLoop(); + R_RenderSegLoop(&dc); R_SetColumnFunc(BASEDRAWFUNC, false); if (g_portal) // if curline is a portal, set portalrender for drawseg diff --git a/src/r_skins.c b/src/r_skins.c index 30c4fa487..938f963f5 100644 --- a/src/r_skins.c +++ b/src/r_skins.c @@ -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; - + } } diff --git a/src/r_splats.c b/src/r_splats.c index c2aae1a93..0b416ec6d 100644 --- a/src/r_splats.c +++ b/src/r_splats.c @@ -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) diff --git a/src/r_textures.c b/src/r_textures.c index f384b6c45..80e7204d7 100644 --- a/src/r_textures.c +++ b/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; } } diff --git a/src/r_textures.h b/src/r_textures.h index b0ca2a6a3..530d2144b 100644 --- a/src/r_textures.h +++ b/src/r_textures.h @@ -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); diff --git a/src/r_things.cpp b/src/r_things.cpp index 67e7de57f..0ecf02c12 100644 --- a/src/r_things.cpp +++ b/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<texturemid = basetexturemid - (topdelta<yl]) + { + drawcolumndata_t dc_copy = *dc; + coldrawfunc_t* colfunccopy = colfunc; + colfunccopy(const_cast(&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(ZZ_Alloc(column->length)); - for (s = (UINT8 *)column+2+column->length, d = dc_source; d < dc_source+column->length; --s) + dc->source = static_cast(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(ZZ_Alloc(brightmap->length)); - for (s = (UINT8 *)brightmap+2+brightmap->length, d = dc_brightmap; d < dc_brightmap+brightmap->length; --s) + dc->brightmap = static_cast(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<texturemid = basetexturemid - (topdelta<yl]) + { + drawcolumndata_t dc_copy = *dc; + coldrawfunc_t* colfunccopy = colfunc; + colfunccopy(const_cast(&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(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; diff --git a/src/r_things.h b/src/r_things.h index 8f74f5135..5ad5687e1 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -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 diff --git a/src/screen.c b/src/screen.c index bc4c51c78..e49c939cb 100644 --- a/src/screen.c +++ b/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 // ------------------ diff --git a/src/screen.h b/src/screen.h index f80a41c7d..a91b0fd50 100644 --- a/src/screen.h +++ b/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 // ----- diff --git a/src/sdl/CMakeLists.txt b/src/sdl/CMakeLists.txt index e77b40910..aaf15644e 100644 --- a/src/sdl/CMakeLists.txt +++ b/src/sdl/CMakeLists.txt @@ -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 diff --git a/src/sdl/i_system.c b/src/sdl/i_system.cpp similarity index 95% rename from src/sdl/i_system.c rename to src/sdl/i_system.cpp index 733bd0b61..54ba51ed0 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.cpp @@ -23,6 +23,10 @@ /// \file /// \brief SRB2 system stuff for SDL +#include + +#include + #include #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(!M_CheckParm("-noconsole")); + framebuffer = static_cast(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(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(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(buf), name); if (hit == NULL) { return -1; } diff --git a/src/sdl/macosx/mac_resources.h b/src/sdl/macosx/mac_resources.h index 727ac9f6b..8297d3d0f 100644 --- a/src/sdl/macosx/mac_resources.h +++ b/src/sdl/macosx/mac_resources.h @@ -1,5 +1,15 @@ #ifndef __MAC_RESOURCES_H__ #define __MAC_RESOURCES_H__ +#ifdef __cplusplus +extern "C" +{ +#endif + void OSX_GetResourcesPath(char * buffer); -#endif \ No newline at end of file + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/typedef.h b/src/typedef.h index 79527c2d6..f6979f09d 100644 --- a/src/typedef.h +++ b/src/typedef.h @@ -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); diff --git a/src/z_zone.c b/src/z_zone.c index 8701848c6..79eaabd17 100644 --- a/src/z_zone.c +++ b/src/z_zone.c @@ -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); } // -----------------