Merge remote-tracking branch 'gzdoom/master' into master202008

This commit is contained in:
Major Cooke 2020-10-10 10:08:19 -05:00
commit 6dc35238d3
261 changed files with 6301 additions and 3199 deletions

View file

@ -1,3 +1,6 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
# Locate SDL2 library
# This module defines
# SDL2_LIBRARY, the name of the library to link against
@ -57,19 +60,6 @@
# was not created for redistribution, and exists temporarily pending official
# SDL2 CMake modules.
#=============================================================================
# Copyright 2003-2009 Kitware, Inc.
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)
FIND_PATH(SDL2_INCLUDE_DIR SDL.h
HINTS
$ENV{SDL2DIR}

View file

@ -96,6 +96,8 @@ function(target_architecture output_var)
set(osx_arch_x86_64 TRUE)
elseif("${osx_arch}" STREQUAL "ppc64" AND ppc_support)
set(osx_arch_ppc64 TRUE)
elseif("${osx_arch}" STREQUAL "arm64")
set(osx_arch_arm64 TRUE)
else()
message(FATAL_ERROR "Invalid OS X arch name: ${osx_arch}")
endif()
@ -117,6 +119,10 @@ function(target_architecture output_var)
if(osx_arch_ppc64)
list(APPEND ARCH ppc64)
endif()
if(osx_arch_arm64)
list(APPEND ARCH arm64)
endif()
else()
file(WRITE "${CMAKE_BINARY_DIR}/arch.c" "${archdetect_c_code}")

106
fm_banks/GENMIDI-readme.txt Normal file
View file

@ -0,0 +1,106 @@
DMXOPL3
==================================================================
https://github.com/sneakernets/DMXOPL
==================================================================
New and improved DMX GENMIDI for Doom and sourceports, taking full advantage of
the OPL3 waveforms. This takes things up a notch in terms of timbre.
# Summary
This is a GENMIDI patch for DMX for OPL3 FM synthesis. This patch aims to remedy
the "weak" default instruments to better match the Roland Sound Canvas, most
notably the SC-55 and SC-88. Recommended minimum setup for no note-cuts is
ZDoom 2.8.1 with DOSBOX OPL3 emulator core, with 6 chips emulated.
======FAQ======
# Why OPL3 only?
OPL3 has four additional waveforms - Alternating Sine, Camel Sine, Square, and
Logarithmic Square (Sawtooth). The most interesting of these is the Square wave,
for obvious reasons! This will benefit percussion instruments immensely.
# What did you use for this project?
Hex Editors, OPL3 Bank Editor, Fraggle's Python scripts, Adlib Tracker II,
Edlib, ADLMidi. I also used the following keyboards and devices:
- Yamaha PSR-3 for basic voice ideas
- Yamaha PSS-50 for layered voice ideas
- Yamaha DX-7
- Commodore 64 Music Module
- VRC7 and related chips
- Sound Blaster 16
- Yamaha PCI cards
- Sounds from various SEGA MegaDrive games
=======WOPL FAQ=======
# What's the difference between the WOPL version and the DMX version?
The main difference is with a few instruments that had to be tweaked to work
with DMX. Most of these changes are negligible for General MIDI stuff. To hear
what I intended DMXOPL to sound like in Doom, you'll have to wait for Eternity
Engine's ADLMIDI support to be finalized.
# Any plans for GS/XG support?
Yes. This will take considerable time, and voices will be added as I come across
them in my MIDI files. You can check the progress on those through the XG and GS
branches that I will make (or have already made). As I think the GM set is solid
enough now, save for just a handful of instruments, I can start work on the
other banks.
# Will the WOPL version be usable on any other FM chips?
Depends on the chip, but more than likely the answer is no. YMF262 (and the OPL*
family for that matter) operate differently than most of the other FM chips, and
wouldn't likely transfer over to DX-7 or other instruments without considerable
work, if they would work at all.
# Is the best way to listen to this really through an emulator?
Yes, unfortunately. Unless someone makes an FM chip that can handle 128+
channels, this is likely never to change. If you're using this in your music
projects and you still want to use the real thing, I recommend recording one
track at a time and throwing the result in your favorite DAW - just be sure to
put a highpass filter set to a really low value (I recommend 5 Hz) to get rid
of the offset garbage, lest your mix splatter like crazy.
======Credits======
* Wohlstand, for the OPL3BankEditor
* Bisqwuit, for ADLMidi
* Fraggle, for Chocolate Doom and GENMIDI research, as well as the Python scripts
* SubZ3ro, for AdLib Tracker II
* Esselfortium, for the encouragement and support
* Jimmy, who will include this in the next Adventures of Square release
* The Fat Man, who created the famous 2-op and 4-op patches everyone knows
* Diode Milliampere, who made FM synth popular again
* Patchouli, for keeping my spirits up
* Graf Zahl, for continuing ZDoom as GZDoom
* Randi, for implementing the OPL Emulation in ZDoom
* Fisk, for miscellaneous feedback and MIDIs to test
* Stewboy, for the Ancient Aliens MIDIs to test
* Xaser, who said this patch passes the "Angry Scientist test"
* Minigunner, just because
* Altazimuth, who claims it'll be in Eternity someday (this is now true)
* MTrop
* Quasar, for Eternity Engine
* Glaice, for patch advice
* BlastFrog, for patch advice
* Vogons Forums, for the OPL-3 Research and tools
* AtariAge, for C64 Sound module preset banks
* NintendoAge
* John Chowning, the father of FM synthesis. I hope he can hear this someday.
## Extra Thanks to:
* Doomworld Forums and the respective IRC/DISCORD channels
* The 4th Modulator DISCORD channels
* Giest118, who installed Doom again to listen to this
* Nuke.YKT, for testing this in Raptor, and for the Nuked OPL core
* kode54, who added this to Cog and FB2K, thank you!
* Patch93, who contributed various patches
* OlPainless, who contributed various patches
* Papiezak, who contributed various of patches
* Infurnus, for support
* Leileilol, for support
* MaliceX, for support
* Kuschelmonster, for support
* Anyone who makes music with this thing!
YMF262 forever.

Binary file not shown.

View file

@ -0,0 +1,7 @@
A bank, created from hardcoded instruments, extracted from "fmmidi" project
http://unhaut.x10host.com/fmmidi/
It's license:
This program is released under the "three clauses" BSD license

BIN
fm_banks/fmmidi.wopn Normal file

Binary file not shown.

View file

@ -0,0 +1,8 @@
This bank was created by Wohlstand from imported instruments from the standard
set of insruments pre-included with GEMS program which was a official Sega
music creation system. Original set was not GM. Therefore, imported instruments
are was organized to provide a proper GM set.
Some instruments was a bit modified, some melodic instruments and percussions
are was taken from Wohlstand's xg.wopn bank.

Binary file not shown.

View file

@ -0,0 +1,25 @@
=============
https://github.com/sneakernets/DMXOPN2
https://github.com/papiezak/DMXOPN2
=============
== DMXOPN2 ==
No-nonsense patches for YM2612.
== About ==
After much work on my DMXOPL project, I noticed that a lot of presets that
I created were not compatible with the YM2612, which was the chip I started
with, but quickly dropped. In response, I decided to rectify this by recreating
the best patches from DMXOPL to OPN2 format. Don't expect miracles, as this is
more of a learning experience so I can start working on expanding my FM synth
knowledge.
I chose the name "DMX" not because it works with DMX, but that it will
(hopefully) be of the same quality as the DMXOPL patch. Yeah, not very
descriptive, but names aren't everything.
Watch this space.

View file

@ -844,7 +844,6 @@ set (PCH_SOURCES
gameconfigfile.cpp
gitinfo.cpp
hu_scores.cpp
i_net.cpp
m_cheat.cpp
m_misc.cpp
playsim/p_acs.cpp
@ -1041,6 +1040,7 @@ set (PCH_SOURCES
common/textures/skyboxtexture.cpp
common/textures/animtexture.cpp
common/textures/v_collection.cpp
common/textures/animlib.cpp
common/textures/formats/automaptexture.cpp
common/textures/formats/brightmaptexture.cpp
common/textures/formats/buildtexture.cpp
@ -1059,6 +1059,7 @@ set (PCH_SOURCES
common/textures/formats/shadertexture.cpp
common/textures/formats/tgatexture.cpp
common/textures/formats/stbtexture.cpp
common/textures/formats/anmtexture.cpp
common/textures/hires/hqresize.cpp
common/models/models_md3.cpp
common/models/models_md2.cpp
@ -1091,6 +1092,7 @@ set (PCH_SOURCES
common/utility/zstrformat.cpp
common/utility/name.cpp
common/utility/r_memory.cpp
common/thirdparty/base64.cpp
common/thirdparty/md5.cpp
common/thirdparty/superfasthash.cpp
common/filesystem/filesystem.cpp
@ -1103,6 +1105,7 @@ set (PCH_SOURCES
common/filesystem/file_zip.cpp
common/filesystem/file_pak.cpp
common/filesystem/file_whres.cpp
common/filesystem/file_ssi.cpp
common/filesystem/file_directory.cpp
common/filesystem/resourcefile.cpp
common/engine/cycler.cpp
@ -1111,6 +1114,7 @@ set (PCH_SOURCES
common/engine/sc_man.cpp
common/engine/palettecontainer.cpp
common/engine/stringtable.cpp
common/engine/i_net.cpp
common/engine/i_interface.cpp
common/engine/renderstyle.cpp
common/engine/v_colortables.cpp
@ -1354,6 +1358,15 @@ add_custom_command(TARGET zdoom POST_BUILD
${CMAKE_SOURCE_DIR}/fm_banks/gs-by-papiezak-and-sneakernets.wopn $<TARGET_FILE_DIR:zdoom>/fm_banks/gs-by-papiezak-and-sneakernets.wopn
)
if( WIN32 )
set( INSTALL_SOUNDFONT_PATH . CACHE STRING "Directory where soundfonts and WOPL/WOPN banks will be placed during install." )
else()
set( INSTALL_SOUNDFONT_PATH share/games/doom CACHE STRING "Directory where soundfonts and WOPL/WOPN banks will be placed during install." )
endif()
install(DIRECTORY "${PROJECT_BINARY_DIR}/soundfonts" "${PROJECT_BINARY_DIR}/fm_banks"
DESTINATION ${INSTALL_SOUNDFONT_PATH}
COMPONENT "Soundfont resources")
if( CMAKE_COMPILER_IS_GNUCXX )
# GCC misoptimizes this file
set_source_files_properties( oplsynth/fmopl.cpp PROPERTIES COMPILE_FLAGS "-fno-tree-dominator-opts -fno-tree-fre" )

View file

@ -401,10 +401,6 @@ void F2DDrawer::AddTexture(FGameTexture* img, DrawParms& parms)
double xscale = parms.destwidth / parms.texwidth;
double yscale = parms.destheight / parms.texheight;
double x = parms.x - parms.left * xscale;
double y = parms.y - parms.top * yscale;
double w = parms.destwidth;
double h = parms.destheight;
double u1, v1, u2, v2;
PalEntry vertexcolor;
@ -414,9 +410,15 @@ void F2DDrawer::AddTexture(FGameTexture* img, DrawParms& parms)
dg.mVertCount = 4;
dg.mTexture = img;
if (img->isWarped()) dg.mFlags |= DTF_Wrap;
if (parms.indexed) dg.mFlags |= DTF_Indexed;
dg.mTranslationId = 0;
SetStyle(img, parms, vertexcolor, dg);
if (parms.indexed)
{
dg.mLightLevel = vertexcolor.Luminance();
vertexcolor = 0xffffffff;
}
if (!img->isHardwareCanvas() && parms.TranslationId != -1)
{
@ -427,44 +429,94 @@ void F2DDrawer::AddTexture(FGameTexture* img, DrawParms& parms)
u2 = parms.srcx + parms.srcwidth;
v2 = parms.srcy + parms.srcheight;
if (parms.flipX)
std::swap(u1, u2);
if (parms.flipY)
std::swap(v1, v2);
// This is crap. Only kept for backwards compatibility with scripts that may have used it.
// Note that this only works for unflipped full textures.
if (parms.windowleft > 0 || parms.windowright < parms.texwidth)
if (parms.flipX)
{
double wi = std::min(parms.windowright, parms.texwidth);
x += parms.windowleft * xscale;
w -= (parms.texwidth - wi + parms.windowleft) * xscale;
u1 = float(u1 + parms.windowleft / parms.texwidth);
u2 = float(u2 - (parms.texwidth - wi) / parms.texwidth);
std::swap(u1, u2);
}
if (x < (double)parms.lclip || y < (double)parms.uclip || x + w >(double)parms.rclip || y + h >(double)parms.dclip)
if (parms.flipY)
{
std::swap(v1, v2);
}
if (parms.rotateangle == 0)
{
double x = parms.x - parms.left * xscale;
double y = parms.y - parms.top * yscale;
double w = parms.destwidth;
double h = parms.destheight;
// This is crap. Only kept for backwards compatibility with scripts that may have used it.
// Note that this only works for unflipped and unrotated full textures.
if (parms.windowleft > 0 || parms.windowright < parms.texwidth)
{
double wi = std::min(parms.windowright, parms.texwidth);
x += parms.windowleft * xscale;
w -= (parms.texwidth - wi + parms.windowleft) * xscale;
u1 = float(u1 + parms.windowleft / parms.texwidth);
u2 = float(u2 - (parms.texwidth - wi) / parms.texwidth);
}
if (x < (double)parms.lclip || y < (double)parms.uclip || x + w >(double)parms.rclip || y + h >(double)parms.dclip)
{
dg.mScissor[0] = parms.lclip;
dg.mScissor[1] = parms.uclip;
dg.mScissor[2] = parms.rclip;
dg.mScissor[3] = parms.dclip;
dg.mFlags |= DTF_Scissor;
}
else
{
memset(dg.mScissor, 0, sizeof(dg.mScissor));
}
dg.mVertCount = 4;
dg.mVertIndex = (int)mVertices.Reserve(4);
TwoDVertex* ptr = &mVertices[dg.mVertIndex];
ptr->Set(x, y, 0, u1, v1, vertexcolor); ptr++;
ptr->Set(x, y + h, 0, u1, v2, vertexcolor); ptr++;
ptr->Set(x + w, y, 0, u2, v1, vertexcolor); ptr++;
ptr->Set(x + w, y + h, 0, u2, v2, vertexcolor); ptr++;
}
else
{
double radang = parms.rotateangle * (pi::pi() / 180.);
double cosang = cos(radang);
double sinang = sin(radang);
double xd1 = -parms.left;
double yd1 = -parms.top;
double xd2 = xd1 + parms.texwidth;
double yd2 = yd1 + parms.texheight;
double x1 = parms.x + xscale * (xd1 * cosang + yd1 * sinang);
double y1 = parms.y - yscale * (xd1 * sinang - yd1 * cosang);
double x2 = parms.x + xscale * (xd1 * cosang + yd2 * sinang);
double y2 = parms.y - yscale * (xd1 * sinang - yd2 * cosang);
double x3 = parms.x + xscale * (xd2 * cosang + yd1 * sinang);
double y3 = parms.y - yscale * (xd2 * sinang - yd1 * cosang);
double x4 = parms.x + xscale * (xd2 * cosang + yd2 * sinang);
double y4 = parms.y - yscale * (xd2 * sinang - yd2 * cosang);
dg.mScissor[0] = parms.lclip;
dg.mScissor[1] = parms.uclip;
dg.mScissor[2] = parms.rclip;
dg.mScissor[3] = parms.dclip;
dg.mFlags |= DTF_Scissor;
}
else
{
memset(dg.mScissor, 0, sizeof(dg.mScissor));
}
dg.mVertCount = 4;
dg.mVertIndex = (int)mVertices.Reserve(4);
TwoDVertex *ptr = &mVertices[dg.mVertIndex];
ptr->Set(x, y, 0, u1, v1, vertexcolor); ptr++;
ptr->Set(x, y + h, 0, u1, v2, vertexcolor); ptr++;
ptr->Set(x + w, y, 0, u2, v1, vertexcolor); ptr++;
ptr->Set(x + w, y + h, 0, u2, v2, vertexcolor); ptr++;
dg.mVertCount = 4;
dg.mVertIndex = (int)mVertices.Reserve(4);
TwoDVertex* ptr = &mVertices[dg.mVertIndex];
ptr->Set(x1, y1, 0, u1, v1, vertexcolor); ptr++;
ptr->Set(x2, y2, 0, u1, v2, vertexcolor); ptr++;
ptr->Set(x3, y3, 0, u2, v1, vertexcolor); ptr++;
ptr->Set(x4, y4, 0, u2, v2, vertexcolor); ptr++;
}
dg.mIndexIndex = mIndices.Size();
dg.mIndexCount += 6;
AddIndices(dg.mVertIndex, 6, 0, 1, 2, 1, 3, 2);
@ -693,7 +745,7 @@ float F2DDrawer::GetClassicFlatScalarHeight()
return sh;
}
void F2DDrawer::AddFlatFill(int left, int top, int right, int bottom, FGameTexture *src, int local_origin, double flatscale)
void F2DDrawer::AddFlatFill(int left, int top, int right, int bottom, FGameTexture *src, int local_origin, double flatscale, PalEntry color)
{
float fU1, fU2, fV1, fV2;
@ -789,18 +841,18 @@ void F2DDrawer::AddFlatFill(int left, int top, int right, int bottom, FGameTextu
dg.mVertIndex = (int)mVertices.Reserve(4);
auto ptr = &mVertices[dg.mVertIndex];
ptr->Set(left, top, 0, fU1, fV1, 0xffffffff); ptr++;
ptr->Set(left, top, 0, fU1, fV1, color); ptr++;
if (local_origin < 4)
{
ptr->Set(left, bottom, 0, fU1, fV2, 0xffffffff); ptr++;
ptr->Set(right, top, 0, fU2, fV1, 0xffffffff); ptr++;
ptr->Set(left, bottom, 0, fU1, fV2, color); ptr++;
ptr->Set(right, top, 0, fU2, fV1, color); ptr++;
}
else
{
ptr->Set(left, bottom, 0, fU2, fV1, 0xffffffff); ptr++;
ptr->Set(right, top, 0, fU1, fV2, 0xffffffff); ptr++;
ptr->Set(left, bottom, 0, fU2, fV1, color); ptr++;
ptr->Set(right, top, 0, fU1, fV2, color); ptr++;
}
ptr->Set(right, bottom, 0, fU2, fV2, 0xffffffff); ptr++;
ptr->Set(right, bottom, 0, fU2, fV2, color); ptr++;
dg.mIndexIndex = mIndices.Size();
dg.mIndexCount += 6;
AddIndices(dg.mVertIndex, 6, 0, 1, 2, 1, 3, 2);
@ -945,8 +997,12 @@ void F2DDrawer::AddPixel(int x1, int y1, uint32_t color)
void F2DDrawer::Clear()
{
mVertices.Clear();
mIndices.Clear();
mData.Clear();
mIsFirstPass = true;
if (!locked)
{
mVertices.Clear();
mIndices.Clear();
mData.Clear();
mIsFirstPass = true;
}
screenFade = 1.f;
}

View file

@ -84,6 +84,7 @@ public:
DTF_Wrap = 1,
DTF_Scissor = 2,
DTF_Burn = 4,
DTF_Indexed = 8,
};
@ -164,6 +165,8 @@ public:
TArray<RenderCommand> mData;
int Width, Height;
bool isIn2D;
bool locked; // prevents clearing of the data so it can be reused multiple times (useful for screen fades)
float screenFade = 1.f;
public:
int fullscreenautoaspect = 0;
int cliptop = -1, clipleft = -1, clipwidth = -1, clipheight = -1;
@ -186,7 +189,7 @@ public:
void AddPoly(FGameTexture* img, FVector4 *vt, size_t vtcount, unsigned int *ind, size_t idxcount, int translation, PalEntry color, FRenderStyle style, int clipx1, int clipy1, int clipx2, int clipy2);
void FillPolygon(int* rx1, int* ry1, int* xb1, int32_t npoints, int picnum, int palette, int shade, int props, const FVector2& xtex, const FVector2& ytex, const FVector2& otex,
int clipx1, int clipy1, int clipx2, int clipy2);
void AddFlatFill(int left, int top, int right, int bottom, FGameTexture *src, int local_origin = false, double flatscale = 1.0);
void AddFlatFill(int left, int top, int right, int bottom, FGameTexture *src, int local_origin = false, double flatscale = 1.0, PalEntry color = 0xffffffff);
void AddColorOnlyQuad(int left, int top, int width, int height, PalEntry color, FRenderStyle *style = nullptr, bool prepend = false);
void ClearScreen(PalEntry color = 0xff000000);
@ -199,6 +202,9 @@ public:
void AddPixel(int x1, int y1, uint32_t color);
void Clear();
void Lock() { locked = true; }
void SetScreenFade(float factor) { screenFade = factor; }
void Unlock() { locked = false; }
int GetWidth() const { return Width; }
int GetHeight() const { return Height; }
void SetSize(int w, int h) { Width = w; Height = h; }
@ -210,6 +216,11 @@ public:
void SetClipRect(int x, int y, int w, int h);
void GetClipRect(int* x, int* y, int* w, int* h);
int DrawCount() const
{
return mData.Size();
}
bool mIsFirstPass = true;
};

View file

@ -45,6 +45,9 @@ EXTERN_CVAR(Int, vid_aspect)
EXTERN_CVAR(Int, uiscale)
CVAR(Bool, ui_screenborder_classic_scaling, true, CVAR_ARCHIVE)
static void VirtualToRealCoords(F2DDrawer* drawer, double Width, double Height, double& x, double& y, double& w, double& h,
double vwidth, double vheight, bool vbottom, bool handleaspect);
// Helper for ActiveRatio and CheckRatio. Returns the forced ratio type, or -1 if none.
int ActiveFakeRatio(int width, int height)
{
@ -187,6 +190,7 @@ void DrawTexture(F2DDrawer *drawer, FGameTexture* img, double x, double y, int t
va_start(tags.list, tags_first);
DrawParms parms;
if (!img || !img->isValid()) return;
bool res = ParseDrawTextureTags(drawer, img, x, y, tags_first, tags, &parms, false);
va_end(tags.list);
if (!res)
@ -208,6 +212,7 @@ static void DrawTexture(F2DDrawer *drawer, FGameTexture *img, double x, double y
{
DrawParms parms;
uint32_t tag = ListGetInt(args);
if (!img || !img->isValid()) return;
bool res = ParseDrawTextureTags(drawer, img, x, y, tag, args, &parms, false);
if (!res) return;
drawer->AddTexture(img, parms);
@ -330,10 +335,19 @@ DEFINE_ACTION_FUNCTION(_Screen, GetClipRect)
}
static void CalcFullscreenScale(F2DDrawer* drawer, double srcwidth, double srcheight, int autoaspect, DoubleRect &rect)
void CalcFullscreenScale(DrawParms *parms, double srcwidth, double srcheight, int oautoaspect, DoubleRect &rect)
{
auto GetWidth = [=]() { return drawer->GetWidth(); };
auto GetHeight = [=]() {return drawer->GetHeight(); };
auto GetWidth = [=]() { return parms->viewport.width; };
auto GetHeight = [=]() {return parms->viewport.height; };
int autoaspect = oautoaspect;
if (autoaspect == FSMode_ScaleToScreen)
{
rect.left = rect.top = 0;
rect.width = GetWidth();
rect.height = GetHeight();
return;
}
double aspect;
if (srcheight == 200) aspect = srcwidth / 240.;
@ -341,23 +355,35 @@ static void CalcFullscreenScale(F2DDrawer* drawer, double srcwidth, double srche
else aspect = srcwidth / srcheight;
rect.left = rect.top = 0;
auto screenratio = ActiveRatio(GetWidth(), GetHeight());
if (autoaspect == 3)
if (autoaspect == FSMode_ScaleToFit43 || autoaspect == FSMode_ScaleToFit43Top || autoaspect == FSMode_ScaleToFit43Bottom)
{
if (screenratio >= aspect || aspect < 1.4) autoaspect = 1; // screen is wider than the image -> pillarbox it. 4:3 images must also be pillarboxed if the screen is taller than the image
else if (screenratio > 1.32) autoaspect = 2; // on anything 4:3 and wider crop the sides of the image.
// screen is wider than the image -> pillarbox it. 4:3 images must also be pillarboxed if the screen is taller than the image
if (screenratio >= aspect || aspect < 1.4) autoaspect = FSMode_ScaleToFit;
else if (screenratio > 1.32) autoaspect = FSMode_ScaleToFill; // on anything 4:3 and wider crop the sides of the image.
else
{
// special case: Crop image to 4:3 and then letterbox this. This avoids too much cropping on narrow windows.
double width4_3 = srcheight * (4. / 3.);
rect.width = (double)GetWidth() * srcwidth / width4_3;
rect.height = GetHeight() * screenratio * (3. / 4.); // use 4:3 for the image
rect.top = (GetHeight() - rect.height) / 2;
rect.left = -(srcwidth - width4_3) / 2;
switch (oautoaspect)
{
default:
rect.top = (GetHeight() - rect.height) / 2;
break;
case FSMode_ScaleToFit43Top:
rect.top = 0;
break;
case FSMode_ScaleToFit43Bottom:
rect.top = (GetHeight() - rect.height);
break;
}
return;
}
}
if ((screenratio > aspect) ^ (autoaspect == 2))
if (autoaspect == FSMode_ScaleToHeight || (screenratio > aspect) ^ (autoaspect == FSMode_ScaleToFill))
{
// pillarboxed or vertically cropped (i.e. scale to height)
rect.height = GetHeight();
@ -369,10 +395,42 @@ static void CalcFullscreenScale(F2DDrawer* drawer, double srcwidth, double srche
// letterboxed or horizontally cropped (i.e. scale to width)
rect.width = GetWidth();
rect.height = GetHeight() * screenratio / aspect;
rect.top = (GetHeight() - rect.height) / 2;
switch (oautoaspect)
{
default:
rect.top = (GetHeight() - rect.height) / 2;
break;
case FSMode_ScaleToFit43Top:
rect.top = 0;
break;
case FSMode_ScaleToFit43Bottom:
rect.top = (GetHeight() - rect.height);
break;
}
}
}
DEFINE_ACTION_FUNCTION(_Screen, GetFullscreenRect)
{
PARAM_PROLOGUE;
PARAM_FLOAT(virtw);
PARAM_FLOAT(virth);
PARAM_INT(fsmode);
DrawParms parms;
DoubleRect rect;
parms.viewport.width = twod->GetWidth();
parms.viewport.height = twod->GetHeight();
CalcFullscreenScale(&parms, virtw, virth, fsmode, rect);
if (numret >= 1) ret[0].SetFloat(rect.left);
if (numret >= 2) ret[1].SetFloat(rect.top);
if (numret >= 3) ret[2].SetFloat(rect.width);
if (numret >= 4) ret[3].SetFloat(rect.height);
return MIN(numret, 4);
}
//==========================================================================
//
// Draw parameter parsing
@ -381,8 +439,8 @@ static void CalcFullscreenScale(F2DDrawer* drawer, double srcwidth, double srche
bool SetTextureParms(F2DDrawer * drawer, DrawParms *parms, FGameTexture *img, double xx, double yy)
{
auto GetWidth = [=]() { return drawer->GetWidth(); };
auto GetHeight = [=]() {return drawer->GetHeight(); };
auto GetWidth = [=]() { return parms->viewport.width; };
auto GetHeight = [=]() {return parms->viewport.height; };
if (img != NULL)
{
parms->x = xx;
@ -399,12 +457,17 @@ bool SetTextureParms(F2DDrawer * drawer, DrawParms *parms, FGameTexture *img, do
}
if (parms->destwidth == INT_MAX || parms->fortext)
{
parms->destwidth = img->GetDisplayWidth();
parms->destwidth = parms->texwidth;
}
if (parms->destheight == INT_MAX || parms->fortext)
{
parms->destheight = img->GetDisplayHeight();
parms->destheight = parms->texheight;
}
parms->destwidth *= parms->patchscalex;
parms->destheight *= parms->patchscaley;
if (parms->flipoffsets && parms->flipY) parms->top = parms->texheight - parms->top;
if (parms->flipoffsets && parms->flipX) parms->left = parms->texwidth - parms->left;
switch (parms->cleanmode)
{
@ -418,6 +481,13 @@ bool SetTextureParms(F2DDrawer * drawer, DrawParms *parms, FGameTexture *img, do
parms->destheight = parms->texheight * CleanYfac;
break;
case DTA_CleanTop:
parms->x = (parms->x - 160.0) * CleanXfac + (GetWidth() * 0.5);
parms->y = (parms->y) * CleanYfac;
parms->destwidth = parms->texwidth * CleanXfac;
parms->destheight = parms->texheight * CleanYfac;
break;
case DTA_CleanNoMove:
parms->destwidth = parms->texwidth * CleanXfac;
parms->destheight = parms->texheight * CleanYfac;
@ -429,13 +499,14 @@ bool SetTextureParms(F2DDrawer * drawer, DrawParms *parms, FGameTexture *img, do
break;
case DTA_Base:
if (parms->fsscalemode != -1)
if (parms->fsscalemode > 0)
{
// First calculate the destination rect for an image of the given size and then reposition this object in it.
DoubleRect rect;
CalcFullscreenScale(drawer, parms->virtWidth, parms->virtHeight, parms->fsscalemode, rect);
parms->x = rect.left + parms->x * rect.width / parms->virtWidth;
parms->y = rect.top + parms->y * rect.height / parms->virtHeight;
CalcFullscreenScale(parms, parms->virtWidth, parms->virtHeight, parms->fsscalemode, rect);
double adder = parms->keepratio < 0 ? 0 : parms->keepratio == 0 ? rect.left : 2 * rect.left;
parms->x = parms->viewport.left + adder + parms->x * rect.width / parms->virtWidth;
parms->y = parms->viewport.top + rect.top + parms->y * rect.height / parms->virtHeight;
parms->destwidth = parms->destwidth * rect.width / parms->virtWidth;
parms->destheight = parms->destheight * rect.height / parms->virtHeight;
return false;
@ -446,12 +517,13 @@ bool SetTextureParms(F2DDrawer * drawer, DrawParms *parms, FGameTexture *img, do
case DTA_FullscreenEx:
{
DoubleRect rect;
CalcFullscreenScale(drawer, img->GetDisplayWidth(), img->GetDisplayHeight(), parms->fsscalemode, rect);
parms->keepratio = true;
parms->x = rect.left;
parms->y = rect.top;
CalcFullscreenScale(parms, parms->texwidth, parms->texheight, parms->fsscalemode, rect);
parms->keepratio = -1;
parms->x = parms->viewport.left + rect.left;
parms->y = parms->viewport.top + rect.top;
parms->destwidth = rect.width;
parms->destheight = rect.height;
parms->top = parms->left = 0;
return false; // Do not call VirtualToRealCoords for this!
}
@ -478,9 +550,11 @@ bool SetTextureParms(F2DDrawer * drawer, DrawParms *parms, FGameTexture *img, do
}
if (parms->virtWidth != GetWidth() || parms->virtHeight != GetHeight())
{
VirtualToRealCoords(drawer, parms->x, parms->y, parms->destwidth, parms->destheight,
VirtualToRealCoords(drawer, GetWidth(), GetHeight(), parms->x, parms->y, parms->destwidth, parms->destheight,
parms->virtWidth, parms->virtHeight, parms->virtBottom, !parms->keepratio);
}
parms->x += parms->viewport.left;
parms->y += parms->viewport.top;
}
return false;
@ -603,8 +677,8 @@ bool ParseDrawTextureTags(F2DDrawer *drawer, FGameTexture *img, double x, double
parms->color = 0xffffffff;
//parms->shadowAlpha = 0;
parms->shadowColor = 0;
parms->virtWidth = drawer->GetWidth();
parms->virtHeight = drawer->GetHeight();
parms->virtWidth = INT_MAX; // these need to match the viewport if not explicitly set, but we do not know that yet.
parms->virtHeight = INT_MAX;
parms->keepratio = false;
parms->style.BlendOp = 255; // Dummy "not set" value
parms->masked = true;
@ -624,6 +698,11 @@ bool ParseDrawTextureTags(F2DDrawer *drawer, FGameTexture *img, double x, double
parms->monospace = EMonospacing::Off;
parms->spacing = 0;
parms->fsscalemode = -1;
parms->patchscalex = parms->patchscaley = 1;
parms->viewport = { 0,0,drawer->GetWidth(), drawer->GetHeight() };
parms->rotateangle = 0;
parms->flipoffsets = false;
parms->indexed = false;
// Parse the tag list for attributes. (For floating point attributes,
// consider that the C ABI dictates that all floats be promoted to
@ -665,6 +744,7 @@ bool ParseDrawTextureTags(F2DDrawer *drawer, FGameTexture *img, double x, double
break;
case DTA_Clean:
case DTA_CleanTop:
boolval = ListGetInt(tags);
if (boolval)
{
@ -746,9 +826,18 @@ bool ParseDrawTextureTags(F2DDrawer *drawer, FGameTexture *img, double x, double
case DTA_FullscreenScale:
intval = ListGetInt(tags);
if (intval >= 0 && intval <= 3)
if (intval >= FSMode_None && intval < FSMode_Max)
{
parms->fsscalemode = (uint8_t)intval;
parms->fsscalemode = (int8_t)intval;
}
else if (intval >= FSMode_Predefined && intval < FSMode_Predefined_Max)
{
static const uint8_t modes[] = { FSMode_ScaleToFit43, FSMode_ScaleToFit43, FSMode_ScaleToFit43, FSMode_ScaleToFit43, FSMode_ScaleToFit43Top};
static const uint16_t widths[] = { 320, 320, 640, 640, 320};
static const uint16_t heights[] = { 200, 240, 400, 480, 200};
parms->fsscalemode = modes[intval - FSMode_Predefined];
parms->virtWidth = widths[intval - FSMode_Predefined];
parms->virtHeight = heights[intval - FSMode_Predefined];
}
break;
@ -821,6 +910,10 @@ bool ParseDrawTextureTags(F2DDrawer *drawer, FGameTexture *img, double x, double
parms->flipY = ListGetInt(tags);
break;
case DTA_FlipOffsets:
parms->flipoffsets = ListGetInt(tags);
break;
case DTA_SrcX:
parms->srcx = ListGetDouble(tags) / img->GetDisplayWidth();
break;
@ -861,6 +954,16 @@ bool ParseDrawTextureTags(F2DDrawer *drawer, FGameTexture *img, double x, double
parms->left = ListGetDouble(tags);
break;
case DTA_TopLeft:
assert(fortext == false);
if (fortext) return false;
if (ListGetInt(tags))
{
parms->left = 0;
parms->top = 0;
}
break;
case DTA_CenterOffset:
assert(fortext == false);
if (fortext) return false;
@ -871,6 +974,16 @@ bool ParseDrawTextureTags(F2DDrawer *drawer, FGameTexture *img, double x, double
}
break;
case DTA_CenterOffsetRel:
assert(fortext == false);
if (fortext) return false;
if (ListGetInt(tags))
{
parms->left = img->GetDisplayLeftOffset() + img->GetDisplayWidth() * 0.5;
parms->top = img->GetDisplayTopOffset() + img->GetDisplayHeight() * 0.5;
}
break;
case DTA_CenterBottomOffset:
assert(fortext == false);
if (fortext) return false;
@ -958,6 +1071,14 @@ bool ParseDrawTextureTags(F2DDrawer *drawer, FGameTexture *img, double x, double
}
break;
case DTA_ScaleX:
parms->patchscalex = ListGetDouble(tags);
break;
case DTA_ScaleY:
parms->patchscaley = ListGetDouble(tags);
break;
case DTA_Masked:
parms->masked = ListGetInt(tags);
break;
@ -967,8 +1088,10 @@ bool ParseDrawTextureTags(F2DDrawer *drawer, FGameTexture *img, double x, double
break;
case DTA_KeepRatio:
// I think this is a terribly misleading name, since it actually turns
// *off* aspect ratio correction.
parms->keepratio = ListGetInt(tags) ? -1 : 0;
break;
case DTA_Pin:
parms->keepratio = ListGetInt(tags);
break;
@ -1012,11 +1135,39 @@ bool ParseDrawTextureTags(F2DDrawer *drawer, FGameTexture *img, double x, double
parms->burn = true;
break;
case DTA_ViewportX:
parms->viewport.left = ListGetInt(tags);
break;
case DTA_ViewportY:
parms->viewport.top = ListGetInt(tags);
break;
case DTA_ViewportWidth:
parms->viewport.width = ListGetInt(tags);
break;
case DTA_ViewportHeight:
parms->viewport.height = ListGetInt(tags);
break;
case DTA_Rotate:
assert(fortext == false);
if (fortext) return false;
parms->rotateangle = ListGetDouble(tags);
break;
case DTA_Indexed:
parms->indexed = !!ListGetInt(tags);
break;
}
tag = ListGetInt(tags);
}
ListEnd(tags);
if (parms->virtWidth == INT_MAX) parms->virtWidth = parms->viewport.width;
if (parms->virtHeight == INT_MAX) parms->virtHeight = parms->viewport.height;
auto clipleft = drawer->clipleft;
auto cliptop = drawer->cliptop;
auto clipwidth = drawer->clipwidth;
@ -1084,12 +1235,10 @@ template bool ParseDrawTextureTags<VMVa_List>(F2DDrawer* drawer, FGameTexture *i
//
//==========================================================================
void VirtualToRealCoords(F2DDrawer *drawer, double &x, double &y, double &w, double &h,
static void VirtualToRealCoords(F2DDrawer *drawer, double Width, double Height, double &x, double &y, double &w, double &h,
double vwidth, double vheight, bool vbottom, bool handleaspect)
{
auto Width = drawer->GetWidth();
auto Height = drawer->GetHeight();
float myratio = handleaspect ? ActiveRatio (Width, Height) : (4.0f / 3.0f);
float myratio = float(handleaspect ? ActiveRatio (Width, Height) : (4.0 / 3.0));
// if 21:9 AR, map to 16:9 for all callers.
// this allows for black bars and stops the stretching of fullscreen images
@ -1129,6 +1278,14 @@ void VirtualToRealCoords(F2DDrawer *drawer, double &x, double &y, double &w, dou
}
}
void VirtualToRealCoords(F2DDrawer* drawer, double& x, double& y, double& w, double& h,
double vwidth, double vheight, bool vbottom, bool handleaspect)
{
auto Width = drawer->GetWidth();
auto Height = drawer->GetHeight();
VirtualToRealCoords(drawer, Width, Height, x, y, w, h, vwidth, vheight, vbottom, handleaspect);
}
DEFINE_ACTION_FUNCTION(_Screen, VirtualToRealCoords)
{
PARAM_PROLOGUE;

View file

@ -2,6 +2,7 @@
#include "v_2ddrawer.h"
#include "c_cvars.h"
#include "intrect.h"
// TagItem definitions for DrawTexture. As far as I know, tag lists
// originated on the Amiga.
@ -13,11 +14,38 @@
// uint32_t ti_Data;
// };
#define TAG_DONE (0) /* Used to indicate the end of the Tag list */
#define TAG_END (0) /* Ditto */
/* list pointed to in ti_Data */
enum tags : uint32_t
{
TAG_DONE = (0), /* Used to indicate the end of the Tag list */
TAG_END = (0), /* Ditto */
/* list pointed to in ti_Data */
#define TAG_USER ((uint32_t)(1u<<30))
TAG_USER = ((uint32_t)(1u << 30))
};
enum
{
FSMode_None = 0,
FSMode_ScaleToFit = 1,
FSMode_ScaleToFill = 2,
FSMode_ScaleToFit43 = 3,
FSMode_ScaleToScreen = 4,
FSMode_ScaleToFit43Top = 5,
FSMode_ScaleToFit43Bottom = 6,
FSMode_ScaleToHeight = 7,
FSMode_Max,
// These all use ScaleToFit43, their purpose is to cut down on verbosity because they imply the virtual screen size.
FSMode_Predefined = 1000,
FSMode_Fit320x200 = 1000,
FSMode_Fit320x240,
FSMode_Fit640x400,
FSMode_Fit640x480,
FSMode_Fit320x200Top,
FSMode_Predefined_Max,
};
enum
{
@ -89,6 +117,20 @@ enum
DTA_FullscreenEx,
DTA_FullscreenScale,
DTA_ScaleX,
DTA_ScaleY,
DTA_ViewportX, // Defines the viewport on the screen that should be rendered to.
DTA_ViewportY,
DTA_ViewportWidth,
DTA_ViewportHeight,
DTA_CenterOffsetRel, // Apply texture offsets relative to center, instead of top left. This is standard alignment for Build's 2D content.
DTA_TopLeft, // always align to top left. Added to have a boolean condition for this alignment.
DTA_Pin, // Pin a non-widescreen image to the left/right edge of the screen.
DTA_Rotate,
DTA_FlipOffsets, // Flips offsets when using DTA_FlipX and DTA_FlipY, this cannot be automatic due to unexpected behavior with unoffsetted graphics.
DTA_Indexed, // Use an indexed texture combined with the given translation.
DTA_CleanTop, // Like DTA_Clean but aligns to the top of the screen instead of the center.
};
@ -154,9 +196,14 @@ struct DrawParms
bool fortext;
bool virtBottom;
bool burn;
bool flipoffsets;
bool indexed;
int8_t fsscalemode;
double srcx, srcy;
double srcwidth, srcheight;
double patchscalex, patchscaley;
double rotateangle;
IntRect viewport;
};
struct Va_List
@ -187,14 +234,8 @@ int GetUIScale(F2DDrawer* drawer, int altval);
int GetConScale(F2DDrawer* drawer, int altval);
EXTERN_CVAR(Int, uiscale);
EXTERN_CVAR(Int, con_scaletext);
EXTERN_CVAR(Int, con_scale);
inline int active_con_scaletext(F2DDrawer* drawer, bool newconfont = false)
{
return newconfont ? GetConScale(drawer, con_scaletext) : GetUIScale(drawer, con_scaletext);
}
inline int active_con_scale(F2DDrawer *drawer)
{
return GetConScale(drawer, con_scale);

View file

@ -258,8 +258,13 @@ void DrawTextCommon(F2DDrawer *drawer, FFont *font, int normalcolor, double x, d
int kerning;
FGameTexture *pic;
double scalex = parms.scalex * parms.patchscalex;
double scaley = parms.scaley * parms.patchscaley;
if (parms.celly == 0) parms.celly = font->GetHeight() + 1;
parms.celly *= parms.scaley;
parms.celly = int (parms.celly * scaley);
bool palettetrans = (normalcolor == CR_UNDEFINED && parms.TranslationId != 0);
if (normalcolor >= NumTextColors)
normalcolor = CR_UNTRANSLATED;
@ -267,7 +272,7 @@ void DrawTextCommon(F2DDrawer *drawer, FFont *font, int normalcolor, double x, d
PalEntry colorparm = parms.color;
PalEntry color = 0xffffffff;
trans = font->GetColorTranslation((EColorRange)normalcolor, &color);
trans = palettetrans? -1 : font->GetColorTranslation((EColorRange)normalcolor, &color);
parms.color = PalEntry(colorparm.a, (color.r * colorparm.r) / 255, (color.g * colorparm.g) / 255, (color.b * colorparm.b) / 255);
kerning = font->GetDefaultKerning();
@ -311,7 +316,8 @@ void DrawTextCommon(F2DDrawer *drawer, FFont *font, int normalcolor, double x, d
bool redirected = false;
if (NULL != (pic = font->GetChar(c, currentcolor, &w, &redirected)))
{
parms.TranslationId = redirected? -1 : trans;
// if palette translation is used, font colors will be ignored.
if (!palettetrans) parms.TranslationId = redirected? -1 : trans;
SetTextureParms(drawer, &parms, pic, cx, cy);
if (parms.cellx)
{
@ -330,11 +336,11 @@ void DrawTextCommon(F2DDrawer *drawer, FFont *font, int normalcolor, double x, d
}
if (parms.monospace == EMonospacing::Off)
{
cx += (w + kerning + parms.spacing) * parms.scalex;
cx += (w + kerning + parms.spacing) * scalex;
}
else
{
cx += (parms.spacing) * parms.scalex;
cx += (parms.spacing) * scalex;
}
}

View file

@ -95,6 +95,26 @@ void S_SetMusicCallbacks(MusicCallbacks* cb)
static std::unique_ptr<SoundStream> musicStream;
SoundStream *S_CreateCustomStream(size_t size, int samplerate, int numchannels, StreamCallback cb, void *userdata)
{
int flags = 0;
if (numchannels < 2) flags |= SoundStream::Mono;
auto stream = GSnd->CreateStream(cb, size, flags, samplerate, userdata);
if (stream) stream->Play(true, 1);
return stream;
}
void S_StopCustomStream(SoundStream *stream)
{
if (stream)
{
stream->Stop();
delete stream;
}
}
static bool FillStream(SoundStream* stream, void* buff, int len, void* userdata)
{
bool written = ZMusic_FillStream(mus_playing.handle, buff, len);
@ -123,6 +143,7 @@ void S_CreateStream()
}
}
void S_PauseStream(bool paused)
{
if (musicStream) musicStream->SetPaused(paused);
@ -298,7 +319,7 @@ bool S_ChangeMusic(const char* musicname, int order, bool looping, bool force)
if (!force && PlayList.GetNumSongs())
{ // Don't change if a playlist is active
return false;
return true; // do not report an error here.
}
// Do game specific lookup.
FString musicname_;

View file

@ -99,9 +99,9 @@ CUSTOM_CVAR(String, adl_custom_bank, "", CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR
FORWARD_STRING_CVAR(adl_custom_bank);
}
CUSTOM_CVAR(Int, adl_volume_model, 3/*ADLMIDI_VolumeModel_DMX*/, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL)
CUSTOM_CVAR(Int, adl_volume_model, 0 /*ADLMIDI_VolumeModel_AUTO*/, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_VIRTUAL)
{
FORWARD_CVAR(adl_bank);
FORWARD_CVAR(adl_volume_model);
}
#endif
//==========================================================================

View file

@ -8,6 +8,12 @@
#include <zmusic.h>
class FileReader;
class SoundStream;
typedef bool(*StreamCallback)(SoundStream* stream, void* buff, int len, void* userdata);
SoundStream *S_CreateCustomStream(size_t size, int samplerate, int numchannels, StreamCallback cb, void *userdata);
void S_StopCustomStream(SoundStream* stream);
struct MusicCallbacks
{

View file

@ -181,7 +181,7 @@ class OpenALSoundStream : public SoundStream
ALuint Source;
std::atomic<bool> Playing;
bool Looping;
//bool Looping;
ALfloat Volume;
bool SetupSource()
@ -227,7 +227,7 @@ class OpenALSoundStream : public SoundStream
public:
OpenALSoundStream(OpenALSoundRenderer *renderer)
: Renderer(renderer), Source(0), Playing(false), Looping(false), Volume(1.0f)
: Renderer(renderer), Source(0), Playing(false), Volume(1.0f)
{
memset(Buffers, 0, sizeof(Buffers));
Renderer->AddStream(this);
@ -1098,6 +1098,10 @@ SoundHandle OpenALSoundRenderer::LoadSound(uint8_t *sfxdata, int length)
data.resize(total * 2);
}
data.resize(total);
if (total == 0)
{
return retval;
}
SoundDecoder_Close(decoder);
ALenum err;
@ -1516,6 +1520,9 @@ void OpenALSoundRenderer::StopChannel(FISoundChannel *chan)
if((i=SfxGroup.Find(source)) < SfxGroup.Size())
SfxGroup.Delete(i);
if (!(chan->ChanFlags & CHANF_EVICTED))
soundEngine->SoundDone(chan);
FreeSfx.Push(source);
}

View file

@ -183,20 +183,31 @@ static ReverbContainer Underwater =
false
};
static ReverbContainer SewerPipe4 =
static ReverbContainer SewerPipe3 =
{
&Underwater,
"Sewer Pipe 2",
"Sewer Pipe 3",
0x1503,
true,
false,
{0,21, 1.7f, 0.80f, -1000, -1000, 0, 1.54f, 0.14f, 1.0f, 200, 0.014f, 0.0f,0.0f,0.0f, 1023, 0.021f, 0.0f,0.0f,0.0f, 0.250f, 0.00f, 0.25f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.0f, 80.0f, 60.0f, 0x3f },
false
};
static ReverbContainer SewerPipe2 =
{
&SewerPipe3,
"Sewer Pipe 2",
0x1502,
true,
false,
{0,21, 1.7f, 0.80f, -1000, -1000, 0, 1.81f, 0.14f, 1.0f, 229, 0.014f, 0.0f,0.0f,0.0f, 1023, 0.021f, 0.0f,0.0f,0.0f, 0.250f, 0.00f, 0.25f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.0f, 80.0f, 60.0f, 0x3f },
false
};
static ReverbContainer SewerPipe =
{
&SewerPipe4,
&SewerPipe2,
"Sewer Pipe",
0x1500,
true,

View file

@ -41,13 +41,14 @@
#include "m_swap.h"
#include "superfasthash.h"
#include "s_music.h"
#include "m_random.h"
enum
{
DEFAULT_PITCH = 128,
};
static FRandom pr_soundpitch ("SoundPitch");
SoundEngine* soundEngine;
int sfx_empty = -1;
@ -405,6 +406,7 @@ FSoundChan *SoundEngine::StartSound(int type, const void *source,
int near_limit = sfx->NearLimit;
float limit_range = sfx->LimitRange;
float defpitch = sfx->DefPitch;
float defpitchmax = sfx->DefPitchMax;
auto pitchmask = sfx->PitchMask;
rolloff = &sfx->Rolloff;
@ -421,6 +423,7 @@ FSoundChan *SoundEngine::StartSound(int type, const void *source,
near_limit = newsfx->NearLimit;
limit_range = newsfx->LimitRange;
defpitch = newsfx->DefPitch;
defpitchmax = newsfx->DefPitchMax;
}
if (rolloff->MinDistance == 0)
{
@ -551,8 +554,8 @@ FSoundChan *SoundEngine::StartSound(int type, const void *source,
float sfxlength = (float)GSnd->GetMSLength(sfx->data) / 1000.f;
startTime = (startflags & SNDF_LOOP)
? (sfxlength > 0 ? fmod(startTime, sfxlength) : 0)
: clamp<float>(startTime, 0.f, sfxlength);
? (sfxlength > 0 ? fmodf(startTime, sfxlength) : 0.f)
: clamp(startTime, 0.f, sfxlength);
if (attenuation > 0 && type != SOURCE_None)
{
@ -590,6 +593,7 @@ FSoundChan *SoundEngine::StartSound(int type, const void *source,
chan->Priority = basepriority;
chan->DistanceScale = float(attenuation);
chan->SourceType = type;
chan->UserData = 0;
if (type == SOURCE_Unattached)
{
chan->Point[0] = pt->X; chan->Point[1] = pt->Y; chan->Point[2] = pt->Z;
@ -602,7 +606,23 @@ FSoundChan *SoundEngine::StartSound(int type, const void *source,
if (spitch > 0.0) // A_StartSound has top priority over all others.
SetPitch(chan, spitch);
else if (defpitch > 0.0) // $PitchSet overrides $PitchShift
{
if (defpitchmax > 0.0)
{
if (defpitchmax < defpitch)
std::swap(defpitch, defpitchmax);
if (defpitch != defpitchmax)
{
FRandom &rng = pr_soundpitch;
int random = (rng)(0x7FFF);
float frandom = random / float(0x7FFF);
defpitch = frandom * (defpitchmax - defpitch) + defpitch;
}
}
SetPitch(chan, defpitch);
}
}
return chan;
@ -1074,6 +1094,16 @@ int SoundEngine::GetSoundPlayingInfo (int sourcetype, const void *source, int so
}
}
}
else
{
for (FSoundChan* chan = Channels; chan != NULL; chan = chan->NextChan)
{
if ((sourcetype == SOURCE_Any || (chan->SourceType == sourcetype && chan->Source == source)))
{
count++;
}
}
}
return count;
}
@ -1327,13 +1357,29 @@ void SoundEngine::ChannelEnded(FISoundChannel *ichan)
}
if (!evicted)
{
ReturnChannel(schan);
schan->ChanFlags &= ~CHANF_EVICTED;
}
else
{
schan->ChanFlags |= CHANF_EVICTED;
schan->SysChannel = NULL;
}
}
}
//==========================================================================
//
//
//
//==========================================================================
void SoundEngine::SoundDone(FISoundChannel* ichan)
{
FSoundChan* schan = static_cast<FSoundChan*>(ichan);
if (schan != NULL)
{
ReturnChannel(schan);
}
}
@ -1495,6 +1541,7 @@ int SoundEngine::AddSoundLump(const char* logicalname, int lump, int CurrentPitc
newsfx.Attenuation = 1;
newsfx.PitchMask = CurrentPitchMask;
newsfx.DefPitch = 0.0;
newsfx.DefPitchMax = 0.0;
newsfx.NearLimit = nearlimit;
newsfx.LimitRange = 256 * 256;
newsfx.bRandomHeader = false;

View file

@ -30,6 +30,7 @@ struct sfxinfo_t
int16_t NearLimit; // 0 means unlimited
float LimitRange; // Range for sound limiting (squared for faster computations)
float DefPitch; // A defined pitch instead of a random one the sound plays at, similar to A_StartSound.
float DefPitchMax; // Randomized range with stronger control over pitch itself.
unsigned bRandomHeader:1;
unsigned bLoadRAW:1;
@ -165,6 +166,7 @@ struct FSoundChan : public FISoundChannel
FSoundID OrgID; // Sound ID of sound used to start this channel.
float Volume;
int EntChannel; // Actor's sound channel.
int UserData; // Not used by the engine, the caller can use this to store some additional info.
int16_t Pitch; // Pitch variation.
int16_t NearLimit;
int8_t Priority;
@ -302,6 +304,10 @@ public:
virtual void CacheSound(sfxinfo_t* sfx);
void CacheSound(int sfx) { CacheSound(&S_sfx[sfx]); }
void UnloadSound(sfxinfo_t* sfx);
void UnloadSound(int sfx)
{
UnloadSound(&S_sfx[sfx]);
}
void UpdateSounds(int time);
@ -409,6 +415,7 @@ public:
// Allow this to be overridden for special needs.
virtual float GetRolloff(const FRolloffInfo* rolloff, float distance);
virtual void ChannelEnded(FISoundChannel* ichan); // allows the client to do bookkeeping on the sound.
virtual void SoundDone(FISoundChannel* ichan); // gets called when the sound has been completely taken down.
// Lookup utilities.
int FindSound(const char* logicalname);

View file

@ -739,7 +739,7 @@ void C_SetDefaultKeys(const char* baseconfig)
//
//
//=============================================================================
CVAR(Int, cl_defaultconfiguration, 2, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
CVAR(Int, cl_defaultconfiguration, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
void C_BindDefaults()

View file

@ -87,7 +87,6 @@ public:
extern FKeyBindings Bindings;
extern FKeyBindings DoubleBindings;
extern FKeyBindings AutomapBindings;
extern FKeyBindings MenuBindings;
bool C_DoKey (event_t *ev, FKeyBindings *binds, FKeyBindings *doublebinds);

View file

@ -57,6 +57,7 @@ extern constate_e ConsoleState;
void C_InitConsole (int width, int height, bool ingame);
void C_DeinitConsole ();
void C_InitConback();
void C_ClearMessages();
// Adjust the console for a new screen mode
void C_NewModeAdjust (void);
@ -83,6 +84,7 @@ bool C_Responder (event_t *ev);
void C_AddTabCommand (const char *name);
void C_RemoveTabCommand (const char *name);
void C_ClearTabCommands(); // Removes all tab commands
void C_SetNotifyFontScale(double scale);
extern const char *console_bar;

View file

@ -150,6 +150,11 @@ const char *FBaseCVar::GetHumanString(int precision) const
return GetGenericRep(CVAR_String).String;
}
const char *FBaseCVar::GetHumanStringDefault(int precision) const
{
return GetGenericRepDefault(CVAR_String).String;
}
void FBaseCVar::ForceSet (UCVarValue value, ECVarType type, bool nouserinfosend)
{
DoSet (value, type);
@ -653,6 +658,16 @@ const char *FFloatCVar::GetHumanString(int precision) const
return cstrbuf;
}
const char *FFloatCVar::GetHumanStringDefault(int precision) const
{
if (precision < 0)
{
precision = 6;
}
mysnprintf(cstrbuf, countof(cstrbuf), "%.*g", precision, DefaultValue);
return cstrbuf;
}
UCVarValue FFloatCVar::GetGenericRep (ECVarType type) const
{
return FromFloat (Value, type);
@ -1519,7 +1534,12 @@ CCMD (toggle)
val = var->GetGenericRep (CVAR_Bool);
val.Bool = !val.Bool;
var->SetGenericRep (val, CVAR_Bool);
Printf ("\"%s\" = \"%s\"\n", var->GetName(),
auto msg = var->GetToggleMessage(val.Bool);
if (msg.IsNotEmpty())
{
Printf(PRINT_NOTIFY, "%s\n", msg.GetChars());
}
else Printf ("\"%s\" = \"%s\"\n", var->GetName(),
val.Bool ? "true" : "false");
}
}

View file

@ -161,6 +161,7 @@ public:
virtual UCVarValue GetGenericRep (ECVarType type) const = 0;
virtual UCVarValue GetFavoriteRep (ECVarType *type) const = 0;
virtual const char *GetHumanStringDefault(int precision = -1) const;
virtual UCVarValue GetGenericRepDefault (ECVarType type) const = 0;
virtual UCVarValue GetFavoriteRepDefault (ECVarType *type) const = 0;
virtual void SetGenericRepDefault (UCVarValue value, ECVarType type) = 0;
@ -176,6 +177,13 @@ public:
static void ListVars (const char *filter, bool plain);
const FString &GetDescription() const { return Description; };
const FString& GetToggleMessage(int which) { return ToggleMessages[which]; }
void SetToggleMessages(const char* on, const char* off)
{
ToggleMessages[0] = off;
ToggleMessages[1] = on;
}
protected:
virtual void DoSet (UCVarValue value, ECVarType type) = 0;
@ -192,13 +200,13 @@ protected:
FString VarName;
FString SafeValue;
FString Description;
FString ToggleMessages[2];
uint32_t Flags;
bool inCallback = false;
private:
FBaseCVar (const FBaseCVar &var) = delete;
FBaseCVar (const char *name, uint32_t flags);
void (*m_Callback)(FBaseCVar &);
FBaseCVar *m_Next;
@ -332,6 +340,7 @@ public:
virtual UCVarValue GetFavoriteRepDefault (ECVarType *type) const override;
virtual void SetGenericRepDefault (UCVarValue value, ECVarType type) override;
const char *GetHumanString(int precision) const override;
const char *GetHumanStringDefault(int precision) const override;
float operator= (float floatval)
{ UCVarValue val; val.Float = floatval; SetGenericRep (val, CVAR_Float); return floatval; }

View file

@ -302,7 +302,8 @@ void C_DoCommand (const char *cmd, int keynum)
else
{ // Get the variable's value
if (var->GetDescription().Len()) Printf("%s\n", GStrings.localize(var->GetDescription()));
Printf ("\"%s\" is \"%s\"\n", var->GetName(), var->GetHumanString());
Printf ("\"%s\" is \"%s\" ", var->GetName(), var->GetHumanString());
Printf ("(default: \"%s\")\n", var->GetHumanStringDefault());
}
}
else
@ -1123,7 +1124,7 @@ int C_RegisterFunction(const char* pszName, const char* pszDesc, int (*func)(CCm
{
if (args.argc() > 0) args.operator[](0);
CCmdFuncParm param = { args.argc() - 1, nname.GetChars(), (const char**)args._argv + 1, args.cmd };
if (func(&param) != CCMD_OK)
if (func(&param) != CCMD_OK && pszDesc)
{
Printf("%s\n", pszDesc);
}

View file

@ -59,7 +59,7 @@ extern bool ParsingKeyConf, UnsafeExecutionContext;
extern FString StoredWarp; // [RH] +warp at the command line
extern bool CheckCheatmode (bool printmsg = true);
extern bool CheckCheatmode (bool printmsg = true, bool sponly = false);
FExecList *C_ParseCmdLineParams(FExecList *exec);

View file

@ -53,6 +53,9 @@ enum EKeyCodes
KEY_PGUP = 0xc9, // DIK_PRIOR
KEY_PGDN = 0xd1, // DIK_NEXT
KEY_VOLUMEDOWN = 0xAE, // DIK_VOLUMEDOWN
KEY_VOLUMEUP = 0xB0, // DIK_VOLUMEUP
KEY_FIRSTMOUSEBUTTON = 0x100,
KEY_MOUSE1 = 0x100,
KEY_MOUSE2 = 0x101,
@ -72,6 +75,8 @@ enum EKeyCodes
KEY_JOY6,
KEY_JOY7,
KEY_JOY8,
KEY_JOY14 = KEY_FIRSTJOYBUTTON+13,
KEY_JOY15 = KEY_FIRSTJOYBUTTON+14,
KEY_LASTJOYBUTTON = 0x187,
KEY_JOYPOV1_UP = 0x188,
KEY_JOYPOV1_RIGHT = 0x189,

View file

@ -41,6 +41,8 @@
#include "utf8.h"
#include "m_joy.h"
#include "vm.h"
#include "gamestate.h"
#include "i_interface.h"
bool G_Responder(event_t* ev);
@ -48,6 +50,11 @@ int eventhead;
int eventtail;
event_t events[MAXEVENTS];
CVAR(Float, m_sensitivity_x, 2, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
CVAR(Float, m_sensitivity_y, 2, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
CVAR(Bool, m_filter, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
//==========================================================================
//
// D_ProcessEvents
@ -69,6 +76,8 @@ void D_ProcessEvents (void)
continue;
if (ev->type == EV_DeviceChange)
UpdateJoystickMenu(I_UpdateDeviceList());
if (gamestate == GS_INTRO)
continue;
if (C_Responder (ev))
continue; // console ate the event
if (M_Responder (ev))
@ -113,6 +122,57 @@ void D_RemoveNextCharEvent()
}
//==========================================================================
//
// D_PostEvent
//
// Called by the I/O functions when input is detected.
//
//==========================================================================
void D_PostEvent(event_t* ev)
{
// Do not post duplicate consecutive EV_DeviceChange events.
if (ev->type == EV_DeviceChange && events[eventhead].type == EV_DeviceChange)
{
return;
}
if (sysCallbacks.DispatchEvent && sysCallbacks.DispatchEvent(ev))
return;
events[eventhead] = *ev;
eventhead = (eventhead + 1) & (MAXEVENTS - 1);
}
void PostMouseMove(int xx, int yy)
{
static float lastx = 0, lasty = 0;
event_t ev{};
float x = float(xx) * m_sensitivity_x;
float y = -float(yy) * m_sensitivity_y;
if (m_filter)
{
ev.x = (x + lastx) / 2;
ev.y = (y + lasty) / 2;
}
else
{
ev.x = x;
ev.y = y;
}
lastx = x;
lasty = y;
if (ev.x || ev.y)
{
ev.type = EV_Mouse;
D_PostEvent(&ev);
}
}
FInputEvent::FInputEvent(const event_t *ev)
{
Type = (EGenericEvent)ev->type;
@ -132,8 +192,8 @@ FInputEvent::FInputEvent(const event_t *ev)
KeyString = FString(char(ev->data1));
break;
case EV_Mouse:
MouseX = ev->x;
MouseY = ev->y;
MouseX = int(ev->x);
MouseY = int(ev->y);
break;
default:
break; // EV_DeviceChange = wat?

View file

@ -22,16 +22,17 @@ struct event_t
int16_t data1; // keys / mouse/joystick buttons
int16_t data2;
int16_t data3;
int x; // mouse/joystick x move
int y; // mouse/joystick y move
float x; // mouse/joystick x move
float y; // mouse/joystick y move
};
// Called by IO functions when input is detected.
void D_PostEvent (const event_t* ev);
void D_PostEvent (event_t* ev);
void D_RemoveNextCharEvent();
void D_ProcessEvents(void);
void PostMouseMove(int x, int y);
enum
{

View file

@ -6,4 +6,4 @@ void I_PutInClipboard (const char *str);
FString I_GetFromClipboard (bool use_primary_selection);
void I_SetMouseCapture();
void I_ReleaseMouseCapture();
void I_GetEvent();

View file

@ -1,8 +1,7 @@
#include "i_interface.h"
// Some global engine variables taken out of the backend code.
SystemCallbacks *sysCallbacks;
double refreshfreq;
SystemCallbacks sysCallbacks;
FString endoomName;
bool batchrun;
float menuBlurAmount;

View file

@ -3,6 +3,8 @@
#include "zstring.h"
#include "intrect.h"
struct event_t;
struct SystemCallbacks
{
bool (*WantGuiCapture)();
@ -18,9 +20,11 @@ struct SystemCallbacks
IntRect(*GetSceneRect)();
FString(*GetLocationDescription)();
void (*MenuDim)();
FString(*GetPlayerName)(int i);
bool (*DispatchEvent)(event_t* ev);
};
extern SystemCallbacks *sysCallbacks;
extern SystemCallbacks sysCallbacks;
struct WadStuff
{

View file

@ -1,7 +1,9 @@
// Emacs style mode select -*- C++ -*-
//-----------------------------------------------------------------------------
//
// Copyright 1993-1996 id Software
// Copyright 1999-2016 Randy Heit
// $Id: i_net.c,v 1.2 1997/12/29 19:50:54 pekangas Exp $
//
// Copyright (C) 1993-1996 by id Software, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@ -16,7 +18,19 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see http://www.gnu.org/licenses/
//
//-----------------------------------------------------------------------------
//
//
// Alternatively the following applies:
//
// This source is available for distribution and/or modification
// only under the terms of the DOOM Source Code License as
// published by id Software. All rights reserved.
//
// The source is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
// for more details.
//
//
// DESCRIPTION:
// Low-level networking code. Uses BSD sockets for UDP networking.
@ -53,16 +67,15 @@
# endif
#endif
#include "doomtype.h"
#include "i_system.h"
#include "d_net.h"
#include "m_argv.h"
#include "m_crc32.h"
#include "d_player.h"
#include "st_start.h"
#include "m_misc.h"
#include "engineerrors.h"
#include "cmdlib.h"
#include "printf.h"
#include "i_interface.h"
#include "templates.h"
#include "i_net.h"
@ -91,6 +104,10 @@ typedef int SOCKET;
typedef int socklen_t;
#endif
bool netgame, multiplayer;
int consoleplayer; // i.e. myconnectindex in Build.
doomcom_t doomcom;
//
// NETWORKING
//
@ -143,6 +160,12 @@ struct PreGamePacket
uint8_t TransmitBuffer[TRANSMIT_SIZE];
FString GetPlayerName(int num)
{
if (sysCallbacks.GetPlayerName) return sysCallbacks.GetPlayerName(sendplayer[num]);
else return FStringf("Player %d", sendplayer[num] + 1);
}
//
// UDPsocket
//
@ -272,12 +295,12 @@ void PacketGet (void)
if (StartScreen != NULL)
{
StartScreen->NetMessage ("The connection from %s was dropped.\n",
players[sendplayer[node]].userinfo.GetName());
GetPlayerName(node).GetChars());
}
else
{
Printf("The connection from %s was dropped.\n",
players[sendplayer[node]].userinfo.GetName());
GetPlayerName(node).GetChars());
}
doomcom.data[0] = 0x80; // NCMD_EXIT
@ -945,7 +968,7 @@ int I_InitNetwork (void)
v = Args->CheckValue ("-dup");
if (v)
{
doomcom.ticdup = clamp (atoi (v), 1, MAXTICDUP);
doomcom.ticdup = clamp<int> (atoi (v), 1, MAXTICDUP);
}
else
{

85
src/common/engine/i_net.h Normal file
View file

@ -0,0 +1,85 @@
#ifndef __I_NET_H__
#define __I_NET_H__
#include <stdint.h>
// Called by D_DoomMain.
int I_InitNetwork (void);
void I_NetCmd (void);
enum ENetConstants
{
MAXNETNODES = 8, // max computers in a game
DOOMCOM_ID = 0x12345678,
BACKUPTICS = 36, // number of tics to remember
MAXTICDUP = 5,
LOCALCMDTICS =(BACKUPTICS*MAXTICDUP),
MAX_MSGLEN = 14000,
CMD_SEND = 1,
CMD_GET = 2,
};
// [RH]
// New generic packet structure:
//
// Header:
// One byte with following flags.
// One byte with starttic
// One byte with master's maketic (master -> slave only!)
// If NCMD_RETRANSMIT set, one byte with retransmitfrom
// If NCMD_XTICS set, one byte with number of tics (minus 3, so theoretically up to 258 tics in one packet)
// If NCMD_QUITTERS, one byte with number of players followed by one byte with each player's consolenum
// If NCMD_MULTI, one byte with number of players followed by one byte with each player's consolenum
// - The first player's consolenum is not included in this list, because it always matches the sender
//
// For each tic:
// Two bytes with consistancy check, followed by tic data
//
// Setup packets are different, and are described just before D_ArbitrateNetStart().
enum ENCMD
{
NCMD_EXIT = 0x80,
NCMD_RETRANSMIT = 0x40,
NCMD_SETUP = 0x20,
NCMD_MULTI = 0x10, // multiple players in this packet
NCMD_QUITTERS = 0x08, // one or more players just quit (packet server only)
NCMD_COMPRESSED = 0x04, // remainder of packet is compressed
NCMD_XTICS = 0x03, // packet contains >2 tics
NCMD_2TICS = 0x02, // packet contains 2 tics
NCMD_1TICS = 0x01, // packet contains 1 tic
NCMD_0TICS = 0x00, // packet contains 0 tics
};
//
// Network packet data.
//
struct doomcom_t
{
uint32_t id; // should be DOOMCOM_ID
int16_t intnum; // DOOM executes an int to execute commands
// communication between DOOM and the driver
int16_t command; // CMD_SEND or CMD_GET
int16_t remotenode; // dest for send, set by get (-1 = no packet).
int16_t datalength; // bytes in data to be sent
// info common to all nodes
int16_t numnodes; // console is always node 0.
int16_t ticdup; // 1 = no duplication, 2-5 = dup for slow nets
// info specific to this node
int16_t consoleplayer;
int16_t numplayers;
// packet data to be sent
uint8_t data[MAX_MSGLEN];
};
extern doomcom_t doomcom;
extern bool netgame, multiplayer;
#endif

View file

@ -660,7 +660,10 @@ xx(Static)
xx(Staticconst)
xx(DeathmatchStatusScreen)
xx(CoopStatusScreen)
xx(DoomStatusScreen)
xx(RavenStatusScreen)
xx(DoomStatusScreenSized)
xx(RavenStatusScreenSized)
xx(StatusbarWidget)
xx(StatusbarHead)
xx(StatusbarCondition)
@ -1039,6 +1042,9 @@ xx(AttackZOffset)
xx(SpawnMask)
xx(ScoreIcon)
xx(ViewHeight)
xx(ViewAngle)
xx(ViewPitch)
xx(ViewRoll)
xx(FallingScreamMinSpeed)
xx(FallingScreamMaxSpeed)
xx(GruntSpeed)
@ -1071,4 +1077,12 @@ xx(PlayerColors)
xx(PlayerSkin)
xx(NewPlayerMenu)
xx(AltHud)
xx(GameScreen)
// summary
xx(cwidth)
xx(cheight)
xx(wrapwidth)
xx(scalefactorx)
xx(scalefactory)
xx(scalemode)

View file

@ -36,6 +36,7 @@ struct FRemapTable
bool Inactive = false; // This table is inactive and should be treated as if it was passed as NULL
bool TwodOnly = false; // Only used for 2D rendering
bool ForFont = false; // Mark font translations because they may require different handling than the ones for sprites-
bool NoTransparency = false; // This palette has no transparent index and must be excluded from all treatment for that.
private:
};
@ -58,19 +59,22 @@ private:
};
#define TRANSLATION_SHIFT 16
#define TRANSLATION_MASK ((1<<TRANSLATION_SHIFT)-1)
#define TRANSLATIONTYPE_MASK (255<<TRANSLATION_SHIFT)
enum
{
TRANSLATION_SHIFT = 16,
TRANSLATION_MASK = ((1 << TRANSLATION_SHIFT) - 1),
TRANSLATIONTYPE_MASK = (255 << TRANSLATION_SHIFT)
};
inline uint32_t TRANSLATION(uint8_t a, uint32_t b)
inline constexpr uint32_t TRANSLATION(uint8_t a, uint32_t b)
{
return (a << TRANSLATION_SHIFT) | b;
}
inline int GetTranslationType(uint32_t trans)
inline constexpr int GetTranslationType(uint32_t trans)
{
return (trans & TRANSLATIONTYPE_MASK) >> TRANSLATION_SHIFT;
}
inline int GetTranslationIndex(uint32_t trans)
inline constexpr int GetTranslationIndex(uint32_t trans)
{
return (trans & TRANSLATION_MASK);
}

View file

@ -61,7 +61,7 @@ enum
PRINT_TYPES = 1023, // Bitmask.
PRINT_NONOTIFY = 1024, // Flag - do not add to notify buffer
PRINT_NOLOG = 2048, // Flag - do not print to log file
PRINT_NOTIFY = 4096, // Flag - add to notify buffer
PRINT_NOTIFY = 4096, // Flag - add to game-native notify display - messages without this only go to the generic notification buffer.
};
enum

View file

@ -47,6 +47,7 @@
#include "templates.h"
#include "zstring.h"
#include "name.h"
#include <inttypes.h>
#include "filesystem.h"
// MACROS ------------------------------------------------------------------
@ -300,6 +301,12 @@ void FScanner :: OpenLumpNum (int lump)
void FScanner::PrepareScript ()
{
// If the file got a UTF-8 byte order mark, remove that.
if (ScriptBuffer.Len() > 3 && ScriptBuffer[0] == (char)0xEF && ScriptBuffer[1] == (char)0xBB && ScriptBuffer[2] == (char)0xBF)
{
ScriptBuffer = ScriptBuffer.Mid(3);
}
// The scanner requires the file to end with a '\n', so add one if
// it doesn't already.
if (ScriptBuffer.Len() == 0 || ScriptBuffer.Back() != '\n')
@ -400,6 +407,13 @@ void FScanner::RestorePos (const FScanner::SavedPos &pos)
Crossed = false;
}
long long FScanner::mystrtoll(const char* p, char** endp, int base)
{
// Do not treat a leading 0 as an octal identifier if so desired.
if (NoOctals && *p == '0' && p[1] != 'x' && p[1] != 'X' && base == 0) base = 10;
return strtoll(p, endp, base);
}
//==========================================================================
//
// FScanner :: isText
@ -491,6 +505,7 @@ bool FScanner::ScanString (bool tokens)
const char *marker, *tok;
bool return_val;
ParseError = false;
CheckOpen();
if (AlreadyGot)
{
@ -590,7 +605,7 @@ bool FScanner::CheckString (const char *name)
//
//==========================================================================
bool FScanner::GetToken ()
bool FScanner::GetToken (bool evaluate)
{
if (ScanString (true))
{
@ -608,7 +623,7 @@ bool FScanner::GetToken ()
}
else
{
BigNumber = strtoll(String, &stopper, 0);
BigNumber = mystrtoll(String, &stopper, 0);
Number = (int)BigNumber;// clamp<int64_t>(BigNumber, 0, UINT_MAX);
Float = Number;
}
@ -620,7 +635,19 @@ bool FScanner::GetToken ()
}
else if (TokenType == TK_StringConst)
{
StringLen = strbin(String);
StringLen = strbin(const_cast<char*>(String));
}
else if (TokenType == TK_Identifier && evaluate && symbols.CountUsed() > 0)
{
auto sym = symbols.CheckKey(String);
if (sym)
{
TokenType = sym->tokenType;
BigNumber = sym->Number;
Number = (int)sym->Number;
Float = sym->Float;
// String will retain the actual symbol name.
}
}
return true;
}
@ -633,9 +660,9 @@ bool FScanner::GetToken ()
//
//==========================================================================
void FScanner::MustGetAnyToken (void)
void FScanner::MustGetAnyToken (bool evaluate)
{
if (GetToken () == false)
if (GetToken (evaluate) == false)
{
ScriptError ("Missing token (unexpected end of file).");
}
@ -663,9 +690,9 @@ void FScanner::TokenMustBe (int token)
//
//==========================================================================
void FScanner::MustGetToken (int token)
void FScanner::MustGetToken (int token, bool evaluate)
{
MustGetAnyToken ();
MustGetAnyToken (evaluate);
TokenMustBe(token);
}
@ -678,9 +705,9 @@ void FScanner::MustGetToken (int token)
//
//==========================================================================
bool FScanner::CheckToken (int token)
bool FScanner::CheckToken (int token, bool evaluate)
{
if (GetToken ())
if (GetToken (evaluate))
{
if (TokenType == token)
{
@ -697,7 +724,7 @@ bool FScanner::CheckToken (int token)
//
//==========================================================================
bool FScanner::GetNumber ()
bool FScanner::GetNumber (bool evaluate)
{
char *stopper;
@ -710,11 +737,25 @@ bool FScanner::GetNumber ()
}
else
{
BigNumber = strtoll(String, &stopper, 0);
BigNumber = mystrtoll(String, &stopper, 0);
Number = (int)BigNumber;// clamp<int64_t>(BigNumber, 0, UINT_MAX);
if (*stopper != 0)
{
if (evaluate && symbols.CountUsed())
{
auto sym = symbols.CheckKey(String);
if (sym && sym->tokenType == TK_IntConst)
{
BigNumber = sym->Number;
Number = (int)sym->Number;
Float = sym->Float;
// String will retain the actual symbol name.
return true;
}
}
ScriptError ("SC_GetNumber: Bad numeric constant \"%s\".", String);
return false;
}
}
Float = Number;
@ -732,9 +773,9 @@ bool FScanner::GetNumber ()
//
//==========================================================================
void FScanner::MustGetNumber ()
void FScanner::MustGetNumber (bool evaluate)
{
if (GetNumber() == false)
if (GetNumber(evaluate) == false)
{
ScriptError ("Missing integer (unexpected end of file).");
}
@ -749,7 +790,7 @@ void FScanner::MustGetNumber ()
//
//==========================================================================
bool FScanner::CheckNumber ()
bool FScanner::CheckNumber (bool evaluate)
{
char *stopper;
@ -767,10 +808,23 @@ bool FScanner::CheckNumber ()
}
else
{
BigNumber = strtoll (String, &stopper, 0);
BigNumber = mystrtoll (String, &stopper, 0);
Number = (int)BigNumber;// clamp<int64_t>(BigNumber, 0, UINT_MAX);
if (*stopper != 0)
{
if (evaluate && symbols.CountUsed())
{
auto sym = symbols.CheckKey(String);
if (sym && sym->tokenType == TK_IntConst)
{
BigNumber = sym->Number;
Number = (int)sym->Number;
Float = sym->Float;
// String will retain the actual symbol name.
return true;
}
}
UnGet();
return false;
}
@ -792,7 +846,7 @@ bool FScanner::CheckNumber ()
//
//==========================================================================
bool FScanner::CheckFloat ()
bool FScanner::CheckFloat (bool evaluate)
{
char *stopper;
@ -807,6 +861,20 @@ bool FScanner::CheckFloat ()
Float = strtod (String, &stopper);
if (*stopper != 0)
{
if (evaluate && symbols.CountUsed())
{
auto sym = symbols.CheckKey(String);
if (sym && sym->tokenType == TK_IntConst && sym->tokenType != TK_FloatConst)
{
BigNumber = sym->Number;
Number = (int)sym->Number;
Float = sym->Float;
// String will retain the actual symbol name.
return true;
}
}
UnGet();
return false;
}
@ -825,7 +893,7 @@ bool FScanner::CheckFloat ()
//
//==========================================================================
bool FScanner::GetFloat ()
bool FScanner::GetFloat (bool evaluate)
{
char *stopper;
@ -835,7 +903,21 @@ bool FScanner::GetFloat ()
Float = strtod (String, &stopper);
if (*stopper != 0)
{
if (evaluate && symbols.CountUsed())
{
auto sym = symbols.CheckKey(String);
if (sym && sym->tokenType == TK_IntConst && sym->tokenType != TK_FloatConst)
{
BigNumber = sym->Number;
Number = (int)sym->Number;
Float = sym->Float;
// String will retain the actual symbol name.
return true;
}
}
ScriptError ("SC_GetFloat: Bad numeric constant \"%s\".", String);
return false;
}
Number = (int)Float;
return true;
@ -852,9 +934,9 @@ bool FScanner::GetFloat ()
//
//==========================================================================
void FScanner::MustGetFloat ()
void FScanner::MustGetFloat (bool evaluate)
{
if (GetFloat() == false)
if (GetFloat(evaluate) == false)
{
ScriptError ("Missing floating-point number (unexpected end of file).");
}
@ -938,44 +1020,54 @@ bool FScanner::Compare (const char *text)
//
//==========================================================================
bool FScanner::ScanValue(bool allowfloat)
bool FScanner::ScanValue(bool allowfloat, bool evaluate)
{
bool neg = false;
if (!GetToken())
if (!GetToken(evaluate))
{
return false;
}
if (TokenType == '-' || TokenType == '+')
{
neg = TokenType == '-';
if (!GetToken())
if (!GetToken(evaluate))
{
return false;
}
}
if (TokenType != TK_IntConst && (TokenType != TK_FloatConst || !allowfloat))
{
if (TokenType == TK_FloatConst && !allowfloat)
return false;
if (TokenType != TK_IntConst && TokenType != TK_FloatConst)
{
auto d = constants.CheckKey(String);
if (!d) return false;
if (!allowfloat && int64_t(*d) != *d) return false;
BigNumber = *d;
Number = *d;
Float = *d;
}
if (neg)
{
BigNumber = -BigNumber;
Number = -Number;
Float = -Float;
}
return true;
}
bool FScanner::CheckValue(bool allowfloat)
bool FScanner::CheckValue(bool allowfloat, bool evaluate)
{
auto savedstate = SavePos();
bool res = ScanValue(allowfloat);
bool res = ScanValue(allowfloat, evaluate);
if (!res) RestorePos(savedstate);
return res;
}
void FScanner::MustGetValue(bool allowfloat)
void FScanner::MustGetValue(bool allowfloat, bool evaluate)
{
if (!ScanValue(allowfloat)) ScriptError(allowfloat ? "Numeric constant expected" : "Integer constant expected");
if (!ScanValue(allowfloat, evaluate)) ScriptError(allowfloat ? "Numeric constant expected" : "Integer constant expected");
}
bool FScanner::CheckBoolToken()
@ -1079,6 +1171,12 @@ void FScanner::ScriptError (const char *message, ...)
va_end (arglist);
}
if (NoFatalErrors)
{
Printf(TEXTCOLOR_RED "Script error, \"%s\"" TEXTCOLOR_RED " line %d:\n" TEXTCOLOR_RED "%s\n", ScriptName.GetChars(),
AlreadyGot ? AlreadyGotLine : Line, composed.GetChars());
return;
}
I_Error ("Script error, \"%s\" line %d:\n%s\n", ScriptName.GetChars(),
AlreadyGot? AlreadyGotLine : Line, composed.GetChars());
}
@ -1123,6 +1221,72 @@ void FScanner::CheckOpen()
}
}
//==========================================================================
//
//
//
//==========================================================================
void FScanner::AddSymbol(const char *name, int64_t value)
{
Symbol sym;
sym.tokenType = TK_IntConst;
sym.Number = value;
sym.Float = value;
symbols.Insert(name, sym);
}
//==========================================================================
//
//
//
//==========================================================================
void FScanner::AddSymbol(const char* name, uint64_t value)
{
Symbol sym;
sym.tokenType = TK_UIntConst;
sym.Number = value;
sym.Float = value;
symbols.Insert(name, sym);
}
//==========================================================================
//
//
//
//==========================================================================
void FScanner::SkipToEndOfBlock()
{
int depth = 0;
while (1)
{
MustGetString(); // this will abort if it reaches the end of the file
if (Compare("{")) depth++;
else if (Compare("}"))
{
depth--;
if (depth < 0) return;
}
}
}
//==========================================================================
//
//
//
//==========================================================================
void FScanner::AddSymbol(const char* name, double value)
{
Symbol sym;
sym.tokenType = TK_FloatConst;
sym.Number = (int64_t)value;
sym.Float = value;
symbols.Insert(name, sym);
}
//==========================================================================
//
// a class that remembers a parser position

View file

@ -2,6 +2,7 @@
#define __SC_MAN_H__
#include "zstring.h"
#include "tarray.h"
#include "name.h"
#include "basics.h"
@ -46,6 +47,16 @@ public:
int SavedScriptLine;
};
struct Symbol
{
int tokenType;
int64_t Number;
double Float;
};
TMap<FName, Symbol> symbols;
// Methods ------------------------------------------------------
FScanner();
FScanner(const FScanner &other);
@ -70,11 +81,19 @@ public:
}
void SetCMode(bool cmode);
void SetNoOctals(bool cmode) { NoOctals = cmode; }
void SetNoFatalErrors(bool cmode) { NoFatalErrors = cmode; }
void SetEscape(bool esc);
void SetStateMode(bool stately);
void DisableStateOptions();
const SavedPos SavePos();
void RestorePos(const SavedPos &pos);
void AddSymbol(const char* name, int64_t value);
void AddSymbol(const char* name, uint64_t value);
inline void AddSymbol(const char* name, int32_t value) { return AddSymbol(name, int64_t(value)); }
inline void AddSymbol(const char* name, uint32_t value) { return AddSymbol(name, uint64_t(value)); }
void AddSymbol(const char* name, double value);
void SkipToEndOfBlock();
static FString TokenName(int token, const char *string=NULL);
@ -83,30 +102,40 @@ public:
void MustGetStringName(const char *name);
bool CheckString(const char *name);
bool GetToken();
void MustGetAnyToken();
bool GetToken(bool evaluate = false);
void MustGetAnyToken(bool evaluate = false);
void TokenMustBe(int token);
void MustGetToken(int token);
bool CheckToken(int token);
void MustGetToken(int token, bool evaluate = false);
bool CheckToken(int token, bool evaluate = false);
bool CheckTokenId(ENamedName id);
bool GetNumber();
void MustGetNumber();
bool CheckNumber();
bool GetNumber(bool evaluate = false);
void MustGetNumber(bool evaluate = false);
bool CheckNumber(bool evaluate = false);
bool GetFloat();
void MustGetFloat();
bool CheckFloat();
bool GetFloat(bool evaluate = false);
void MustGetFloat(bool evaluate = false);
bool CheckFloat(bool evaluate = false);
double *LookupConstant(FName name)
{
return constants.CheckKey(name);
}
// Token based variant
bool CheckValue(bool allowfloat);
void MustGetValue(bool allowfloat);
bool CheckValue(bool allowfloat, bool evaluate = true);
void MustGetValue(bool allowfloat, bool evaluate = true);
bool CheckBoolToken();
void MustGetBoolToken();
void UnGet();
bool Compare(const char *text);
inline bool Compare(const std::initializer_list<const char*>& list)
{
for (auto c : list) if (Compare(c)) return true;
return false;
}
int MatchString(const char * const *strings, size_t stride = sizeof(char*));
int MustMatchString(const char * const *strings, size_t stride = sizeof(char*));
int GetMessageLine();
@ -125,11 +154,13 @@ public:
double Float;
int Line;
bool End;
bool ParseError = false;
bool Crossed;
int LumpNum;
FString ScriptName;
protected:
long long mystrtoll(const char* p, char** endp, int base);
void PrepareScript();
void CheckOpen();
bool ScanString(bool tokens);
@ -137,6 +168,8 @@ protected:
// Strings longer than this minus one will be dynamically allocated.
static const int MAX_STRING_SIZE = 128;
TMap<FName, double> constants;
bool ScriptOpen;
FString ScriptBuffer;
const char *ScriptPtr;
@ -149,13 +182,15 @@ protected:
const char *LastGotPtr;
int LastGotLine;
bool CMode;
bool NoOctals = false;
bool NoFatalErrors = false;
uint8_t StateMode;
bool StateOptions;
bool Escape;
VersionInfo ParseVersion = { 0, 0, 0 }; // no ZScript extensions by default
bool ScanValue(bool allowfloat);
bool ScanValue(bool allowfloat, bool evaluate);
};
enum

View file

@ -54,6 +54,7 @@
#include "engineerrors.h"
#include "textures.h"
#include "texturemanager.h"
#include "base64.h"
extern DObject *WP_NOCHANGE;
bool save_full = false; // for testing. Should be removed afterward.
@ -675,6 +676,7 @@ void FSerializer::ReadObjects(bool hubtravel)
{
Printf(TEXTCOLOR_RED "Failed to restore all objects in savegame\n");
mErrors++;
mObjectErrors++;
}
}
catch(...)
@ -771,6 +773,31 @@ error:
return buff;
}
//==========================================================================
//
//
//
//==========================================================================
FSerializer &FSerializer::SerializeMemory(const char *key, void* mem, size_t length)
{
if (isWriting())
{
auto array = base64_encode((const uint8_t*)mem, length);
AddString(key, (const char*)array.Data());
}
else
{
auto cp = GetString(key);
if (key)
{
base64_decode(mem, length, cp);
}
}
return *this;
}
//==========================================================================
//
//

View file

@ -95,6 +95,7 @@ public:
virtual FSerializer &Sprite(const char *key, int32_t &spritenum, int32_t *def);
// This is only needed by the type system.
virtual FSerializer& StatePointer(const char* key, void* ptraddr, bool *res);
FSerializer& SerializeMemory(const char* key, void* mem, size_t length);
FSerializer &StringPtr(const char *key, const char *&charptr); // This only retrieves the address but creates no permanent copy of the string unlike the regular char* serializer.
FSerializer &AddString(const char *key, const char *charptr);
@ -181,6 +182,7 @@ public:
}
int mErrors = 0;
int mObjectErrors = 0;
};
FSerializer& Serialize(FSerializer& arc, const char* key, char& value, char* defval);
@ -218,7 +220,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, TArray<T, TT> &value,
{
if (arc.isWriting())
{
if (value.Size() == 0) return arc; // do not save empty arrays
if (value.Size() == 0 && key) return arc; // do not save empty arrays
}
bool res = arc.BeginArray(key);
if (arc.isReading())
@ -238,6 +240,12 @@ FSerializer &Serialize(FSerializer &arc, const char *key, TArray<T, TT> &value,
return arc;
}
template<int size>
FSerializer& Serialize(FSerializer& arc, const char* key, FixedBitArray<size>& value, FixedBitArray<size>* def)
{
return arc.SerializeMemory(key, value.Storage(), value.StorageSize());
}
template<> FSerializer& Serialize(FSerializer& arc, const char* key, PClass*& clst, PClass** def);
template<> FSerializer& Serialize(FSerializer& arc, const char* key, FFont*& font, FFont** def);
template<> FSerializer &Serialize(FSerializer &arc, const char *key, Dictionary *&dict, Dictionary **def);
@ -257,7 +265,8 @@ inline FSerializer &Serialize(FSerializer &arc, const char *key, DVector2 &p, DV
return arc.Array<double>(key, &p[0], def? &(*def)[0] : nullptr, 2, true);
}
inline FSerializer &Serialize(FSerializer &arc, const char *key, DAngle &p, DAngle *def)
template<class T>
inline FSerializer &Serialize(FSerializer &arc, const char *key, TAngle<T> &p, TAngle<T> *def)
{
return Serialize(arc, key, p.Degrees, def? &def->Degrees : nullptr);
}

View file

@ -226,15 +226,44 @@ struct FReader
//==========================================================================
template<class T>
FSerializer &SerializePointer(FSerializer &arc, const char *key, T *&value, T **defval, T *base)
FSerializer &SerializePointer(FSerializer &arc, const char *key, T *&value, T **defval, T *base, const int64_t count)
{
assert(base != nullptr);
assert(count > 0);
if (arc.isReading() || !arc.w->inObject() || defval == nullptr || value != *defval)
{
int64_t vv = value == nullptr ? -1 : value - base;
int64_t vv = -1;
if (value != nullptr)
{
vv = value - base;
if (vv < 0 || vv >= count)
{
Printf("Trying to serialize out-of-bounds array value with key '%s', index = %lli, size = %lli\n", key, vv, count);
vv = -1;
}
}
Serialize(arc, key, vv, nullptr);
value = vv < 0 ? nullptr : base + vv;
if (vv == -1)
value = nullptr;
else if (vv < 0 || vv >= count)
{
Printf("Trying to serialize out-of-bounds array value with key '%s', index = %lli, size = %lli\n", key, vv, count);
value = nullptr;
}
else
value = base + vv;
}
return arc;
}
template<class T>
FSerializer &SerializePointer(FSerializer &arc, const char *key, T *&value, T **defval, TArray<T> &array)
{
if (array.Size() == 0)
{
Printf("Trying to serialize a value with key '%s' from empty array\n", key);
return arc;
}
return SerializePointer(arc, key, value, defval, array.Data(), array.Size());
}

View file

@ -132,6 +132,9 @@ inline uint64_t rdtsc()
}
while (upper != temp);
return (static_cast<unsigned long long>(upper) << 32) | lower;
#elif defined __aarch64__
// TODO: Implement and test on ARM64
return 0;
#else // i386
if (CPU.bRDTSC)
{

View file

@ -450,7 +450,7 @@ void FStringTable::InsertString(int lumpnum, int langid, FName label, const FStr
auto replace = allMacros.CheckKey(lookupname);
for (int i = 0; i < 4; i++)
{
const char *replacement = replace && replace->Replacements[i] ? replace->Replacements[i].GetChars() : "";
const char *replacement = replace? replace->Replacements[i].GetChars() : "";
te.strings[i].Substitute(replacee, replacement);
}
}
@ -575,7 +575,10 @@ const char *FStringTable::GetString(const char *name, uint32_t *langtable, int g
if (item)
{
if (langtable) *langtable = map.first;
return item->strings[gender].GetChars();
auto c = item->strings[gender].GetChars();
if (c && *c == '$' && c[1] == '$')
return GetString(c + 2, langtable, gender);
return c;
}
}
}

View file

@ -110,6 +110,8 @@ public:
bool exists(const char *name);
void SetCallbacks(StringtableCallbacks* cb) { callbacks = cb; }
void InsertString(int lumpnum, int langid, FName label, const FString& string);
private:
FString activeLanguage;
@ -124,7 +126,6 @@ private:
bool LoadLanguageFromSpreadsheet(int lumpnum, const TArray<uint8_t> &buffer);
bool readMacros(int lumpnum);
void InsertString(int lumpnum, int langid, FName label, const FString &string);
void DeleteString(int langid, FName label);
void DeleteForLabel(int lumpnum, FName label);

View file

@ -367,7 +367,7 @@ FResourceFile *Check7Z(const char *filename, FileReader &file, bool quiet, LumpF
file.Seek(0, FileReader::SeekSet);
if (!memcmp(head, k7zSignature, k7zSignatureSize))
{
FResourceFile *rf = new F7ZFile(filename, file);
auto rf = new F7ZFile(filename, file);
if (rf->Open(quiet, filter)) return rf;
file = std::move(rf->Reader); // to avoid destruction of reader

View file

@ -254,9 +254,9 @@ int FDirectoryLump::FillCache()
FResourceFile *CheckDir(const char *filename, bool quiet, bool nosubdirflag, LumpFilterInfo* filter)
{
FResourceFile *rf = new FDirectory(filename, nosubdirflag);
auto rf = new FDirectory(filename, nosubdirflag);
if (rf->Open(quiet, filter)) return rf;
delete rf;
return NULL;
return nullptr;
}

View file

@ -140,7 +140,7 @@ FResourceFile *CheckGRP(const char *filename, FileReader &file, bool quiet, Lump
file.Seek(0, FileReader::SeekSet);
if (!memcmp(head, "KenSilverman", 12))
{
FResourceFile *rf = new FGrpFile(filename, file);
auto rf = new FGrpFile(filename, file);
if (rf->Open(quiet, filter)) return rf;
file = std::move(rf->Reader); // to avoid destruction of reader

View file

@ -94,7 +94,7 @@ bool FLumpFile::Open(bool quiet, LumpFilterInfo*)
FResourceFile *CheckLump(const char *filename, FileReader &file, bool quiet, LumpFilterInfo* filter)
{
// always succeeds
FResourceFile *rf = new FLumpFile(filename, file);
auto rf = new FLumpFile(filename, file);
if (rf->Open(quiet, filter)) return rf;
file = std::move(rf->Reader); // to avoid destruction of reader
delete rf;

View file

@ -134,7 +134,7 @@ FResourceFile *CheckPak(const char *filename, FileReader &file, bool quiet, Lump
file.Seek(0, FileReader::SeekSet);
if (!memcmp(head, "PACK", 4))
{
FResourceFile *rf = new FPakFile(filename, file);
auto rf = new FPakFile(filename, file);
if (rf->Open(quiet, filter)) return rf;
file = std::move(rf->Reader); // to avoid destruction of reader

View file

@ -248,7 +248,7 @@ FResourceFile *CheckRFF(const char *filename, FileReader &file, bool quiet, Lump
file.Seek(0, FileReader::SeekSet);
if (!memcmp(head, "RFF\x1a", 4))
{
FResourceFile *rf = new FRFFFile(filename, file);
auto rf = new FRFFFile(filename, file);
if (rf->Open(quiet, filter)) return rf;
file = std::move(rf->Reader); // to avoid destruction of reader

View file

@ -0,0 +1,155 @@
/*
** file_grp.cpp
**
**---------------------------------------------------------------------------
** Copyright 1998-2009 Randy Heit
** Copyright 2005-2020 Christoph Oelckers
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions
** are met:
**
** 1. Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** 2. Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
** 3. The name of the author may not be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**---------------------------------------------------------------------------
**
**
*/
#include "resourcefile.h"
#include "printf.h"
//==========================================================================
//
// Build GRP file
//
//==========================================================================
class FSSIFile : public FUncompressedFile
{
public:
FSSIFile(const char * filename, FileReader &file);
bool Open(bool quiet, int version, int lumpcount, LumpFilterInfo* filter);
};
//==========================================================================
//
// Initializes a Build GRP file
//
//==========================================================================
FSSIFile::FSSIFile(const char *filename, FileReader &file)
: FUncompressedFile(filename, file)
{
}
//==========================================================================
//
// Open it
// Note that SSIs can contain embedded GRPs which must be flagged accordingly.
//
//==========================================================================
bool FSSIFile::Open(bool quiet, int version, int lumpcount, LumpFilterInfo*)
{
NumLumps = lumpcount*2;
Lumps.Resize(lumpcount*2);
int32_t j = (version == 2 ? 267 : 254) + (lumpcount * 121);
for (uint32_t i = 0; i < NumLumps; i+=2)
{
char fn[13];
int strlength = Reader.ReadUInt8();
if (strlength > 12) strlength = 12;
Reader.Read(fn, 12);
fn[strlength] = 0;
int flength = Reader.ReadInt32();
Lumps[i].LumpNameSetup(fn);
Lumps[i].Position = j;
Lumps[i].LumpSize = flength;
Lumps[i].Owner = this;
if (strstr(fn, ".GRP")) Lumps[i].Flags |= LUMPF_EMBEDDED;
// SSI files can swap the order of the extension's characters - but there's no reliable detection for this and it can be mixed inside the same container,
// so we have no choice but to create another file record for the altered name.
std::swap(fn[strlength - 1], fn[strlength - 3]);
Lumps[i+1].LumpNameSetup(fn);
Lumps[i+1].Position = j;
Lumps[i+1].LumpSize = flength;
Lumps[i+1].Owner = this;
if (strstr(fn, ".GRP")) Lumps[i+1].Flags |= LUMPF_EMBEDDED;
j += flength;
Reader.Seek(104, FileReader::SeekCur);
}
return true;
}
//==========================================================================
//
// File open
//
//==========================================================================
FResourceFile* CheckSSI(const char* filename, FileReader& file, bool quiet, LumpFilterInfo* filter)
{
char zerobuf[72];
char buf[72];
memset(zerobuf, 0, 72);
auto skipstring = [&](size_t length)
{
size_t strlength = file.ReadUInt8();
if (strlength > length) return false;
size_t count = file.Read(buf, length);
buf[length] = 0;
if (count != length || strlen(buf) != strlength) return false;
if (length != strlength && memcmp(buf + strlength, zerobuf, length - strlength)) return false;
return true;
};
if (file.GetLength() >= 12)
{
// check if SSI
// this performs several checks because there is no "SSI" magic
int version = file.ReadInt32();
if (version == 1 || version == 2) // if
{
int numfiles = file.ReadInt32();
if (!skipstring(32)) return nullptr;
if (version == 2 && !skipstring(12)) return nullptr;
for (int i = 0; i < 3; i++)
{
if (!skipstring(70)) return nullptr;
}
auto ssi = new FSSIFile(filename, file);
if (ssi->Open(filename, version, numfiles, filter)) return ssi;
file = std::move(ssi->Reader); // to avoid destruction of reader
delete ssi;
}
}
return nullptr;
}

View file

@ -70,8 +70,8 @@ public:
int GetNamespace() const override { return Namespace; }
int GetFileOffset() { return Position; }
FileReader *GetReader()
int GetFileOffset() override { return Position; }
FileReader *GetReader() override
{
if(!Compressed)
{
@ -80,7 +80,7 @@ public:
}
return NULL;
}
int FillCache()
int FillCache() override
{
if(!Compressed)
{
@ -472,7 +472,7 @@ FResourceFile *CheckWad(const char *filename, FileReader &file, bool quiet, Lump
file.Seek(0, FileReader::SeekSet);
if (!memcmp(head, "IWAD", 4) || !memcmp(head, "PWAD", 4))
{
FResourceFile *rf = new FWadFile(filename, file);
auto rf = new FWadFile(filename, file);
if (rf->Open(quiet, filter)) return rf;
file = std::move(rf->Reader); // to avoid destruction of reader

View file

@ -148,7 +148,7 @@ FResourceFile *CheckWHRes(const char *filename, FileReader &file, bool quiet, Lu
if (offset != checkpos || length <= 0) return nullptr;
checkpos += (length+4095) / 4096;
}
FResourceFile *rf = new FWHResFile(filename, file);
auto rf = new FWHResFile(filename, file);
if (rf->Open(quiet, filter)) return rf;
file = std::move(rf->Reader); // to avoid destruction of reader
delete rf;

View file

@ -464,7 +464,7 @@ FResourceFile *CheckZip(const char *filename, FileReader &file, bool quiet, Lump
file.Seek(0, FileReader::SeekSet);
if (!memcmp(head, "PK\x3\x4", 4))
{
FResourceFile *rf = new FZipFile(filename, file);
auto rf = new FZipFile(filename, file);
if (rf->Open(quiet, filter)) return rf;
file = std::move(rf->Reader); // to avoid destruction of reader

View file

@ -1634,79 +1634,8 @@ static void PrintLastError ()
//
//==========================================================================
FResourceLump *FileSystem::Lookup(const char *name, const char *type)
{
FStringf fname("%s.%s", name, type);
auto lump = FindFile(fname);
if (lump >= 0) return FileInfo[lump].lump;
else return nullptr;
}
FResourceLump *FileSystem::Lookup(unsigned int id, const char *type)
{
auto lump = FindResource(id, type);
if (lump >= 0) return FileInfo[lump].lump;
else return nullptr;
}
FResourceLump* FileSystem::GetFileAt(int no)
{
return FileInfo[no].lump;
}
//==========================================================================
//
// Stand-ins for Blood's resource class
//
//==========================================================================
const void *FileSystem::Lock(int lump)
{
if ((size_t)lump >= FileInfo.Size()) return nullptr;
auto lumpp = FileInfo[lump].lump;
return lumpp->Lock();
}
void FileSystem::Unlock(int lump)
{
if ((size_t)lump >= FileInfo.Size()) return;
auto lumpp = FileInfo[lump].lump;
lumpp->Unlock();
}
const void *FileSystem::Get(int lump)
{
if ((size_t)lump >= FileInfo.Size()) return nullptr;
auto lumpp = FileInfo[lump].lump;
auto p = lumpp->Lock();
lumpp->RefCount = INT_MAX/2; // lock forever.
return p;
}
//==========================================================================
//
// Stand-ins for Blood's resource class
//
//==========================================================================
const void *FileSystem::Lock(FResourceLump *lump)
{
if (lump) return lump->Lock();
else return nullptr;
}
void FileSystem::Unlock(FResourceLump *lump)
{
if (lump) lump->Unlock();
}
const void *FileSystem::Load(FResourceLump *lump)
{
if (lump)
{
auto p = lump->Lock();
lump->RefCount = INT_MAX/2; // lock forever.
return p;
}
else return nullptr;
}

View file

@ -187,20 +187,8 @@ public:
int AddFromBuffer(const char* name, const char* type, char* data, int size, int id, int flags);
FileReader* GetFileReader(int wadnum); // Gets a FileReader object to the entire WAD
void InitHashChains();
// Blood stuff
FResourceLump* Lookup(const char* name, const char* type);
FResourceLump* Lookup(unsigned int id, const char* type);
FResourceLump* GetFileAt(int no);
const void* Lock(int lump);
void Unlock(int lump);
const void* Get(int lump);
static const void* Lock(FResourceLump* lump);
static void Unlock(FResourceLump* lump);
static const void* Load(FResourceLump* lump);;
protected:
struct LumpRecord;

View file

@ -240,10 +240,11 @@ FResourceFile *CheckRFF(const char *filename, FileReader &file, bool quiet, Lump
FResourceFile *CheckPak(const char *filename, FileReader &file, bool quiet, LumpFilterInfo* filter);
FResourceFile *CheckZip(const char *filename, FileReader &file, bool quiet, LumpFilterInfo* filter);
FResourceFile *Check7Z(const char *filename, FileReader &file, bool quiet, LumpFilterInfo* filter);
FResourceFile* CheckSSI(const char* filename, FileReader& file, bool quiet, LumpFilterInfo* filter);
FResourceFile *CheckLump(const char *filename,FileReader &file, bool quiet, LumpFilterInfo* filter);
FResourceFile *CheckDir(const char *filename, bool quiet, bool nosub, LumpFilterInfo* filter);
static CheckFunc funcs[] = { CheckWad, CheckZip, Check7Z, CheckPak, CheckGRP, CheckRFF, CheckLump };
static CheckFunc funcs[] = { CheckWad, CheckZip, Check7Z, CheckPak, CheckGRP, CheckRFF, CheckSSI, CheckLump };
FResourceFile *FResourceFile::DoOpenResourceFile(const char *filename, FileReader &file, bool quiet, bool containeronly, LumpFilterInfo* filter)
{

View file

@ -164,7 +164,6 @@ public:
const FString &GetHash() const { return Hash; }
virtual bool Open(bool quiet, LumpFilterInfo* filter) = 0;
virtual FResourceLump *GetLump(int no) = 0;
FResourceLump *FindLump(const char *name);
};

View file

@ -214,8 +214,8 @@ FFont::FFont (const char *name, const char *nametemplate, const char *filetempla
// Because a lot of wads with their own font seem to foolishly
// copy STCFN121 and make it a '|' themselves, wads must
// provide STCFN120 (x) and STCFN122 (z) for STCFN121 to load as a 'y'.
FStringf c120("%s120", nametemplate);
FStringf c122("%s122", nametemplate);
FStringf c120(nametemplate, 120);
FStringf c122(nametemplate, 122);
if (!TexMan.CheckForTexture(c120, ETextureType::MiscPatch).isValid() ||
!TexMan.CheckForTexture(c122, ETextureType::MiscPatch).isValid())
{
@ -328,14 +328,14 @@ FFont::FFont (const char *name, const char *nametemplate, const char *filetempla
auto orig = pic->GetTexture();
auto tex = MakeGameTexture(orig, nullptr, ETextureType::FontChar);
tex->CopySize(pic);
tex->CopySize(pic, true);
TexMan.AddGameTexture(tex);
Chars[i].OriginalPic = tex;
if (!noTranslate)
{
Chars[i].TranslatedPic = MakeGameTexture(new FImageTexture(new FFontChar1(orig->GetImage())), nullptr, ETextureType::FontChar);
Chars[i].TranslatedPic->CopySize(pic);
Chars[i].TranslatedPic->CopySize(pic, true);
TexMan.AddGameTexture(Chars[i].TranslatedPic);
}
else
@ -441,9 +441,9 @@ void FFont::ReadSheetFont(TArray<FolderEntry> &folderdata, int width, int height
auto pic = (*lump)->GetTexture();
Chars[i].OriginalPic = (*lump)->GetUseType() == ETextureType::FontChar? (*lump) : MakeGameTexture(pic, nullptr, ETextureType::FontChar);
Chars[i].OriginalPic->SetUseType(ETextureType::FontChar);
Chars[i].OriginalPic->CopySize(*lump);
Chars[i].OriginalPic->CopySize(*lump, true);
Chars[i].TranslatedPic = MakeGameTexture(new FImageTexture(new FFontChar1(pic->GetImage())), nullptr, ETextureType::FontChar);
Chars[i].TranslatedPic->CopySize(*lump);
Chars[i].TranslatedPic->CopySize(*lump, true);
Chars[i].TranslatedPic->SetUseType(ETextureType::FontChar);
if (Chars[i].OriginalPic != *lump) TexMan.AddGameTexture(Chars[i].OriginalPic);
TexMan.AddGameTexture(Chars[i].TranslatedPic);
@ -860,7 +860,7 @@ int FFont::GetColorTranslation (EColorRange range, PalEntry *color) const
}
if (color != nullptr) *color = retcolor;
}
if (ActiveColors == 0)
if (ActiveColors == 0 || range == CR_UNDEFINED)
return -1;
else if (range >= NumTextColors)
range = CR_UNTRANSLATED;
@ -880,6 +880,8 @@ int FFont::GetColorTranslation (EColorRange range, PalEntry *color) const
int FFont::GetCharCode(int code, bool needpic) const
{
int newcode;
if (code < 0 && code >= -128)
{
// regular chars turn negative when the 8th bit is set.
@ -905,8 +907,7 @@ int FFont::GetCharCode(int code, bool needpic) const
}
}
// Try stripping accents from accented characters.
int newcode = stripaccent(code);
if (newcode != code)
while ((newcode = stripaccent(code)) != code)
{
code = newcode;
if (code >= FirstChar && code <= LastChar && (!needpic || Chars[code - FirstChar].TranslatedPic != nullptr))
@ -918,7 +919,6 @@ int FFont::GetCharCode(int code, bool needpic) const
else
{
int originalcode = code;
int newcode;
// Try stripping accents from accented characters. This may repeat to allow multi-step fallbacks.
while ((newcode = stripaccent(code)) != code)
@ -977,7 +977,7 @@ FGameTexture *FFont::GetChar (int code, int translation, int *const width, bool
if (code < 0) return nullptr;
if (translation == CR_UNTRANSLATED && !forceremap)
if ((translation == CR_UNTRANSLATED || translation == CR_UNDEFINED) && !forceremap)
{
bool redirect = Chars[code].OriginalPic && Chars[code].OriginalPic != Chars[code].TranslatedPic;
if (redirected) *redirected = redirect;

View file

@ -46,7 +46,7 @@ public:
// FFont interface
FGameTexture *GetChar(int code, int translation, int *const width, bool *redirected = nullptr) const override;
int GetCharWidth (int code) const;
int GetCharWidth (int code) const override;
protected:
FTextureID PicNum;

View file

@ -105,13 +105,13 @@ FSpecialFont::FSpecialFont (const char *name, int first, int count, FGameTexture
{
auto pic = charlumps[i];
Chars[i].OriginalPic = MakeGameTexture(pic->GetTexture(), nullptr, ETextureType::FontChar);
Chars[i].OriginalPic->CopySize(pic);
Chars[i].OriginalPic->CopySize(pic, true);
TexMan.AddGameTexture(Chars[i].OriginalPic);
if (!noTranslate)
{
Chars[i].TranslatedPic = MakeGameTexture(new FImageTexture(new FFontChar1 (charlumps[i]->GetTexture()->GetImage())), nullptr, ETextureType::FontChar);
Chars[i].TranslatedPic->CopySize(charlumps[i]);
Chars[i].TranslatedPic->CopySize(charlumps[i], true);
TexMan.AddGameTexture(Chars[i].TranslatedPic);
}
else Chars[i].TranslatedPic = Chars[i].OriginalPic;

View file

@ -786,7 +786,7 @@ void V_InitFonts()
}
if (!(IntermissionFont = FFont::FindFont("IntermissionFont")))
{
if (fileSystem.CheckNumForName("WINUM0") >= 0)
if (TexMan.CheckForTexture("WINUM0", ETextureType::MiscPatch).isValid())
{
IntermissionFont = FFont::FindFont("IntermissionFont_Doom");
}

View file

@ -56,13 +56,13 @@ protected:
public:
FVoxelModel(FVoxel *voxel, bool owned);
~FVoxelModel();
bool Load(const char * fn, int lumpnum, const char * buffer, int length);
bool Load(const char * fn, int lumpnum, const char * buffer, int length) override;
void Initialize();
virtual int FindFrame(const char * name);
virtual void RenderFrame(FModelRenderer *renderer, FGameTexture * skin, int frame, int frame2, double inter, int translation=0);
virtual void AddSkins(uint8_t *hitlist);
virtual int FindFrame(const char * name) override;
virtual void RenderFrame(FModelRenderer *renderer, FGameTexture * skin, int frame, int frame2, double inter, int translation=0) override;
virtual void AddSkins(uint8_t *hitlist) override;
FTextureID GetPaletteTexture() const { return mPalette; }
void BuildVertexBuffer(FModelRenderer *renderer);
void BuildVertexBuffer(FModelRenderer *renderer) override;
float getAspectFactor(float vscale) override;
};

View file

@ -13,7 +13,7 @@ public:
PT_TwoSided = 1, // like normal, but don't cull backfaces
PT_Translucent = 2, // additive blending
PT_Masked = 3, // draw with alpha testing
PT_Modulated = 4, // modulated blending (src*dest*2)
PT_Modulated = 4, // overlay-like blending (rgb values below 128 darken, 128 is unchanged, and above 128 lighten)
// types mask
PT_Type = 7,
// flags

View file

@ -51,6 +51,7 @@
// TYPES -------------------------------------------------------------------
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
bool AreCompatiblePointerTypes(PType* dest, PType* source, bool forcompare = false);
// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
@ -665,7 +666,7 @@ PClass *PClass::FindClassTentative(FName name)
//
//==========================================================================
int PClass::FindVirtualIndex(FName name, PFunction::Variant *variant, PFunction *parentfunc)
int PClass::FindVirtualIndex(FName name, PFunction::Variant *variant, PFunction *parentfunc, bool exactReturnType)
{
auto proto = variant->Proto;
for (unsigned i = 0; i < Virtuals.Size(); i++)
@ -693,7 +694,10 @@ int PClass::FindVirtualIndex(FName name, PFunction::Variant *variant, PFunction
for (unsigned a = 0; a < proto->ReturnTypes.Size(); a++)
{
if (proto->ReturnTypes[a] != vproto->ReturnTypes[a])
PType* expected = vproto->ReturnTypes[a];
PType* actual = proto->ReturnTypes[a];
if (expected != actual && (exactReturnType || !AreCompatiblePointerTypes(expected, actual)))
{
fail = true;
break;

View file

@ -43,7 +43,7 @@ public:
void InitializeSpecials(void* addr, void* defaults, TArray<FTypeAndOffset> PClass::* Inits);
void WriteAllFields(FSerializer &ar, const void *addr) const;
bool ReadAllFields(FSerializer &ar, void *addr) const;
int FindVirtualIndex(FName name, PFunction::Variant *variant, PFunction *parentfunc);
int FindVirtualIndex(FName name, PFunction::Variant *variant, PFunction *parentfunc, bool exactReturnType);
PSymbol *FindSymbol(FName symname, bool searchparents) const;
PField *AddField(FName name, PType *type, uint32_t flags);
void InitializeDefaults();

View file

@ -52,8 +52,6 @@
EXTERN_CVAR(Int, m_use_mouse)
CVAR(Bool, use_mouse, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
CVAR(Bool, m_noprescale, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
CVAR(Bool, m_filter, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
CVAR(Bool, k_allowfullscreentoggle, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
@ -75,7 +73,7 @@ size_t s_skipMouseMoves;
void CheckGUICapture()
{
bool wantCapt = sysCallbacks && sysCallbacks->WantGuiCapture && sysCallbacks->WantGuiCapture();
bool wantCapt = sysCallbacks.WantGuiCapture && sysCallbacks.WantGuiCapture();
if (wantCapt != GUICapture)
{
@ -151,7 +149,7 @@ void CheckNativeMouse()
}
else
{
bool captureModeInGame = sysCallbacks && sysCallbacks->CaptureModeInGame && sysCallbacks->CaptureModeInGame();
bool captureModeInGame = sysCallbacks.CaptureModeInGame && sysCallbacks.CaptureModeInGame();
wantNative = (!m_use_mouse || MENU_WaitKey != menuactive)
&& (!captureModeInGame || GUICapture);
}
@ -163,7 +161,7 @@ void CheckNativeMouse()
&& (MENU_On == menuactive || MENU_OnNoPause == menuactive);
}
if (!wantNative && sysCallbacks && sysCallbacks->WantNativeMouse && sysCallbacks->WantNativeMouse())
if (!wantNative && sysCallbacks.WantNativeMouse && sysCallbacks.WantNativeMouse())
wantNative = true;
I_SetNativeMouse(wantNative);
@ -488,42 +486,9 @@ void ProcessMouseMoveInMenu(NSEvent* theEvent)
void ProcessMouseMoveInGame(NSEvent* theEvent)
{
int x([theEvent deltaX]);
int y(-[theEvent deltaY]);
int y([theEvent deltaY]);
if (0 == x && 0 == y)
{
return;
}
if (!m_noprescale)
{
x <<= 2;
}
event_t event = {};
static int lastX = 0, lastY = 0;
if (m_filter)
{
event.x = (x + lastX) / 2;
event.y = (y + lastY) / 2;
}
else
{
event.x = x;
event.y = y;
}
lastX = x;
lastY = y;
if (0 != event.x || 0 != event.y)
{
event.type = EV_Mouse;
D_PostEvent(&event);
}
PostMouseMove(x, y);
}

View file

@ -1066,7 +1066,7 @@ void IOKitJoystickManager::UseAxesPolling(const bool axesPolling)
void PostDeviceChangeEvent()
{
const event_t event = { EV_DeviceChange };
event_t event = { EV_DeviceChange };
D_PostEvent(&event);
}

View file

@ -101,15 +101,26 @@ void I_DetectOS()
const char* name = "Unknown version";
if (10 == version.majorVersion) switch (version.minorVersion)
if (10 == version.majorVersion)
{
case 9: name = "OS X Mavericks"; break;
case 10: name = "OS X Yosemite"; break;
case 11: name = "OS X El Capitan"; break;
case 12: name = "macOS Sierra"; break;
case 13: name = "macOS High Sierra"; break;
case 14: name = "macOS Mojave"; break;
case 15: name = "macOS Catalina"; break;
switch (version.minorVersion)
{
case 9: name = "OS X Mavericks"; break;
case 10: name = "OS X Yosemite"; break;
case 11: name = "OS X El Capitan"; break;
case 12: name = "macOS Sierra"; break;
case 13: name = "macOS High Sierra"; break;
case 14: name = "macOS Mojave"; break;
case 15: name = "macOS Catalina"; break;
case 16: name = "macOS Big Sur"; break;
}
}
else if (11 == version.majorVersion)
{
switch (version.minorVersion)
{
case 0: name = "macOS Big Sur"; break;
}
}
char release[16] = "unknown";
@ -124,7 +135,9 @@ void I_DetectOS()
#ifdef __i386__
"32-bit Intel";
#elif defined __x86_64__
"64-bit Intel";
"64-bit Intel";
#elif defined __aarch64__
"64-bit ARM";
#else
"Unknown";
#endif

View file

@ -102,6 +102,7 @@ EXTERN_CVAR(Int, vid_preferbackend)
EXTERN_CVAR(Bool, vk_debug)
CVAR(Bool, mvk_debug, false, 0)
CVAR(Bool, vid_nativefullscreen, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
CUSTOM_CVAR(Bool, vid_autoswitch, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL)
{
@ -290,6 +291,7 @@ CocoaWindow* CreateWindow(const NSUInteger styleMask)
[window setOpaque:YES];
[window makeFirstResponder:appCtrl];
[window setAcceptsMouseMovedEvents:YES];
[window exitAppOnClose];
NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
[nc addObserver:window
@ -633,7 +635,6 @@ void SystemBaseFrameBuffer::SetWindowedMode()
const NSRect frameSize = NSMakeRect(win_x, win_y, win_w, win_h);
[m_window setFrame:frameSize display:YES];
[m_window enterFullscreenOnZoom];
[m_window exitAppOnClose];
}
void SystemBaseFrameBuffer::SetMode(const bool fullscreen, const bool hiDPI)
@ -650,7 +651,11 @@ void SystemBaseFrameBuffer::SetMode(const bool fullscreen, const bool hiDPI)
[m_window.contentView layer].contentsScale = hiDPI ? m_window.screen.backingScaleFactor : 1.0;
}
if (fullscreen)
if (vid_nativefullscreen && fullscreen != m_fullscreen)
{
[m_window toggleFullScreen:(nil)];
}
else if (fullscreen)
{
SetFullscreenMode();
}
@ -742,7 +747,11 @@ void SystemGLFrameBuffer::SetMode(const bool fullscreen, const bool hiDPI)
NSOpenGLView* const glView = [m_window contentView];
[glView setWantsBestResolutionOpenGLSurface:hiDPI];
if (fullscreen)
if (vid_nativefullscreen && fullscreen != m_fullscreen)
{
[m_window toggleFullScreen:(nil)];
}
else if (fullscreen)
{
SetFullscreenMode();
}

View file

@ -66,8 +66,8 @@ static const char* const tableHeaders[NUM_COLUMNS] = { "IWAD", "Game" };
- (void)dealloc;
- (IWADTableData *)init:(WadStuff *) wads num:(int) numwads;
- (int)numberOfRowsInTableView:(NSTableView *)aTableView;
- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex;
- (NSInteger)numberOfRowsInTableView:(NSTableView *)aTableView;
- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex;
@end
@implementation IWADTableData
@ -100,12 +100,12 @@ static const char* const tableHeaders[NUM_COLUMNS] = { "IWAD", "Game" };
return self;
}
- (int)numberOfRowsInTableView:(NSTableView *)aTableView
- (NSInteger)numberOfRowsInTableView:(NSTableView *)aTableView
{
return [data count];
}
- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex
- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex
{
NSParameterAssert(rowIndex >= 0 && (unsigned int) rowIndex < [data count]);
NSMutableDictionary *record = [data objectAtIndex:rowIndex];
@ -375,6 +375,8 @@ static NSString* GetArchitectureString()
return @"i386";
#elif defined __x86_64__
return @"x86_64";
#elif defined __aarch64__
return @"arm64";
#endif
}
@ -382,13 +384,6 @@ static void RestartWithParameters(const WadStuff& wad, NSString* parameters)
{
assert(nil != parameters);
defaultiwad = wad.Name;
GameConfig->ArchiveGlobalData();
GameConfig->WriteConfigFile();
delete GameConfig;
GameConfig = nullptr;
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
@try
@ -396,22 +391,14 @@ static void RestartWithParameters(const WadStuff& wad, NSString* parameters)
NSString* executablePath = [NSString stringWithUTF8String:Args->GetArg(0)];
NSMutableArray* const arguments = [[NSMutableArray alloc] init];
// The following value shoud be equal to NSAppKitVersionNumber10_5
// It's hard-coded in order to build with earlier SDKs
const bool canSelectArchitecture = NSAppKitVersionNumber >= 949;
if (canSelectArchitecture)
{
[arguments addObject:@"-arch"];
[arguments addObject:GetArchitectureString()];
[arguments addObject:executablePath];
executablePath = @"/usr/bin/arch";
}
[arguments addObject:@"-arch"];
[arguments addObject:GetArchitectureString()];
[arguments addObject:executablePath];
[arguments addObject:@"-iwad"];
[arguments addObject:[NSString stringWithUTF8String:wad.Path]];
[arguments addObject:@"+defaultiwad"];
[arguments addObject:[NSString stringWithUTF8String:wad.Name]];
[arguments addObject:[NSString stringWithFormat:@"+osx_additional_parameters \"%@\"", parameters]];
for (int i = 1, count = Args->NumArgs(); i < count; ++i)
{
@ -433,7 +420,7 @@ static void RestartWithParameters(const WadStuff& wad, NSString* parameters)
wordfree(&expansion);
}
[NSTask launchedTaskWithLaunchPath:executablePath
[NSTask launchedTaskWithLaunchPath:@"/usr/bin/arch"
arguments:arguments];
_exit(0); // to avoid atexit()'s functions
@ -454,11 +441,10 @@ int I_PickIWad_Cocoa (WadStuff *wads, int numwads, bool showwin, int defaultiwad
IWADPicker *picker = [IWADPicker alloc];
int ret = [picker pickIWad:wads num:numwads showWindow:showwin defaultWad:defaultiwad];
NSString* parametersToAppend = [picker commandLineParameters];
osx_additional_parameters = [parametersToAppend UTF8String];
if (ret >= 0)
{
NSString* parametersToAppend = [picker commandLineParameters];
if (0 != [parametersToAppend length])
{
RestartWithParameters(wads[ret], parametersToAppend);

View file

@ -52,6 +52,7 @@ bool I_SetCursor(FGameTexture *cursorpic)
return false;
}
SDL_ShowCursor(SDL_DISABLE);
if (cursorSurface == NULL)
cursorSurface = SDL_CreateRGBSurface (0, 32, 32, 32, MAKEARGB(0,255,0,0), MAKEARGB(0,0,255,0), MAKEARGB(0,0,0,255), MAKEARGB(255,0,0,0));
@ -67,6 +68,7 @@ bool I_SetCursor(FGameTexture *cursorpic)
SDL_FreeCursor (cursor);
cursor = SDL_CreateColorCursor (cursorSurface, 0, 0);
SDL_SetCursor (cursor);
SDL_ShowCursor(SDL_ENABLE);
}
else
{

View file

@ -54,8 +54,6 @@ bool GUICapture;
static bool NativeMouse = true;
CVAR (Bool, use_mouse, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
CVAR (Bool, m_noprescale, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
CVAR (Bool, m_filter, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
extern int WaitingForKey, chatmodeon;
@ -167,7 +165,7 @@ static const TMap<SDL_Scancode, uint8_t> KeyScanToDIK(InitKeyScanMap());
static void I_CheckGUICapture ()
{
bool wantCapt = sysCallbacks && sysCallbacks->WantGuiCapture && sysCallbacks->WantGuiCapture();
bool wantCapt = sysCallbacks.WantGuiCapture && sysCallbacks.WantGuiCapture();
if (wantCapt != GUICapture)
{
@ -191,30 +189,6 @@ void I_ReleaseMouseCapture()
SDL_SetRelativeMouseMode (SDL_FALSE);
}
static void PostMouseMove (int x, int y)
{
static int lastx = 0, lasty = 0;
event_t ev = { 0,0,0,0,0,0,0 };
if (m_filter)
{
ev.x = (x + lastx) / 2;
ev.y = (y + lasty) / 2;
}
else
{
ev.x = x;
ev.y = y;
}
lastx = x;
lasty = y;
if (ev.x | ev.y)
{
ev.type = EV_Mouse;
D_PostEvent (&ev);
}
}
static void MouseRead ()
{
int x, y;
@ -225,21 +199,17 @@ static void MouseRead ()
}
SDL_GetRelativeMouseState (&x, &y);
if (x | y)
{
PostMouseMove (m_noprescale ? x : x << 2, -y);
}
PostMouseMove (x, y);
}
static void I_CheckNativeMouse ()
{
bool focus = SDL_GetKeyboardFocus() != NULL;
bool captureModeInGame = sysCallbacks && sysCallbacks->CaptureModeInGame && sysCallbacks->CaptureModeInGame();
bool captureModeInGame = sysCallbacks.CaptureModeInGame && sysCallbacks.CaptureModeInGame();
bool wantNative = !focus || (!use_mouse || GUICapture || !captureModeInGame);
if (!wantNative && sysCallbacks && sysCallbacks->WantNativeMouse && sysCallbacks->WantNativeMouse())
if (!wantNative && sysCallbacks.WantNativeMouse && sysCallbacks.WantNativeMouse())
wantNative = true;
if (wantNative != NativeMouse)
@ -493,13 +463,10 @@ void MessagePump (const SDL_Event &sev)
case SDL_JOYBUTTONDOWN:
case SDL_JOYBUTTONUP:
if (!GUICapture)
{
event.type = sev.type == SDL_JOYBUTTONDOWN ? EV_KeyDown : EV_KeyUp;
event.data1 = KEY_FIRSTJOYBUTTON + sev.jbutton.button;
if(event.data1 != 0)
D_PostEvent(&event);
}
event.type = sev.type == SDL_JOYBUTTONDOWN ? EV_KeyDown : EV_KeyUp;
event.data1 = KEY_FIRSTJOYBUTTON + sev.jbutton.button;
if(event.data1 != 0)
D_PostEvent(&event);
break;
}
}

View file

@ -87,7 +87,7 @@ FArgs *Args;
static int GetCrashInfo (char *buffer, char *end)
{
if (sysCallbacks && sysCallbacks->CrashInfo) sysCallbacks->CrashInfo(buffer, end - buffer, "\n");
if (sysCallbacks.CrashInfo) sysCallbacks.CrashInfo(buffer, end - buffer, "\n");
return strlen(buffer);
}

View file

@ -75,7 +75,6 @@
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
extern double refreshfreq;
extern IVideo *Video;
EXTERN_CVAR (Int, vid_adapter)
@ -451,19 +450,6 @@ SDLVideo::SDLVideo ()
Priv::CreateWindow(SDL_WINDOW_HIDDEN);
}
#endif
// Get refresh rate for current display.
SDL_DisplayMode display;
if(SDL_GetCurrentDisplayMode(vid_adapter, &display) == 0)
{
refreshfreq = display.refresh_rate;
}
else
{
fprintf(stderr, "Failed to get refresh rate: %s\n", SDL_GetError());
return;
}
}
SDLVideo::~SDLVideo ()

View file

@ -58,7 +58,6 @@ extern "C" {
__declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
__declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1;
}
void GetRefreshRate(HWND hWnd);
EXTERN_CVAR(Int, vid_defwidth)
EXTERN_CVAR(Int, vid_defheight)
@ -339,7 +338,6 @@ void SystemBaseFrameBuffer::PositionWindow(bool fullscreen, bool initialcall)
}
m_Fullscreen = fullscreen;
SetSize(GetClientWidth(), GetClientHeight());
GetRefreshRate(Window);
}
//==========================================================================

View file

@ -109,7 +109,7 @@ SystemGLFrameBuffer::SystemGLFrameBuffer(void *hMonitor, bool fullscreen) : Syst
//
//==========================================================================
EXTERN_CVAR(Bool, vid_vsync);
CUSTOM_CVAR(Bool, gl_control_tear, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
CUSTOM_CVAR(Bool, gl_control_tear, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
{
vid_vsync.Callback();
}

View file

@ -459,7 +459,7 @@ void FDInputJoystick::ProcessInput()
{
// Since we sorted the axes, we know that the first two are definitely X and Y.
// They are probably a single stick, so use angular position to determine buttons.
buttonstate = Joy_XYAxesToButtons(axisval, Axes[0].Value);
buttonstate = Joy_XYAxesToButtons(Axes[0].Value, axisval);
Joy_GenerateButtonEvents(info->ButtonValue, buttonstate, 4, KEY_JOYAXIS1PLUS);
}
info->ButtonValue = buttonstate;

View file

@ -135,8 +135,7 @@ LPDIRECTINPUT g_pdi3;
extern bool AppActive;
int SessionState = 0;
int BlockMouseMove;
extern double refreshfreq;
int BlockMouseMove;
static bool EventHandlerResultForNativeMouse;
@ -148,7 +147,7 @@ extern int chatmodeon;
static void I_CheckGUICapture ()
{
bool wantCapt = sysCallbacks && sysCallbacks->WantGuiCapture && sysCallbacks->WantGuiCapture();
bool wantCapt = sysCallbacks.WantGuiCapture && sysCallbacks.WantGuiCapture();
if (wantCapt != GUICapture)
{
@ -345,22 +344,6 @@ bool CallHook(FInputDevice *device, HWND hWnd, UINT message, WPARAM wParam, LPAR
return device->WndProcHook(hWnd, message, wParam, lParam, result);
}
void GetRefreshRate(HWND hWnd)
{
HMONITOR moni = MonitorFromWindow(hWnd, MONITOR_DEFAULTTONEAREST);
MONITORINFOEXA moninf;
moninf.cbSize = sizeof(moninf);
if (GetMonitorInfoA(moni, (LPMONITORINFO)&moninf))
{
DEVMODEA dm;
dm.dmSize = sizeof(DEVMODEA);
if (EnumDisplaySettingsA(moninf.szDevice, ENUM_CURRENT_SETTINGS, &dm))
{
refreshfreq = dm.dmDisplayFrequency;
}
}
}
LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
LRESULT result;
@ -411,7 +394,7 @@ LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
return result;
}
if (message == WM_LBUTTONDOWN && sysCallbacks && sysCallbacks->WantLeftButton() && sysCallbacks->WantLeftButton())
if (message == WM_LBUTTONDOWN && sysCallbacks.WantLeftButton() && sysCallbacks.WantLeftButton())
{
if (GUIWndProcHook(hWnd, message, wParam, lParam, &result))
{
@ -446,7 +429,6 @@ LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
break;
case WM_SETFOCUS:
GetRefreshRate(hWnd);
I_CheckNativeMouse (false, EventHandlerResultForNativeMouse); // This cannot call the event handler. Doing it from here is unsafe.
break;
@ -491,8 +473,6 @@ LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
break;
case WM_DISPLAYCHANGE:
GetRefreshRate(hWnd);
// fall through
case WM_STYLECHANGED:
return DefWindowProc(hWnd, message, wParam, lParam);
@ -524,7 +504,7 @@ LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
SetPriorityClass (GetCurrentProcess (), INGAME_PRIORITY_CLASS);
}
else if (!noidle && !(sysCallbacks && sysCallbacks->NetGame && sysCallbacks->NetGame()))
else if (!noidle && !(sysCallbacks.NetGame && sysCallbacks.NetGame()))
{
SetPriorityClass (GetCurrentProcess (), IDLE_PRIORITY_CLASS);
}
@ -769,7 +749,7 @@ void I_StartTic ()
BlockMouseMove--;
buttonMap.ResetButtonTriggers ();
I_CheckGUICapture ();
EventHandlerResultForNativeMouse = sysCallbacks && sysCallbacks->WantNativeMouse && sysCallbacks->WantNativeMouse();
EventHandlerResultForNativeMouse = sysCallbacks.WantNativeMouse && sysCallbacks.WantNativeMouse();
I_CheckNativeMouse (false, EventHandlerResultForNativeMouse);
I_GetEvent ();
}

View file

@ -77,7 +77,6 @@ public:
virtual void Ungrab() = 0;
protected:
void PostMouseMove(int x, int y);
void WheelMoved(int axis, int wheelmove);
void PostButtonEvent(int button, bool down);
void ClearButtonState();

View file

@ -277,6 +277,8 @@ void FKeyboard::PostKeyEvent(int key, INTBOOL down, bool foreground)
}
ev.data1 = key;
ev.data2 = Convert[key];
ev.data3 = 0;
if (CheckKey(DIK_LSHIFT) || CheckKey(DIK_RSHIFT)) ev.data3 |= 1;
D_PostEvent(&ev);
}

View file

@ -1108,7 +1108,7 @@ LONG WINAPI CatchAllExceptions (LPEXCEPTION_POINTERS info)
char *custominfo = (char *)HeapAlloc (GetProcessHeap(), 0, 16384);
CrashPointers = *info;
if (sysCallbacks && sysCallbacks->CrashInfo && custominfo) sysCallbacks->CrashInfo(custominfo, 16384, "\r\n");
if (sysCallbacks.CrashInfo && custominfo) sysCallbacks.CrashInfo(custominfo, 16384, "\r\n");
CreateCrashLog (custominfo, (DWORD)strlen(custominfo), ConWindow);
// If the main thread crashed, then make it clean up after itself.

View file

@ -162,8 +162,6 @@ bool NativeMouse;
bool CursorState;
CVAR (Bool, use_mouse, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
CVAR (Bool, m_noprescale, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
CVAR (Bool, m_filter, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
CVAR (Bool, m_hidepointer, true, 0)
CUSTOM_CVAR (Int, in_mouse, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOINITCALL)
@ -271,7 +269,7 @@ void I_CheckNativeMouse(bool preferNative, bool eventhandlerresult)
else
{
bool pauseState = false;
bool captureModeInGame = sysCallbacks && sysCallbacks->CaptureModeInGame && sysCallbacks->CaptureModeInGame();
bool captureModeInGame = sysCallbacks.CaptureModeInGame && sysCallbacks.CaptureModeInGame();
want_native = ((!m_use_mouse || menuactive != MENU_WaitKey) &&
(!captureModeInGame || GUICapture));
}
@ -314,38 +312,6 @@ FMouse::FMouse()
WheelMove[1] = 0;
}
//==========================================================================
//
// FMouse :: PostMouseMove
//
// Posts a mouse movement event, potentially averaging it with the previous
// movement. If there is no movement to post, then no event is generated.
//
//==========================================================================
void FMouse::PostMouseMove(int x, int y)
{
event_t ev = { 0 };
if (m_filter)
{
ev.x = (x + LastX) / 2;
ev.y = (y + LastY) / 2;
}
else
{
ev.x = x;
ev.y = y;
}
LastX = x;
LastY = y;
if (ev.x | ev.y)
{
ev.type = EV_Mouse;
D_PostEvent(&ev);
}
}
//==========================================================================
//
// FMouse :: WheelMoved
@ -620,8 +586,8 @@ bool FRawMouse::ProcessRawInput(RAWINPUT *raw, int code)
{
WheelMoved(1, (SHORT)raw->data.mouse.usButtonData);
}
int x = m_noprescale ? raw->data.mouse.lLastX : raw->data.mouse.lLastX << 2;
int y = -raw->data.mouse.lLastY;
int x = raw->data.mouse.lLastX;
int y = raw->data.mouse.lLastY;
PostMouseMove(x, y);
if (x | y)
{
@ -847,7 +813,7 @@ void FDInputMouse::ProcessInput()
}
}
}
PostMouseMove(m_noprescale ? dx : dx<<2, -dy);
PostMouseMove(dx, dy);
}
//==========================================================================
@ -952,18 +918,13 @@ void FWin32Mouse::ProcessInput()
}
x = pt.x - PrevX;
y = PrevY - pt.y;
y = pt.y - PrevY;
if (!m_noprescale)
{
x *= 3;
y *= 2;
}
if (x | y)
{
CenterMouse(pt.x, pt.y, &PrevX, &PrevY);
}
PostMouseMove(x, y);
PostMouseMove(2* x, 2* y); // The factor of 2 is needed to match this with raw mouse input.
}
//==========================================================================

View file

@ -52,6 +52,7 @@
#include "printf.h"
#include "startupinfo.h"
#include "i_interface.h"
#include "texturemanager.h"
// MACROS ------------------------------------------------------------------
@ -607,6 +608,7 @@ int RunEndoom()
void ST_Endoom()
{
TexMan.DeleteAll();
int code = RunEndoom();
throw CExitEvent(code);

View file

@ -396,8 +396,8 @@ static const int StrifeStartupPicSizes[4 + 2 + 1] =
static void ST_Sound(const char* sndname)
{
if (sysCallbacks && sysCallbacks->PlayStartupSound)
sysCallbacks->PlayStartupSound(sndname);
if (sysCallbacks.PlayStartupSound)
sysCallbacks.PlayStartupSound(sndname);
}
//==========================================================================

View file

@ -58,7 +58,7 @@ public:
void Swap();
bool IsHWGammaActive() const { return HWGammaActive; }
void SetVSync(bool vsync);
void SetVSync(bool vsync) override;
void Draw2D() override;
void PostProcessScene(bool swscene, int fixedcm, float flash, const std::function<void()> &afterBloomDrawEndScene2D) override;

View file

@ -49,7 +49,7 @@ void FGLRenderer::RenderScreenQuad()
{
auto buffer = static_cast<GLVertexBuffer *>(screen->mVertexData->GetBufferObjects().first);
buffer->Bind(nullptr);
glDrawArrays(GL_TRIANGLE_STRIP, FFlatVertexBuffer::PRESENT_INDEX, 4);
glDrawArrays(GL_TRIANGLE_STRIP, FFlatVertexBuffer::PRESENT_INDEX, 3);
}
void FGLRenderer::PostProcessScene(int fixedcm, float flash, const std::function<void()> &afterBloomDrawEndScene2D)

View file

@ -329,12 +329,24 @@ void FGLRenderState::ApplyMaterial(FMaterial *mat, int clampmode, int translatio
if (base->BindOrCreate(tex->GetTexture(), 0, clampmode, translation, layer->scaleFlags))
{
for (int i = 1; i<numLayers; i++)
if (!(layer->scaleFlags & CTF_Indexed))
{
auto systex = static_cast<FHardwareTexture*>(mat->GetLayer(i, 0, &layer));
// fixme: Upscale flags must be disabled for certain layers.
systex->BindOrCreate(layer->layerTexture, i, clampmode, 0, layer->scaleFlags);
maxbound = i;
for (int i = 1; i < numLayers; i++)
{
auto systex = static_cast<FHardwareTexture*>(mat->GetLayer(i, 0, &layer));
// fixme: Upscale flags must be disabled for certain layers.
systex->BindOrCreate(layer->layerTexture, i, clampmode, 0, layer->scaleFlags);
maxbound = i;
}
}
else
{
for (int i = 1; i < 3; i++)
{
auto systex = static_cast<FHardwareTexture*>(mat->GetLayer(i, translation, &layer));
systex->Bind(i, false);
maxbound = i;
}
}
}
// unbind everything from the last texture that's still active

View file

@ -109,8 +109,17 @@ uint8_t FSamplerManager::Bind(int texunit, int num, int lastval)
void FSamplerManager::SetTextureFilterMode()
{
UnbindAll();
int filter = sysCallbacks && sysCallbacks->DisableTextureFilter && sysCallbacks->DisableTextureFilter() ? 0 : gl_texture_filter;
GLint bounds[IHardwareTexture::MAX_TEXTURES];
// Unbind all
for(int i = IHardwareTexture::MAX_TEXTURES-1; i >= 0; i--)
{
glActiveTexture(GL_TEXTURE0 + i);
glGetIntegerv(GL_SAMPLER_BINDING, &bounds[i]);
glBindSampler(i, 0);
}
int filter = sysCallbacks.DisableTextureFilter && sysCallbacks.DisableTextureFilter() ? 0 : gl_texture_filter;
for (int i = 0; i < 4; i++)
{
@ -122,6 +131,10 @@ void FSamplerManager::SetTextureFilterMode()
glSamplerParameteri(mSamplers[CLAMP_XY_NOMIP], GL_TEXTURE_MAG_FILTER, TexFilter[filter].magfilter);
glSamplerParameteri(mSamplers[CLAMP_CAMTEX], GL_TEXTURE_MIN_FILTER, TexFilter[filter].magfilter);
glSamplerParameteri(mSamplers[CLAMP_CAMTEX], GL_TEXTURE_MAG_FILTER, TexFilter[filter].magfilter);
for(int i = 0; i < IHardwareTexture::MAX_TEXTURES; i++)
{
glBindSampler(i, bounds[i]);
}
}

View file

@ -246,7 +246,6 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char *
uniform vec4 uTextureBlendColor;
uniform vec4 uTextureModulateColor;
uniform vec4 uTextureAddColor;
uniform vec4 uBlendColor;
uniform vec4 uFogColor;
uniform float uDesaturationFactor;
uniform float uInterpolationFactor;

View file

@ -56,7 +56,7 @@ public:
virtual void Resize(size_t newsize) = 0;
virtual void Map() {} // Only needed by old OpenGL but this needs to be in the interface.
virtual void Unmap() {}
void *Memory() { assert(map); return map; }
void *Memory() { return map; }
size_t Size() { return buffersize; }
};

View file

@ -63,9 +63,9 @@ FFlatVertexBuffer::FFlatVertexBuffer(int width, int height)
// and this is for the postprocessing copy operation
vbo_shadowdata[8].Set(-1.0f, -1.0f, 0, 0.0f, 0.0f);
vbo_shadowdata[9].Set(-1.0f, 1.0f, 0, 0.0f, 1.f);
vbo_shadowdata[10].Set(1.0f, -1.0f, 0, 1.f, 0.0f);
vbo_shadowdata[11].Set(1.0f, 1.0f, 0, 1.f, 1.f);
vbo_shadowdata[9].Set(3.0f, -1.0f, 0, 2.f, 0.0f);
vbo_shadowdata[10].Set(-1.0f, 3.0f, 0, 0.0f, 2.f);
vbo_shadowdata[11].Set(3.0f, 3.0f, 0, 2.f, 2.f); // Note: not used anymore
// The next two are the stencil caps.
vbo_shadowdata[12].Set(-32767.0f, 32767.0f, -32767.0f, 0, 0);

View file

@ -166,7 +166,7 @@ void CheckBench()
FString compose;
if (sysCallbacks && sysCallbacks->GetLocationDescription) compose = sysCallbacks->GetLocationDescription();
if (sysCallbacks.GetLocationDescription) compose = sysCallbacks.GetLocationDescription();
AppendRenderStats(compose);
AppendRenderTimes(compose);

View file

@ -4,6 +4,7 @@
#include "matrix.h"
#include "hw_material.h"
#include "texmanip.h"
#include "version.h"
struct FColormap;
class IVertexBuffer;
@ -290,7 +291,7 @@ public:
mStreamData.uGradientBottomPlane = { 0.0f, 0.0f, 0.0f, 0.0f };
mStreamData.uSplitTopPlane = { 0.0f, 0.0f, 0.0f, 0.0f };
mStreamData.uSplitBottomPlane = { 0.0f, 0.0f, 0.0f, 0.0f };
mStreamData.uDynLightColor = { 0.0f, 0.0f, 0.0f, 0.0f };
mStreamData.uDynLightColor = { 0.0f, 0.0f, 0.0f, 1.0f };
mStreamData.uDetailParms = { 0.0f, 0.0f, 0.0f, 0.0f };
#ifdef NPOT_EMULATION
mStreamData.uNpotEmulation = { 0,0 };
@ -459,7 +460,15 @@ public:
void SetDynLight(float r, float g, float b)
{
mStreamData.uDynLightColor = { r, g, b, 0.0f };
mStreamData.uDynLightColor.X = r;
mStreamData.uDynLightColor.Y = g;
mStreamData.uDynLightColor.Z = b;
}
void SetScreenFade(float f)
{
// This component is otherwise unused.
mStreamData.uDynLightColor.W = f;
}
void SetObjectColor(PalEntry pe)
@ -569,7 +578,7 @@ public:
mMaterial.mChanged = true;
mTextureModeFlags = mat->GetLayerFlags();
auto scale = mat->GetDetailScale();
mStreamData.uDetailParms = { scale.X, scale.Y, 0, 0 };
mStreamData.uDetailParms = { scale.X, scale.Y, 2, 0 };
}
void SetMaterial(FGameTexture* tex, EUpscaleFlags upscalemask, int scaleflags, int clampmode, int translation, int overrideshader)

View file

@ -277,7 +277,7 @@ const FDefaultShader defaultshaders[] =
{"Warp 2", "shaders/glsl/func_warp2.fp", "shaders/glsl/material_normal.fp", ""},
{"Specular", "shaders/glsl/func_spec.fp", "shaders/glsl/material_specular.fp", "#define SPECULAR\n#define NORMALMAP\n"},
{"PBR","shaders/glsl/func_pbr.fp", "shaders/glsl/material_pbr.fp", "#define PBR\n#define NORMALMAP\n"},
{"Paletted", "shaders/glsl/func_paletted.fp", "shaders/glsl/material_nolight.fp", ""},
{"Paletted", "shaders/glsl/func_paletted.fp", "shaders/glsl/material_nolight.fp", "#define PALETTE_EMULATION\n"},
{"No Texture", "shaders/glsl/func_notexture.fp", "shaders/glsl/material_normal.fp", "#define NO_LAYERS\n"},
{"Basic Fuzz", "shaders/glsl/fuzz_standard.fp", "shaders/glsl/material_normal.fp", ""},
{"Smooth Fuzz", "shaders/glsl/fuzz_smooth.fp", "shaders/glsl/material_normal.fp", ""},

Some files were not shown because too many files have changed in this diff Show more