- use GZDoom's 2D drawer.

Console and menu font colors are not ok yet, aside from that it works.
This commit is contained in:
Christoph Oelckers 2020-05-25 17:11:32 +02:00
parent 2f672da7ba
commit 55a3c62b59
58 changed files with 2738 additions and 1719 deletions

View file

@ -622,6 +622,7 @@ file( GLOB HEADER_FILES
common/audio/sound/thirdparty/*.h
common/audio/sound/*.h
common/audio/music/*.h*
common/2d/*.h
common/console/*.h
common/utility/*.h
common/engine/*.h
@ -751,9 +752,6 @@ set (PCH_SOURCES
core/raze_music.cpp
core/raze_sound.cpp
core/2d/v_2ddrawer.cpp
core/2d/v_draw.cpp
core/2d/v_drawtext.cpp
core/2d/screentext.cpp
core/console/c_console.cpp
@ -768,6 +766,9 @@ set (PCH_SOURCES
common/audio/music/i_music.cpp
common/audio/music/i_soundfont.cpp
common/audio/music/music_config.cpp
common/2d/v_2ddrawer.cpp
common/2d/v_drawtext.cpp
common/2d/v_draw.cpp
common/thirdparty/sfmt/SFMT.cpp
common/fonts/singlelumpfont.cpp
common/fonts/singlepicfont.cpp
@ -775,9 +776,10 @@ set (PCH_SOURCES
common/fonts/font.cpp
common/fonts/hexfont.cpp
common/fonts/v_font.cpp
common/fonts/v_text.cpp
common/textures/hw_ihwtexture.cpp
common/textures/hw_material.cpp
common/fonts/v_text.cpp
common/textures/bitmap.cpp
common/textures/m_png.cpp
common/textures/texture.cpp
@ -1011,6 +1013,7 @@ include_directories(
platform
common/audio/sound
common/audio/music
common/2d
common/thirdparty
common/textures
common/textures/formats
@ -1139,6 +1142,7 @@ source_group("Common\\Audio\\Music" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_
source_group("Common\\Console" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/console/.+")
source_group("Common\\Utility" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/utility/.+")
source_group("Common\\Engine" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/engine/.+")
source_group("Common\\2D" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/2d/.+")
source_group("Common\\Objects" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/objects/.+")
source_group("Common\\Fonts" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/fonts/.+")
source_group("Common\\File System" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/filesystem/.+")

View file

@ -59,7 +59,7 @@ void _consoleSysMsg(const char* pzFormat, ...) {
va_start(args, pzFormat);
vsprintf(buffer, pzFormat, args);
Printf(OSDTEXT_RED "%s(%i): %s\n", _module, _line, buffer);
Printf(TEXTCOLOR_RED "%s(%i): %s\n", _module, _line, buffer);
}
END_BLD_NS

View file

@ -60,7 +60,7 @@ static int osdcmd_map(CCmdFuncPtr parm)
if (!fileSystem.Lookup(filename, "MAP"))
{
Printf(OSD_ERROR "map: file \"%s\" not found.\n", filename);
Printf(TEXTCOLOR_RED "map: file \"%s\" not found.\n", filename);
return OSDCMD_OK;
}
@ -237,7 +237,7 @@ static int osdcmd_levelwarp(CCmdFuncPtr parm)
int m = atoi(parm->parms[1]);
if (e == 0 || m == 0)
{
Printf(OSD_ERROR "Invalid level!: E%sM%s\n", parm->parms[0], parm->parms[1]);
Printf(TEXTCOLOR_RED "Invalid level!: E%sM%s\n", parm->parms[0], parm->parms[1]);
return OSDCMD_OK;
}
LevelWarp(e - 1, m - 1);

View file

@ -1296,4 +1296,35 @@ extern int32_t(*loadboard_replace)(const char *filename, char flags, vec3_t *dap
extern void(*PolymostProcessVoxels_Callback)(void);
#endif
class F2DDrawer;
extern F2DDrawer twodgen;
extern F2DDrawer twodpsp;
extern F2DDrawer* twod;
// This is for safely substituting the 2D drawer for a block of code.
class PspTwoDSetter
{
F2DDrawer* old;
public:
PspTwoDSetter()
{
old = twod;
twod = &twodpsp;
}
~PspTwoDSetter()
{
twod = old;
}
// Shadow Warrior fucked this up and draws the weapons in the same pass as the hud, meaning we have to switch this on and off depending on context.
void set()
{
twod = &twodpsp;
}
void clear()
{
twod = old;
}
};
#endif // build_h_

View file

@ -13,6 +13,7 @@
#include "textures.h"
#include "bitmap.h"
#include "v_draw.h"
#include "v_video.h"
#undef UNUSED
#define VPX_CODEC_DISABLE_COMPAT 1

View file

@ -27,6 +27,7 @@
#include "stats.h"
#include "menu.h"
#include "version.h"
#include "earcut.hpp"
#ifdef USE_OPENGL
# include "hightile.h"
@ -2863,6 +2864,323 @@ killsprite:
}
//==========================================================================
//
//
//
//==========================================================================
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)
{
//Convert int32_t to float (in-place)
TArray<FVector4> points(npoints, true);
using Point = std::pair<float, float>;
std::vector<std::vector<Point>> polygon;
std::vector<Point>* curPoly;
polygon.resize(1);
curPoly = &polygon.back();
for (bssize_t i = 0; i < npoints; ++i)
{
auto X = ((float)rx1[i]) * (1.0f / 4096.f);
auto Y = ((float)ry1[i]) * (1.0f / 4096.f);
curPoly->push_back(std::make_pair(X, Y));
if (xb1[i] < i && i < npoints - 1)
{
polygon.resize(polygon.size() + 1);
curPoly = &polygon.back();
}
}
// Now make sure that the outer boundary is the first polygon by picking a point that's as much to the outside as possible.
int outer = 0;
float minx = FLT_MAX;
float miny = FLT_MAX;
for (size_t a = 0; a < polygon.size(); a++)
{
for (auto& pt : polygon[a])
{
if (pt.first < minx || (pt.first == minx && pt.second < miny))
{
minx = pt.first;
miny = pt.second;
outer = a;
}
}
}
if (outer != 0) std::swap(polygon[0], polygon[outer]);
auto indices = mapbox::earcut(polygon);
int p = 0;
for (size_t a = 0; a < polygon.size(); a++)
{
for (auto& pt : polygon[a])
{
FVector4 point = { pt.first, pt.second, float(pt.first * xtex.X + pt.second * ytex.X + otex.X), float(pt.first * xtex.Y + pt.second * ytex.Y + otex.Y) };
points[p++] = point;
}
}
int maskprops = (props >> 7) & DAMETH_MASKPROPS;
FRenderStyle rs = LegacyRenderStyles[STYLE_Translucent];
double alpha = 1.;
if (maskprops > DAMETH_MASK)
{
rs = GetRenderStyle(0, maskprops == DAMETH_TRANS2);
alpha = GetAlphaFromBlend(maskprops, 0);
}
int translation = TRANSLATION(Translation_Remap + curbasepal, palette);
int light = clamp(scale((numshades - shade), 255, numshades), 0, 255);
PalEntry pe = PalEntry(uint8_t(alpha*255), light, light, light);
twod->AddPoly(tileGetTexture(picnum), points.Data(), points.Size(), indices.data(), indices.size(), translation, pe, rs, clipx1, clipy1, clipx2, clipy2);
}
void drawlinergb(int32_t x1, int32_t y1, int32_t x2, int32_t y2, PalEntry p)
{
twod->AddLine(x1 / 4096.f, y1 / 4096.f, x2 / 4096.f, y2 / 4096.f, windowxy1.x, windowxy1.y, windowxy2.x, windowxy2.y, p);
}
void drawlinergb(int32_t x1, int32_t y1, int32_t x2, int32_t y2, palette_t p)
{
drawlinergb(x1, y1, x2, y2, PalEntry(p.r, p.g, p.b));
}
void renderDrawLine(int32_t x1, int32_t y1, int32_t x2, int32_t y2, uint8_t col)
{
drawlinergb(x1, y1, x2, y2, GPalette.BaseColors[GPalette.Remap[col]]);
}
//==========================================================================
//
//
//
//==========================================================================
#include "build.h"
#include "../src/engine_priv.h"
//sx,sy center of sprite; screen coords*65536
//z zoom*65536. > is zoomed in
//a angle (0 is default)
//dastat&1 1:translucence
//dastat&2 1:auto-scale mode (use 320*200 coordinates)
//dastat&4 1:y-flip
//dastat&8 1:don't clip to startumost/startdmost
//dastat&16 1:force point passed to be top-left corner, 0:Editart center
//dastat&32 1:reverse translucence
//dastat&64 1:non-masked, 0:masked
//dastat&128 1:draw all pages (permanent - no longer used)
//cx1,... clip window (actual screen coords)
//==========================================================================
//
// INTERNAL helper function for classic/polymost dorotatesprite
// sxptr, sxptr, z: in/out
// ret_yxaspect, ret_xyaspect: out
//
//==========================================================================
static int32_t dorotspr_handle_bit2(int32_t* sxptr, int32_t* syptr, int32_t* z, int32_t dastat, int32_t cx1_plus_cx2, int32_t cy1_plus_cy2)
{
if ((dastat & RS_AUTO) == 0)
{
if (!(dastat & RS_STRETCH) && 4 * ydim <= 3 * xdim)
{
return (10 << 16) / 12;
}
else
{
return xyaspect;
}
}
else
{
// dastat&2: Auto window size scaling
const int32_t oxdim = xdim;
const int32_t oydim = ydim;
int32_t xdim = oxdim; // SHADOWS global
int32_t ydim = oydim;
int32_t zoomsc, sx = *sxptr, sy = *syptr;
int32_t ouryxaspect = yxaspect, ourxyaspect = xyaspect;
sy += rotatesprite_y_offset;
if (!(dastat & RS_STRETCH) && 4 * ydim <= 3 * xdim)
{
if ((dastat & RS_ALIGN_MASK) && (dastat & RS_ALIGN_MASK) != RS_ALIGN_MASK)
sx += NEGATE_ON_CONDITION(scale(120 << 16, xdim, ydim) - (160 << 16), !(dastat & RS_ALIGN_R));
if ((dastat & RS_ALIGN_MASK) == RS_ALIGN_MASK)
ydim = scale(xdim, 3, 4);
else
xdim = scale(ydim, 4, 3);
ouryxaspect = (12 << 16) / 10;
ourxyaspect = (10 << 16) / 12;
}
ouryxaspect = mulscale16(ouryxaspect, rotatesprite_yxaspect);
ourxyaspect = divscale16(ourxyaspect, rotatesprite_yxaspect);
// screen center to s[xy], 320<<16 coords.
const int32_t normxofs = sx - (320 << 15), normyofs = sy - (200 << 15);
// nasty hacks go here
if (!(dastat & RS_NOCLIP))
{
const int32_t twice_midcx = cx1_plus_cx2 + 2;
// screen x center to sx1, scaled to viewport
const int32_t scaledxofs = scale(normxofs, scale(xdimen, xdim, oxdim), 320);
sx = ((twice_midcx) << 15) + scaledxofs;
zoomsc = xdimenscale; //= scale(xdimen,yxaspect,320);
zoomsc = mulscale16(zoomsc, rotatesprite_yxaspect);
if ((dastat & RS_ALIGN_MASK) == RS_ALIGN_MASK)
zoomsc = scale(zoomsc, ydim, oydim);
sy = ((cy1_plus_cy2 + 2) << 15) + mulscale16(normyofs, zoomsc);
}
else
{
//If not clipping to startmosts, & auto-scaling on, as a
//hard-coded bonus, scale to full screen instead
sx = (xdim << 15) + 32768 + scale(normxofs, xdim, 320);
zoomsc = scale(xdim, ouryxaspect, 320);
sy = (ydim << 15) + 32768 + mulscale16(normyofs, zoomsc);
if ((dastat & RS_ALIGN_MASK) == RS_ALIGN_MASK)
sy += (oydim - ydim) << 15;
else
sx += (oxdim - xdim) << 15;
if (dastat & RS_CENTERORIGIN)
sx += oxdim << 15;
}
*sxptr = sx;
*syptr = sy;
*z = mulscale16(*z, zoomsc);
return ourxyaspect;
}
}
//==========================================================================
//
//
//
//==========================================================================
void twod_rotatesprite(int32_t sx, int32_t sy, int32_t z, int16_t a, int16_t picnum,
int8_t dashade, uint8_t dapalnum, int32_t dastat, uint8_t daalpha, uint8_t dablend,
int32_t clipx1, int32_t clipy1, int32_t clipx2, int32_t clipy2, FTexture* pic, int basepal)
{
F2DDrawer::RenderCommand dg = {};
int method = 0;
dg.mTranslationId = TRANSLATION(Translation_Remap + basepal, dapalnum);
dg.mType = F2DDrawer::DrawTypeTriangles;
if (clipx1 > 0 || clipy1 > 0 || clipx2 < screen->GetWidth() - 1 || clipy2 < screen->GetHeight() - 1)
{
dg.mScissor[0] = clipx1;
dg.mScissor[1] = clipy1;
dg.mScissor[2] = clipx2 + 1;
dg.mScissor[3] = clipy2 + 1;
dg.mFlags |= F2DDrawer::DTF_Scissor;
}
if (!(dastat & RS_NOMASK))
{
if (dastat & RS_TRANS1)
method |= (dastat & RS_TRANS2) ? DAMETH_TRANS2 : DAMETH_TRANS1;
else
method |= DAMETH_MASK;
dg.mRenderStyle = GetRenderStyle(dablend, (dastat & RS_TRANS2) ? 1 : 0);
}
else
{
dg.mRenderStyle = LegacyRenderStyles[STYLE_Normal];
}
dg.mTexture = pic ? pic : tileGetTexture(picnum);
dg.mVertCount = 4;
dg.mVertIndex = (int)twod->mVertices.Reserve(4);
auto ptr = &twod->mVertices[dg.mVertIndex];
float drawpoly_alpha = daalpha * (1.0f / 255.0f);
float alpha = GetAlphaFromBlend(method, dablend) * (1.f - drawpoly_alpha); // Hmmm...
int light = clamp(scale((numshades - dashade), 255, numshades), 0, 255);
auto p = PalEntry((uint8_t)(alpha * 255), light, light, light);
vec2_t const siz = { dg.mTexture->GetDisplayWidth(), dg.mTexture->GetDisplayHeight() };
vec2_16_t ofs = { 0, 0 };
if (!(dastat & RS_TOPLEFT))
{
if (!pic)
{
ofs = { int16_t(tileLeftOffset(picnum) + (siz.x >> 1)),
int16_t(tileTopOffset(picnum) + (siz.y >> 1)) };
}
else
{
ofs = { int16_t((siz.x >> 1)),
int16_t((siz.y >> 1)) };
}
}
if (dastat & RS_YFLIP)
ofs.y = siz.y - ofs.y;
int32_t aspectcorrect = dorotspr_handle_bit2(&sx, &sy, &z, dastat, clipx1 + clipx2, clipy1 + clipy2);
int32_t cosang = mulscale14(sintable[(a + 512) & 2047], z);
int32_t cosang2 = cosang;
int32_t sinang = mulscale14(sintable[a & 2047], z);
int32_t sinang2 = sinang;
if ((dastat & RS_AUTO) || (!(dastat & RS_NOCLIP))) // Don't aspect unscaled perms
{
cosang2 = mulscale16(cosang2, aspectcorrect);
sinang2 = mulscale16(sinang2, aspectcorrect);
}
int cx0 = sx - ofs.x * cosang2 + ofs.y * sinang2;
int cy0 = sy - ofs.x * sinang - ofs.y * cosang;
int cx1 = cx0 + siz.x * cosang2;
int cy1 = cy0 + siz.x * sinang;
int cx3 = cx0 - siz.y * sinang2;
int cy3 = cy0 + siz.y * cosang;
int cx2 = cx1 + cx3 - cx0;
int cy2 = cy1 + cy3 - cy0;
float y = (dastat & RS_YFLIP) ? 1.f : 0.f;
ptr->Set(cx0 / 65536.f, cy0 / 65536.f, 0.f, 0.f, y, p); ptr++;
ptr->Set(cx1 / 65536.f, cy1 / 65536.f, 0.f, 1.f, y, p); ptr++;
ptr->Set(cx2 / 65536.f, cy2 / 65536.f, 0.f, 1.f, 1.f - y, p); ptr++;
ptr->Set(cx3 / 65536.f, cy3 / 65536.f, 0.f, 0.f, 1.f - y, p); ptr++;
dg.mIndexIndex = twod->mIndices.Size();
dg.mIndexCount += 6;
twod->AddIndices(dg.mVertIndex, 6, 0, 1, 2, 0, 2, 3);
twod->AddCommand(&dg);
}
//
// fillpolygon (internal)
//
@ -2882,7 +3200,7 @@ static void renderFillPolygon(int32_t npoints)
ytex.Y = ((float)y2) * (-1.f / 4294967296.f);
otex.X = (fxdim * xtex.X + fydim * ytex.X) * -0.5f + fglobalposx * (1.f / 4294967296.f);
otex.Y = (fxdim * xtex.Y + fydim * ytex.Y) * -0.5f - fglobalposy * (1.f / 4294967296.f);
twod->FillPolygon(rx1, ry1, xb1, npoints, globalpicnum, globalpal, globalshade, globalorientation, xtex, ytex, otex, windowxy1.x, windowxy1.y, windowxy2.x, windowxy2.y);
FillPolygon(rx1, ry1, xb1, npoints, globalpicnum, globalpal, globalshade, globalorientation, xtex, ytex, otex, windowxy1.x, windowxy1.y, windowxy2.x, windowxy2.y);
}
//
@ -3750,7 +4068,7 @@ void videoNextPage(void)
// Ideally this stuff should be moved out of videoNextPage so that all those busy loops won't call UI overlays at all.
recursion = true;
M_Drawer();
FStat::PrintStat();
FStat::PrintStat(twod);
C_DrawConsole();
recursion = false;
}
@ -5035,7 +5353,7 @@ void rotatesprite_(int32_t sx, int32_t sy, int32_t z, int16_t a, int16_t picnum,
}
// We must store all calls in the 2D drawer so that the backend can operate on a clean 3D view.
twod->rotatesprite(sx, sy, z, a, picnum, dashade, dapalnum, dastat, daalpha, dablend, cx1, cy1, cx2, cy2, tex, basepal);
twod_rotatesprite(sx, sy, z, a, picnum, dashade, dapalnum, dastat, daalpha, dablend, cx1, cy1, cx2, cy2, tex, basepal);
// RS_PERM code was removed because the current backend supports only one page that needs to be redrawn each frame in which case the perm list was skipped anyway.
}

View file

@ -1,49 +1,183 @@
// scissi
//---------------------------------------------------------------------------
//
// Copyright(C) 2016-2018 Christoph Oelckers
// All rights reserved.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see http://www.gnu.org/licenses/
//
//--------------------------------------------------------------------------
//
/*
** v_2ddrawer.h
** Device independent 2D draw list
**
**/
**---------------------------------------------------------------------------
** Copyright 2016-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 <stdarg.h>
#include "c_cvars.h"
#include "v_2ddrawer.h"
#include "renderstyle.h"
#include "drawparms.h"
#include "vectors.h"
#include "gamecvars.h"
#include "earcut.hpp"
#include "palettecontainer.h"
//#include "doomtype.h"
#include "templates.h"
//#include "r_utility.h"
#include "v_video.h"
//#include "g_levellocals.h"
//#include "vm.h"
#include "vm.h"
#include "c_cvars.h"
#include "v_draw.h"
#include "fcolormap.h"
F2DDrawer twodpsp;
F2DDrawer twodgen;
F2DDrawer *twod = &twodgen;
F2DDrawer* twod;
EXTERN_CVAR(Float, transsouls)
IMPLEMENT_CLASS(DShape2DTransform, false, false)
static void Shape2DTransform_Clear(DShape2DTransform* self)
{
self->transform.Identity();
}
DEFINE_ACTION_FUNCTION_NATIVE(DShape2DTransform, Clear, Shape2DTransform_Clear)
{
PARAM_SELF_PROLOGUE(DShape2DTransform);
Shape2DTransform_Clear(self);
return 0;
}
static void Shape2DTransform_Rotate(DShape2DTransform* self, double angle)
{
self->transform = DMatrix3x3::Rotate2D(DEG2RAD(angle)) * self->transform;
}
DEFINE_ACTION_FUNCTION_NATIVE(DShape2DTransform, Rotate, Shape2DTransform_Rotate)
{
PARAM_SELF_PROLOGUE(DShape2DTransform);
PARAM_FLOAT(angle);
Shape2DTransform_Rotate(self, angle);
return 0;
}
static void Shape2DTransform_Scale(DShape2DTransform* self, double x, double y)
{
self->transform = DMatrix3x3::Scale2D(DVector2(x, y)) * self->transform;
}
DEFINE_ACTION_FUNCTION_NATIVE(DShape2DTransform, Scale, Shape2DTransform_Scale)
{
PARAM_SELF_PROLOGUE(DShape2DTransform);
PARAM_FLOAT(x);
PARAM_FLOAT(y);
Shape2DTransform_Scale(self, x, y);
return 0;
}
static void Shape2DTransform_Translate(DShape2DTransform* self, double x, double y)
{
self->transform = DMatrix3x3::Translate2D(DVector2(x, y)) * self->transform;
}
DEFINE_ACTION_FUNCTION_NATIVE(DShape2DTransform, Translate, Shape2DTransform_Translate)
{
PARAM_SELF_PROLOGUE(DShape2DTransform);
PARAM_FLOAT(x);
PARAM_FLOAT(y);
Shape2DTransform_Translate(self, x, y);
return 0;
}
IMPLEMENT_CLASS(DShape2D, false, false)
static void Shape2D_SetTransform(DShape2D* self, DShape2DTransform *transform)
{
self->transform = transform->transform;
self->dirty = true;
}
DEFINE_ACTION_FUNCTION_NATIVE(DShape2D, SetTransform, Shape2D_SetTransform)
{
PARAM_SELF_PROLOGUE(DShape2D);
PARAM_OBJECT(transform, DShape2DTransform);
Shape2D_SetTransform(self, transform);
return 0;
}
static void Shape2D_Clear(DShape2D* self, int which)
{
if (which & C_Verts)
{
self->mVertices.Clear();
self->dirty = true;
}
if (which & C_Coords) self->mCoords.Clear();
if (which & C_Indices) self->mIndices.Clear();
}
DEFINE_ACTION_FUNCTION_NATIVE(DShape2D, Clear, Shape2D_Clear)
{
PARAM_SELF_PROLOGUE(DShape2D);
PARAM_INT(which);
Shape2D_Clear(self, which);
return 0;
}
static void Shape2D_PushVertex(DShape2D* self, double x, double y)
{
self->mVertices.Push(DVector2(x, y));
self->dirty = true;
}
DEFINE_ACTION_FUNCTION_NATIVE(DShape2D, PushVertex, Shape2D_PushVertex)
{
PARAM_SELF_PROLOGUE(DShape2D);
PARAM_FLOAT(x);
PARAM_FLOAT(y);
Shape2D_PushVertex(self, x, y);
return 0;
}
static void Shape2D_PushCoord(DShape2D* self, double u, double v)
{
self->mCoords.Push(DVector2(u, v));
}
DEFINE_ACTION_FUNCTION_NATIVE(DShape2D, PushCoord, Shape2D_PushCoord)
{
PARAM_SELF_PROLOGUE(DShape2D);
PARAM_FLOAT(u);
PARAM_FLOAT(v);
Shape2D_PushCoord(self, u, v);
return 0;
}
static void Shape2D_PushTriangle(DShape2D* self, int a, int b, int c)
{
self->mIndices.Push(a);
self->mIndices.Push(b);
self->mIndices.Push(c);
}
DEFINE_ACTION_FUNCTION_NATIVE(DShape2D, PushTriangle, Shape2D_PushTriangle)
{
PARAM_SELF_PROLOGUE(DShape2D);
PARAM_INT(a);
PARAM_INT(b);
PARAM_INT(c);
Shape2D_PushTriangle(self, a, b, c);
return 0;
}
//==========================================================================
//
@ -106,7 +240,11 @@ bool F2DDrawer::SetStyle(FTexture *tex, DrawParms &parms, PalEntry &vertexcolor,
float alpha;
bool stencilling;
if (style.Flags & STYLEF_Alpha1)
if (style.Flags & STYLEF_TransSoulsAlpha)
{
alpha = transsouls;
}
else if (style.Flags & STYLEF_Alpha1)
{
alpha = 1;
}
@ -192,6 +330,16 @@ bool F2DDrawer::SetStyle(FTexture *tex, DrawParms &parms, PalEntry &vertexcolor,
{
quad.mDrawMode = TM_INVERSE;
}
if (parms.specialcolormap != nullptr)
{ // draw with an invulnerability or similar colormap.
auto scm = parms.specialcolormap;
quad.mSpecialColormap[0] = PalEntry(255, int(scm->ColorizeStart[0] * 127.5f), int(scm->ColorizeStart[1] * 127.5f), int(scm->ColorizeStart[2] * 127.5f));
quad.mSpecialColormap[1] = PalEntry(255, int(scm->ColorizeEnd[0] * 127.5f), int(scm->ColorizeEnd[1] * 127.5f), int(scm->ColorizeEnd[2] * 127.5f));
quad.mColor1 = 0; // this disables the color overlay.
}
quad.mDesaturate = parms.desaturate;
}
// apply the element's own color. This is being blended with anything that came before.
@ -260,10 +408,15 @@ void F2DDrawer::AddTexture(FTexture *img, DrawParms &parms)
dg.mType = DrawTypeTriangles;
dg.mVertCount = 4;
dg.mTexture = img;
if (img->isWarped()) dg.mFlags |= DTF_Wrap;
dg.mRemapIndex = parms.TranslationId;
dg.mTranslationId = 0;
SetStyle(img, parms, vertexcolor, dg);
if (!img->isHardwareCanvas() && parms.TranslationId != -1)
{
dg.mTranslationId = parms.TranslationId;
}
u1 = parms.srcx;
v1 = parms.srcy;
u2 = parms.srcx + parms.srcwidth;
@ -319,6 +472,211 @@ void F2DDrawer::AddTexture(FTexture *img, DrawParms &parms)
//
//==========================================================================
void F2DDrawer::AddShape( FTexture *img, DShape2D *shape, DrawParms &parms )
{
// [MK] bail out if vertex/coord array sizes are mismatched
if ( shape->mVertices.Size() != shape->mCoords.Size() )
ThrowAbortException(X_OTHER, "Mismatch in vertex/coord count: %u != %u", shape->mVertices.Size(), shape->mCoords.Size());
if (parms.style.BlendOp == STYLEOP_None) return; // not supposed to be drawn.
PalEntry vertexcolor;
RenderCommand dg;
dg.mType = DrawTypeTriangles;
dg.mVertCount = shape->mVertices.Size();
dg.mFlags |= DTF_Wrap;
dg.mTexture = img;
dg.mTranslationId = 0;
SetStyle(img, parms, vertexcolor, dg);
if (!img->isHardwareCanvas() && parms.TranslationId != -1)
dg.mTranslationId = parms.TranslationId;
if (shape->dirty) {
if (shape->mVertices.Size() != shape->mTransformedVertices.Size())
shape->mTransformedVertices.Resize(shape->mVertices.Size());
for (int i = 0; i < dg.mVertCount; i++) {
shape->mTransformedVertices[i] = (shape->transform * DVector3(shape->mVertices[i], 1.0)).XY();
}
shape->dirty = false;
}
double minx = 16383, miny = 16383, maxx = -16384, maxy = -16384;
for ( int i=0; i<dg.mVertCount; i++ )
{
if ( shape->mTransformedVertices[i].X < minx ) minx = shape->mTransformedVertices[i].X;
if ( shape->mTransformedVertices[i].Y < miny ) miny = shape->mTransformedVertices[i].Y;
if ( shape->mTransformedVertices[i].X > maxx ) maxx = shape->mTransformedVertices[i].X;
if ( shape->mTransformedVertices[i].Y > maxy ) maxy = shape->mTransformedVertices[i].Y;
}
if (minx < (double)parms.lclip || miny < (double)parms.uclip || maxx >(double)parms.rclip || maxy >(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.mVertIndex = (int)mVertices.Reserve(dg.mVertCount);
TwoDVertex *ptr = &mVertices[dg.mVertIndex];
for ( int i=0; i<dg.mVertCount; i++ )
ptr[i].Set(shape->mTransformedVertices[i].X, shape->mTransformedVertices[i].Y, 0, shape->mCoords[i].X, shape->mCoords[i].Y, vertexcolor);
dg.mIndexIndex = mIndices.Size();
dg.mIndexCount += shape->mIndices.Size();
for ( int i=0; i<int(shape->mIndices.Size()); i+=3 )
{
// [MK] bail out if any indices are out of bounds
for ( int j=0; j<3; j++ )
{
if ( shape->mIndices[i+j] < 0 )
ThrowAbortException(X_ARRAY_OUT_OF_BOUNDS, "Triangle %u index %u is negative: %i\n", i/3, j, shape->mIndices[i+j]);
if ( shape->mIndices[i+j] >= dg.mVertCount )
ThrowAbortException(X_ARRAY_OUT_OF_BOUNDS, "Triangle %u index %u: %u, max: %u\n", i/3, j, shape->mIndices[i+j], dg.mVertCount-1);
}
AddIndices(dg.mVertIndex, 3, shape->mIndices[i], shape->mIndices[i+1], shape->mIndices[i+2]);
}
AddCommand(&dg);
}
//==========================================================================
//
//
//
//==========================================================================
void F2DDrawer::AddPoly(FTexture *texture, FVector2 *points, int npoints,
double originx, double originy, double scalex, double scaley,
DAngle rotation, const FColormap &colormap, PalEntry flatcolor, double fadelevel,
uint32_t *indices, size_t indexcount)
{
RenderCommand poly;
poly.mType = DrawTypeTriangles;
poly.mTexture = texture;
poly.mRenderStyle = DefaultRenderStyle();
poly.mFlags |= DTF_Wrap;
poly.mDesaturate = colormap.Desaturation;
PalEntry color0;
double invfade = 1. - fadelevel;
color0.r = uint8_t(colormap.LightColor.r * invfade);
color0.g = uint8_t(colormap.LightColor.g * invfade);
color0.b = uint8_t(colormap.LightColor.b * invfade);
color0.a = 255;
poly.mColor1.a = 0;
poly.mColor1.r = uint8_t(colormap.FadeColor.r * fadelevel);
poly.mColor1.g = uint8_t(colormap.FadeColor.g * fadelevel);
poly.mColor1.b = uint8_t(colormap.FadeColor.b * fadelevel);
bool dorotate = rotation != 0;
float cosrot = (float)cos(rotation.Radians());
float sinrot = (float)sin(rotation.Radians());
float uscale = float(1.f / (texture->GetDisplayWidth() * scalex));
float vscale = float(1.f / (texture->GetDisplayHeight() * scaley));
float ox = float(originx);
float oy = float(originy);
poly.mVertCount = npoints;
poly.mVertIndex = (int)mVertices.Reserve(npoints);
for (int i = 0; i < npoints; ++i)
{
float u = points[i].X - 0.5f - ox;
float v = points[i].Y - 0.5f - oy;
if (dorotate)
{
float t = u;
u = t * cosrot - v * sinrot;
v = v * cosrot + t * sinrot;
}
mVertices[poly.mVertIndex+i].Set(points[i].X, points[i].Y, 0, u*uscale, v*vscale, color0);
}
poly.mIndexIndex = mIndices.Size();
if (indices == nullptr || indexcount == 0)
{
poly.mIndexCount += (npoints - 2) * 3;
for (int i = 2; i < npoints; ++i)
{
AddIndices(poly.mVertIndex, 3, 0, i - 1, i);
}
}
else
{
poly.mIndexCount += (int)indexcount;
int addr = mIndices.Reserve(indexcount);
for (size_t i = 0; i < indexcount; i++)
{
mIndices[addr + i] = poly.mVertIndex + indices[i];
}
}
AddCommand(&poly);
}
//==========================================================================
//
//
//
//==========================================================================
void F2DDrawer::AddPoly(FTexture* 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)
{
RenderCommand dg = {};
int method = 0;
dg.mType = DrawTypeTriangles;
if (clipx1 > 0 || clipy1 > 0 || clipx2 < GetWidth() - 1 || clipy2 < GetHeight() - 1)
{
dg.mScissor[0] = clipx1;
dg.mScissor[1] = clipy1;
dg.mScissor[2] = clipx2 + 1;
dg.mScissor[3] = clipy2 + 1;
dg.mFlags |= DTF_Scissor;
}
dg.mTexture = img;
dg.mTranslationId = translation;
dg.mColor1 = color;
dg.mVertCount = (int)vtcount;
dg.mVertIndex = (int)mVertices.Reserve(vtcount);
dg.mRenderStyle = LegacyRenderStyles[STYLE_Translucent];
dg.mIndexIndex = mIndices.Size();
dg.mFlags |= DTF_Wrap;
auto ptr = &mVertices[dg.mVertIndex];
for (size_t i=0;i<vtcount;i++)
{
ptr->Set(vt[i].X, vt[i].Y, 0.f, vt[i].Z, vt[i].W, color);
ptr++;
}
dg.mIndexIndex = mIndices.Size();
mIndices.Reserve(idxcount);
for (size_t i = 0; i < idxcount; i++)
{
mIndices[dg.mIndexIndex + i] = ind[i] + dg.mVertIndex;
}
dg.mIndexCount = (int)idxcount;
AddCommand(&dg);
}
//==========================================================================
//
//
//
//==========================================================================
void F2DDrawer::AddFlatFill(int left, int top, int right, int bottom, FTexture *src, bool local_origin)
{
float fU1, fU2, fV1, fV2;
@ -388,7 +746,7 @@ void F2DDrawer::AddColorOnlyQuad(int x1, int y1, int w, int h, PalEntry color, F
void F2DDrawer::ClearScreen(PalEntry color)
{
AddColorOnlyQuad(0, 0, screen->GetWidth(), screen->GetHeight(), color);
AddColorOnlyQuad(0, 0, GetWidth(), GetHeight(), color);
}
//==========================================================================
@ -404,7 +762,7 @@ void F2DDrawer::AddLine(float x1, float y1, float x2, float y2, int clipx1, int
RenderCommand dg;
if (clipx1 > 0 || clipy1 > 0 || clipx2 < screen->GetWidth()- 1 || clipy2 < screen->GetHeight() - 1)
if (clipx1 > 0 || clipy1 > 0 || clipx2 < GetWidth()- 1 || clipy2 < GetHeight() - 1)
{
dg.mScissor[0] = clipx1;
dg.mScissor[1] = clipy1;
@ -497,360 +855,3 @@ void F2DDrawer::Clear()
mData.Clear();
mIsFirstPass = true;
}
//==========================================================================
//
//
//
//==========================================================================
#include "build.h"
#include "../src/engine_priv.h"
//sx,sy center of sprite; screen coords*65536
//z zoom*65536. > is zoomed in
//a angle (0 is default)
//dastat&1 1:translucence
//dastat&2 1:auto-scale mode (use 320*200 coordinates)
//dastat&4 1:y-flip
//dastat&8 1:don't clip to startumost/startdmost
//dastat&16 1:force point passed to be top-left corner, 0:Editart center
//dastat&32 1:reverse translucence
//dastat&64 1:non-masked, 0:masked
//dastat&128 1:draw all pages (permanent - no longer used)
//cx1,... clip window (actual screen coords)
//==========================================================================
//
// INTERNAL helper function for classic/polymost dorotatesprite
// sxptr, sxptr, z: in/out
// ret_yxaspect, ret_xyaspect: out
//
//==========================================================================
static int32_t dorotspr_handle_bit2(int32_t* sxptr, int32_t* syptr, int32_t* z, int32_t dastat, int32_t cx1_plus_cx2, int32_t cy1_plus_cy2)
{
if ((dastat & RS_AUTO) == 0)
{
if (!(dastat & RS_STRETCH) && 4 * ydim <= 3 * xdim)
{
return (10 << 16) / 12;
}
else
{
return xyaspect;
}
}
else
{
// dastat&2: Auto window size scaling
const int32_t oxdim = xdim;
const int32_t oydim = ydim;
int32_t xdim = oxdim; // SHADOWS global
int32_t ydim = oydim;
int32_t zoomsc, sx = *sxptr, sy = *syptr;
int32_t ouryxaspect = yxaspect, ourxyaspect = xyaspect;
sy += rotatesprite_y_offset;
if (!(dastat & RS_STRETCH) && 4 * ydim <= 3 * xdim)
{
if ((dastat & RS_ALIGN_MASK) && (dastat & RS_ALIGN_MASK) != RS_ALIGN_MASK)
sx += NEGATE_ON_CONDITION(scale(120 << 16, xdim, ydim) - (160 << 16), !(dastat & RS_ALIGN_R));
if ((dastat & RS_ALIGN_MASK) == RS_ALIGN_MASK)
ydim = scale(xdim, 3, 4);
else
xdim = scale(ydim, 4, 3);
ouryxaspect = (12 << 16) / 10;
ourxyaspect = (10 << 16) / 12;
}
ouryxaspect = mulscale16(ouryxaspect, rotatesprite_yxaspect);
ourxyaspect = divscale16(ourxyaspect, rotatesprite_yxaspect);
// screen center to s[xy], 320<<16 coords.
const int32_t normxofs = sx - (320 << 15), normyofs = sy - (200 << 15);
// nasty hacks go here
if (!(dastat & RS_NOCLIP))
{
const int32_t twice_midcx = cx1_plus_cx2 + 2;
// screen x center to sx1, scaled to viewport
const int32_t scaledxofs = scale(normxofs, scale(xdimen, xdim, oxdim), 320);
sx = ((twice_midcx) << 15) + scaledxofs;
zoomsc = xdimenscale; //= scale(xdimen,yxaspect,320);
zoomsc = mulscale16(zoomsc, rotatesprite_yxaspect);
if ((dastat & RS_ALIGN_MASK) == RS_ALIGN_MASK)
zoomsc = scale(zoomsc, ydim, oydim);
sy = ((cy1_plus_cy2 + 2) << 15) + mulscale16(normyofs, zoomsc);
}
else
{
//If not clipping to startmosts, & auto-scaling on, as a
//hard-coded bonus, scale to full screen instead
sx = (xdim << 15) + 32768 + scale(normxofs, xdim, 320);
zoomsc = scale(xdim, ouryxaspect, 320);
sy = (ydim << 15) + 32768 + mulscale16(normyofs, zoomsc);
if ((dastat & RS_ALIGN_MASK) == RS_ALIGN_MASK)
sy += (oydim - ydim) << 15;
else
sx += (oxdim - xdim) << 15;
if (dastat & RS_CENTERORIGIN)
sx += oxdim << 15;
}
*sxptr = sx;
*syptr = sy;
*z = mulscale16(*z, zoomsc);
return ourxyaspect;
}
}
//==========================================================================
//
//
//
//==========================================================================
void F2DDrawer::rotatesprite(int32_t sx, int32_t sy, int32_t z, int16_t a, int16_t picnum,
int8_t dashade, uint8_t dapalnum, int32_t dastat, uint8_t daalpha, uint8_t dablend,
int32_t clipx1, int32_t clipy1, int32_t clipx2, int32_t clipy2, FTexture *pic, int basepal)
{
RenderCommand dg = {};
int method = 0;
dg.mType = pic? DrawTypeTriangles : DrawTypeRotateSprite;
if (clipx1 > 0 || clipy1 > 0 || clipx2 < screen->GetWidth() - 1 || clipy2 < screen->GetHeight() - 1)
{
dg.mScissor[0] = clipx1;
dg.mScissor[1] = clipy1;
dg.mScissor[2] = clipx2 + 1;
dg.mScissor[3] = clipy2 + 1;
dg.mFlags |= DTF_Scissor;
}
if (!(dastat & RS_NOMASK))
{
if (dastat & RS_TRANS1)
method |= (dastat & RS_TRANS2) ? DAMETH_TRANS2 : DAMETH_TRANS1;
else
method |= DAMETH_MASK;
dg.mRenderStyle = GetRenderStyle(dablend, (dastat & RS_TRANS2) ? 1 : 0);
}
else
{
dg.mRenderStyle = LegacyRenderStyles[STYLE_Normal];
}
PalEntry p = 0xffffffff;
dg.mTexture = pic? pic : tileGetTexture(picnum);
dg.mRemapIndex = dapalnum | (basepal << 8) | (dashade << 16);
dg.mVertCount = 4;
dg.mVertIndex = (int)mVertices.Reserve(4);
auto ptr = &mVertices[dg.mVertIndex];
float drawpoly_alpha = daalpha * (1.0f / 255.0f);
float alpha = GetAlphaFromBlend(method, dablend) * (1.f - drawpoly_alpha); // Hmmm...
p.a = (uint8_t)(alpha * 255);
vec2_t const siz = { dg.mTexture->GetDisplayWidth(), dg.mTexture->GetDisplayHeight() };
vec2_16_t ofs = { 0, 0 };
if (!(dastat & RS_TOPLEFT))
{
if (!pic)
{
ofs = { int16_t(tileLeftOffset(picnum) + (siz.x >> 1)),
int16_t(tileTopOffset(picnum) + (siz.y >> 1)) };
}
else
{
ofs = { int16_t((siz.x >> 1)),
int16_t((siz.y >> 1)) };
}
}
if (dastat & RS_YFLIP)
ofs.y = siz.y - ofs.y;
int32_t aspectcorrect = dorotspr_handle_bit2(&sx, &sy, &z, dastat, clipx1 + clipx2, clipy1 + clipy2);
int32_t cosang = mulscale14(sintable[(a + 512) & 2047], z);
int32_t cosang2 = cosang;
int32_t sinang = mulscale14(sintable[a & 2047], z);
int32_t sinang2 = sinang;
if ((dastat & RS_AUTO) || (!(dastat & RS_NOCLIP))) // Don't aspect unscaled perms
{
cosang2 = mulscale16(cosang2, aspectcorrect);
sinang2 = mulscale16(sinang2, aspectcorrect);
}
int cx0 = sx - ofs.x * cosang2 + ofs.y * sinang2;
int cy0 = sy - ofs.x * sinang - ofs.y * cosang;
int cx1 = cx0 + siz.x * cosang2;
int cy1 = cy0 + siz.x * sinang;
int cx3 = cx0 - siz.y * sinang2;
int cy3 = cy0 + siz.y * cosang;
int cx2 = cx1 + cx3 - cx0;
int cy2 = cy1 + cy3 - cy0;
float y = (dastat & RS_YFLIP) ? 1.f : 0.f;
ptr->Set(cx0 / 65536.f, cy0 / 65536.f, 0.f, 0.f, y, p); ptr++;
ptr->Set(cx1 / 65536.f, cy1 / 65536.f, 0.f, 1.f, y, p); ptr++;
ptr->Set(cx2 / 65536.f, cy2 / 65536.f, 0.f, 1.f, 1.f-y, p); ptr++;
ptr->Set(cx3 / 65536.f, cy3 / 65536.f, 0.f, 0.f, 1.f-y, p); ptr++;
dg.mIndexIndex = mIndices.Size();
dg.mIndexCount += 6;
AddIndices(dg.mVertIndex, 6, 0, 1, 2, 0, 2, 3);
AddCommand(&dg);
}
//==========================================================================
//
//
//
//==========================================================================
void F2DDrawer::AddPoly(FTexture* img, FVector4* vt, size_t vtcount, unsigned int* ind, size_t idxcount, int palette, int shade, int maskprops, int clipx1, int clipy1, int clipx2, int clipy2)
{
RenderCommand dg = {};
int method = 0;
dg.mType = DrawTypeRotateSprite;
if (clipx1 > 0 || clipy1 > 0 || clipx2 < screen->GetWidth() - 1 || clipy2 < screen->GetHeight() - 1)
{
dg.mScissor[0] = clipx1;
dg.mScissor[1] = clipy1;
dg.mScissor[2] = clipx2 + 1;
dg.mScissor[3] = clipy2 + 1;
dg.mFlags |= DTF_Scissor;
}
PalEntry p = 0xffffffff;
if (maskprops > DAMETH_MASK)
{
dg.mRenderStyle = GetRenderStyle(0, maskprops == DAMETH_TRANS2);
p.a = (uint8_t)(GetAlphaFromBlend(maskprops, 0) * 255);
}
dg.mTexture = img;
dg.mRemapIndex = palette | (shade << 16);
dg.mVertCount = vtcount;
dg.mVertIndex = (int)mVertices.Reserve(vtcount);
dg.mRenderStyle = LegacyRenderStyles[STYLE_Translucent];
dg.mIndexIndex = mIndices.Size();
dg.mFlags |= DTF_Wrap;
auto ptr = &mVertices[dg.mVertIndex];
for (size_t i=0;i<vtcount;i++)
{
ptr->Set(vt[i].X, vt[i].Y, 0.f, vt[i].Z, vt[i].W, p);
ptr++;
}
dg.mIndexIndex = mIndices.Size();
mIndices.Reserve(idxcount);
for (size_t i = 0; i < idxcount; i++)
{
mIndices[dg.mIndexIndex + i] = ind[i] + dg.mVertIndex;
}
dg.mIndexCount = idxcount;
AddCommand(&dg);
}
//==========================================================================
//
//
//
//==========================================================================
void F2DDrawer::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)
{
//Convert int32_t to float (in-place)
TArray<FVector4> points(npoints, true);
using Point = std::pair<float, float>;
std::vector<std::vector<Point>> polygon;
std::vector<Point>* curPoly;
polygon.resize(1);
curPoly = &polygon.back();
for (bssize_t i = 0; i < npoints; ++i)
{
auto X = ((float)rx1[i]) * (1.0f / 4096.f);
auto Y = ((float)ry1[i]) * (1.0f / 4096.f);
curPoly->push_back(std::make_pair(X, Y));
if (xb1[i] < i && i < npoints - 1)
{
polygon.resize(polygon.size() + 1);
curPoly = &polygon.back();
}
}
// Now make sure that the outer boundary is the first polygon by picking a point that's as much to the outside as possible.
int outer = 0;
float minx = FLT_MAX;
float miny = FLT_MAX;
for (size_t a = 0; a < polygon.size(); a++)
{
for (auto& pt : polygon[a])
{
if (pt.first < minx || (pt.first == minx && pt.second < miny))
{
minx = pt.first;
miny = pt.second;
outer = a;
}
}
}
if (outer != 0) std::swap(polygon[0], polygon[outer]);
auto indices = mapbox::earcut(polygon);
int p = 0;
for (size_t a = 0; a < polygon.size(); a++)
{
for (auto& pt : polygon[a])
{
FVector4 point = { pt.first, pt.second, float(pt.first * xtex.X + pt.second * ytex.X + otex.X), float(pt.first * xtex.Y + pt.second * ytex.Y + otex.Y) };
points[p++] = point;
}
}
AddPoly(tileGetTexture(picnum), points.Data(), points.Size(), indices.data(), indices.size(), palette, shade, (props >> 7)& DAMETH_MASKPROPS, clipx1, clipy1, clipx2, clipy2);
}
void drawlinergb(int32_t x1, int32_t y1, int32_t x2, int32_t y2, PalEntry p)
{
twod->AddLine(x1 / 4096.f, y1 / 4096.f, x2 / 4096.f, y2 / 4096.f, windowxy1.x, windowxy1.y, windowxy2.x, windowxy2.y, p);
}
void drawlinergb(int32_t x1, int32_t y1, int32_t x2, int32_t y2, palette_t p)
{
drawlinergb(x1, y1, x2, y2, PalEntry(p.r, p.g, p.b));
}
void renderDrawLine(int32_t x1, int32_t y1, int32_t x2, int32_t y2, uint8_t col)
{
drawlinergb(x1, y1, x2, y2, GPalette.BaseColors[GPalette.Remap[col]]);
}

View file

@ -5,10 +5,53 @@
#include "vectors.h"
#include "textures.h"
#include "renderstyle.h"
#include "dobject.h"
struct DrawParms;
class FFont;
struct FColormap;
class DShape2DTransform : public DObject
{
DECLARE_CLASS(DShape2DTransform, DObject)
public:
DShape2DTransform()
{
transform.Identity();
}
DMatrix3x3 transform;
};
// intermediate struct for shape drawing
enum EClearWhich
{
C_Verts = 1,
C_Coords = 2,
C_Indices = 4,
};
class DShape2D : public DObject
{
DECLARE_CLASS(DShape2D,DObject)
public:
DShape2D()
{
transform.Identity();
}
TArray<int> mIndices;
TArray<DVector2> mVertices;
TArray<DVector2> mCoords;
DMatrix3x3 transform;
// dirty stores whether we need to re-apply the transformation
// otherwise it uses the cached values
bool dirty = true;
TArray<DVector2> mTransformedVertices;
};
struct F2DPolygons
{
@ -24,8 +67,6 @@ struct F2DPolygons
};
class F2DDrawer
{
public:
@ -84,7 +125,7 @@ public:
int mIndexCount;
FTexture *mTexture;
int mRemapIndex;
int mTranslationId;
PalEntry mSpecialColormap[2];
int mScissor[4];
int mDesaturate;
@ -103,7 +144,7 @@ public:
{
return mTexture == other.mTexture &&
mType == other.mType &&
mRemapIndex == other.mRemapIndex &&
mTranslationId == other.mTranslationId &&
mSpecialColormap[0].d == other.mSpecialColormap[0].d &&
mSpecialColormap[1].d == other.mSpecialColormap[1].d &&
!memcmp(mScissor, other.mScissor, sizeof(mScissor)) &&
@ -119,70 +160,54 @@ public:
TArray<int> mIndices;
TArray<TwoDVertex> mVertices;
TArray<RenderCommand> mData;
int Width, Height;
bool isIn2D;
public:
int fullscreenautoaspect = 0;
int cliptop = -1, clipleft = -1, clipwidth = -1, clipheight = -1;
int AddCommand(const RenderCommand *data);
void AddIndices(int firstvert, int count, ...);
private:
void AddIndices(int firstvert, TArray<int> &v);
bool SetStyle(FTexture *tex, DrawParms &parms, PalEntry &color0, RenderCommand &quad);
void SetColorOverlay(PalEntry color, float alpha, PalEntry &vertexcolor, PalEntry &overlaycolor);
public:
void AddTexture(FTexture *img, DrawParms &parms);
void AddPoly(FTexture* img, FVector4 *vt, size_t vtcount, unsigned int *ind, size_t idxcount, int palette, int shade, int maskprops, int clipx1, int clipy1, int clipx2, int clipy2);
void AddShape(FTexture *img, DShape2D *shape, DrawParms &parms);
void AddPoly(FTexture *texture, FVector2 *points, int npoints,
double originx, double originy, double scalex, double scaley,
DAngle rotation, const FColormap &colormap, PalEntry flatcolor, double lightlevel, uint32_t *indices, size_t indexcount);
void AddPoly(FTexture* 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, FTexture *src, bool local_origin);
void AddFlatFill(int left, int top, int right, int bottom, FTexture *src, bool local_origin = false);
void AddColorOnlyQuad(int left, int top, int width, int height, PalEntry color, FRenderStyle *style = nullptr);
void ClearScreen(PalEntry color = 0xff000000);
void AddDim(PalEntry color, float damount, int x1, int y1, int w, int h);
void AddClear(int left, int top, int right, int bottom, int palcolor, uint32_t color);
void AddLine(float x1, float y1, float x2, float y2, uint32_t color, uint8_t alpha = 255);
void AddLine(float x1, float y1, float x2, float y2, int cx, int cy, int cx2, int cy2, uint32_t color, uint8_t alpha = 255);
void AddThickLine(int x1, int y1, int x2, int y2, double thickness, uint32_t color, uint8_t alpha = 255);
void AddPixel(int x1, int y1, uint32_t color);
void rotatesprite(int32_t sx, int32_t sy, int32_t z, int16_t a, int16_t picnum,
int8_t dashade, uint8_t dapalnum, int32_t dastat, uint8_t daalpha, uint8_t dablend,
int32_t cx1, int32_t cy1, int32_t cx2, int32_t cy2, FTexture *pic = nullptr, int basepal = 0);
void Clear();
int GetWidth() const { return Width; }
int GetHeight() const { return Height; }
void SetSize(int w, int h) { Width = w; Height = h; }
void Begin() { isIn2D = true; }
void End() { isIn2D = false; }
bool HasBegun2D() { return isIn2D; }
void ClearClipRect() { clipleft = cliptop = 0; clipwidth = clipheight = -1; }
void SetClipRect(int x, int y, int w, int h);
void GetClipRect(int* x, int* y, int* w, int* h);
bool mIsFirstPass = true;
};
extern F2DDrawer twodgen;
extern F2DDrawer twodpsp;
extern F2DDrawer* twod;
// This is for safely substituting the 2D drawer for a block of code.
class PspTwoDSetter
{
F2DDrawer* old;
public:
PspTwoDSetter()
{
old = twod;
twod = &twodpsp;
}
~PspTwoDSetter()
{
twod = old;
}
// Shadow Warrior fucked this up and draws the weapons in the same pass as the hud, meaning we have to switch this on and off depending on context.
void set()
{
twod = &twodpsp;
}
void clear()
{
twod = old;
}
};
void DrawTexture(F2DDrawer* drawer, FTexture* img, double x, double y, int tags_first, ...);
void DrawChar(F2DDrawer* drawer, FFont* font, int normalcolor, double x, double y, int character, int tag_first, ...);
void DrawText(F2DDrawer* drawer, FFont* font, int normalcolor, double x, double y, const char* string, int tag_first, ...);
void DrawText(F2DDrawer* drawer, FFont* font, int normalcolor, double x, double y, const char32_t* string, int tag_first, ...);
void DrawFrame(F2DDrawer* twod, PalEntry color, int left, int top, int width, int height, int thickness);
#endif

1384
source/common/2d/v_draw.cpp Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,50 +1,27 @@
#pragma once
/*
** v_video.h
**
**---------------------------------------------------------------------------
** Copyright 1998-2008 Randy Heit
** 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 "palentry.h"
#include "renderstyle.h"
#include "c_cvars.h"
#include "v_2ddrawer.h"
#include "c_cvars.h"
// TagItem definitions for DrawTexture. As far as I know, tag lists
// originated on the Amiga.
//
// Think of TagItems as an array of the following structure:
//
// struct TagItem {
// uint32_t ti_Tag;
// 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 */
#define TAG_USER ((uint32_t)(1u<<30))
enum
{
DTA_Base = 1,
DTA_Base = TAG_USER + 5000,
DTA_DestWidth, // width of area to draw to
DTA_DestHeight, // height of area to draw to
DTA_Alpha, // alpha value for translucency
@ -129,6 +106,9 @@ enum
class FFont;
struct FRemapTable;
class player_t;
typedef uint32_t angle_t;
struct DrawParms
{
@ -149,8 +129,8 @@ struct DrawParms
double top;
double left;
float Alpha;
int TranslationId;
PalEntry fillcolor;
int TranslationId;
PalEntry colorOverlay;
PalEntry color;
int alphaChannel;
@ -162,6 +142,7 @@ struct DrawParms
int masked;
int bilinear;
FRenderStyle style;
struct FSpecialColormap *specialcolormap;
int desaturate;
int scalex, scaley;
int cellx, celly;
@ -170,9 +151,10 @@ struct DrawParms
int maxstrlen;
bool fortext;
bool virtBottom;
bool burn;
uint8_t fsscalemode;
double srcx, srcy;
double srcwidth, srcheight;
bool burn;
};
struct Va_List
@ -180,3 +162,73 @@ struct Va_List
va_list list;
};
struct VMVa_List
{
VMValue *args;
int curindex;
int numargs;
const uint8_t *reginfo;
};
float ActiveRatio (int width, int height, float *trueratio = NULL);
inline double ActiveRatio (double width, double height) { return ActiveRatio(int(width), int(height)); }
int AspectBaseWidth(float aspect);
int AspectBaseHeight(float aspect);
double AspectPspriteOffset(float aspect);
int AspectMultiplier(float aspect);
bool AspectTallerThanWide(float aspect);
extern F2DDrawer* twod;
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);
}
#ifdef DrawText
#undef DrawText // See WinUser.h for the definition of DrawText as a macro
#endif
template<class T>
bool ParseDrawTextureTags(F2DDrawer *drawer, FTexture* img, double x, double y, uint32_t tag, T& tags, DrawParms* parms, bool fortext);
template<class T>
void DrawTextCommon(F2DDrawer *drawer, FFont* font, int normalcolor, double x, double y, const T* string, DrawParms& parms);
bool SetTextureParms(F2DDrawer *drawer, DrawParms* parms, FTexture* img, double x, double y);
void DrawText(F2DDrawer* drawer, FFont* font, int normalcolor, double x, double y, const char* string, int tag_first, ...);
void DrawText(F2DDrawer* drawer, FFont* font, int normalcolor, double x, double y, const char32_t* string, int tag_first, ...);
void DrawChar(F2DDrawer* drawer, FFont* font, int normalcolor, double x, double y, int character, int tag_first, ...);
void DrawTexture(F2DDrawer* drawer, FTexture* img, double x, double y, int tags_first, ...);
void DoDim(F2DDrawer* drawer, PalEntry color, float amount, int x1, int y1, int w, int h, FRenderStyle* style = nullptr);
void Dim(F2DDrawer* drawer, PalEntry color, float damount, int x1, int y1, int w, int h, FRenderStyle* style = nullptr);
void FillBorder(F2DDrawer *drawer, FTexture* img); // Fills the border around a 4:3 part of the screen on non-4:3 displays
void DrawFrame(F2DDrawer* drawer, int left, int top, int width, int height);
void DrawBorder(F2DDrawer* drawer, FTextureID, int x1, int y1, int x2, int y2);
void DrawFrame(F2DDrawer* twod, PalEntry color, int left, int top, int width, int height, int thickness);
// Set an area to a specified color
void ClearRect(F2DDrawer* drawer, int left, int top, int right, int bottom, int palcolor, uint32_t color);
void VirtualToRealCoords(F2DDrawer* drawer, double& x, double& y, double& w, double& h, double vwidth, double vheight, bool vbottom = false, bool handleaspect = true);
// Code that uses these (i.e. SBARINFO) should probably be evaluated for using doubles all around instead.
void VirtualToRealCoordsInt(F2DDrawer* drawer, int& x, int& y, int& w, int& h, int vwidth, int vheight, bool vbottom = false, bool handleaspect = true);
extern int CleanWidth, CleanHeight, CleanXfac, CleanYfac;
extern int CleanWidth_1, CleanHeight_1, CleanXfac_1, CleanYfac_1;

View file

@ -37,39 +37,123 @@
#include <ctype.h>
#include <wctype.h>
#include "utf8.h"
#include "v_text.h"
#include "drawparms.h"
#include "utf8.h"
#include "v_draw.h"
#include "image.h"
#include "v_2ddrawer.h"
#include "gstrings.h"
#include "v_font.h"
#include "vm.h"
#include "printf.h"
int ListGetInt(VMVa_List &tags);
class FFont;
//==========================================================================
//
// Internal texture drawing function
// Create a texture from a text in a given font.
//
//==========================================================================
void DrawTexture(F2DDrawer *drawer, FTexture* img, double x, double y, int tags_first, ...)
#if 0
FTexture * BuildTextTexture(FFont *font, const char *string, int textcolor)
{
Va_List tags;
va_start(tags.list, tags_first);
DrawParms parms;
int w;
const uint8_t *ch;
int cx;
int cy;
int trans = -1;
int kerning;
FTexture *pic;
bool res = ParseDrawTextureTags(img, x, y, tags_first, tags, &parms, false);
va_end(tags.list);
if (!res)
kerning = font->GetDefaultKerning();
ch = (const uint8_t *)string;
cx = 0;
cy = 0;
IntRect box;
while (auto c = GetCharFromString(ch))
{
return;
if (c == TEXTCOLOR_ESCAPE)
{
// Here we only want to measure the texture so just parse over the color.
V_ParseFontColor(ch, 0, 0);
continue;
}
drawer->AddTexture(img, parms);
if (c == '\n')
{
cx = 0;
cy += font->GetHeight();
continue;
}
if (nullptr != (pic = font->GetChar(c, CR_UNTRANSLATED, &w, nullptr)))
{
auto img = pic->GetImage();
auto offsets = img->GetOffsets();
int x = cx - offsets.first;
int y = cy - offsets.second;
int ww = img->GetWidth();
int h = img->GetHeight();
box.AddToRect(x, y);
box.AddToRect(x + ww, y + h);
}
cx += (w + kerning);
}
cx = -box.left;
cy = -box.top;
TArray<TexPart> part(strlen(string));
while (auto c = GetCharFromString(ch))
{
if (c == TEXTCOLOR_ESCAPE)
{
EColorRange newcolor = V_ParseFontColor(ch, textcolor, textcolor);
if (newcolor != CR_UNDEFINED)
{
trans = font->GetColorTranslation(newcolor);
textcolor = newcolor;
}
continue;
}
if (c == '\n')
{
cx = 0;
cy += font->GetHeight();
continue;
}
if (nullptr != (pic = font->GetChar(c, textcolor, &w, nullptr)))
{
auto img = pic->GetImage();
auto offsets = img->GetOffsets();
int x = cx - offsets.first;
int y = cy - offsets.second;
auto &tp = part[part.Reserve(1)];
tp.OriginX = x;
tp.OriginY = y;
tp.Image = img;
tp.Translation = range;
}
cx += (w + kerning);
}
FMultiPatchTexture *image = new FMultiPatchTexture(box.width, box.height, part, false, false);
image->SetOffsets(-box.left, -box.top);
FImageTexture *tex = new FImageTexture(image, "");
tex->SetUseType(ETextureType::MiscPatch);
TexMan.AddTexture(tex);
return tex;
}
#endif
//==========================================================================
//
// DrawChar
@ -95,7 +179,7 @@ void DrawChar (F2DDrawer* drawer, FFont *font, int normalcolor, double x, double
DrawParms parms;
Va_List tags;
va_start(tags.list, tag_first);
bool res = ParseDrawTextureTags(pic, x, y, tag_first, tags, &parms, false);
bool res = ParseDrawTextureTags(drawer, pic, x, y, tag_first, tags, &parms, false);
va_end(tags.list);
if (!res)
{
@ -108,6 +192,48 @@ void DrawChar (F2DDrawer* drawer, FFont *font, int normalcolor, double x, double
}
}
void DrawChar(F2DDrawer *drawer, FFont *font, int normalcolor, double x, double y, int character, VMVa_List &args)
{
if (font == NULL)
return;
if (normalcolor >= NumTextColors)
normalcolor = CR_UNTRANSLATED;
FTexture *pic;
int dummy;
bool redirected;
if (NULL != (pic = font->GetChar(character, normalcolor, &dummy, &redirected)))
{
DrawParms parms;
uint32_t tag = ListGetInt(args);
bool res = ParseDrawTextureTags(drawer, pic, x, y, tag, args, &parms, false);
if (!res) return;
PalEntry color = 0xffffffff;
parms.TranslationId = redirected ? -1 : font->GetColorTranslation((EColorRange)normalcolor, &color);
parms.color = PalEntry((color.a * parms.color.a) / 255, (color.r * parms.color.r) / 255, (color.g * parms.color.g) / 255, (color.b * parms.color.b) / 255);
drawer->AddTexture(pic, parms);
}
}
DEFINE_ACTION_FUNCTION(_Screen, DrawChar)
{
PARAM_PROLOGUE;
PARAM_POINTER(font, FFont);
PARAM_INT(cr);
PARAM_FLOAT(x);
PARAM_FLOAT(y);
PARAM_INT(chr);
PARAM_VA_POINTER(va_reginfo) // Get the hidden type information array
if (!twod->HasBegun2D()) ThrowAbortException(X_OTHER, "Attempt to draw to screen outside a draw function");
VMVa_List args = { param + 5, 0, numparam - 6, va_reginfo + 5 };
DrawChar(twod, font, cr, x, y, chr, args);
return 0;
}
//==========================================================================
//
// DrawText
@ -128,6 +254,7 @@ void DrawTextCommon(F2DDrawer* drawer, FFont *font, int normalcolor, double x, d
double cx;
double cy;
int boldcolor;
int trans = -1;
int kerning;
FTexture *pic;
@ -140,7 +267,7 @@ void DrawTextCommon(F2DDrawer* drawer, FFont *font, int normalcolor, double x, d
PalEntry colorparm = parms.color;
PalEntry color = 0xffffffff;
parms.TranslationId = font->GetColorTranslation((EColorRange)normalcolor, &color);
trans = 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();
@ -167,7 +294,7 @@ void DrawTextCommon(F2DDrawer* drawer, FFont *font, int normalcolor, double x, d
EColorRange newcolor = V_ParseFontColor(ch, normalcolor, boldcolor);
if (newcolor != CR_UNDEFINED)
{
parms.TranslationId = font->GetColorTranslation(newcolor, &color);
trans = font->GetColorTranslation(newcolor, &color);
parms.color = PalEntry(colorparm.a, (color.r * colorparm.r) / 255, (color.g * colorparm.g) / 255, (color.b * colorparm.b) / 255);
currentcolor = newcolor;
}
@ -184,7 +311,8 @@ void DrawTextCommon(F2DDrawer* drawer, FFont *font, int normalcolor, double x, d
bool redirected = false;
if (NULL != (pic = font->GetChar(c, currentcolor, &w, &redirected)))
{
SetTextureParms(&parms, pic, cx, cy);
parms.TranslationId = redirected? -1 : trans;
SetTextureParms(drawer, &parms, pic, cx, cy);
if (parms.cellx)
{
w = parms.cellx;
@ -208,9 +336,12 @@ void DrawTextCommon(F2DDrawer* drawer, FFont *font, int normalcolor, double x, d
{
cx += (parms.spacing) * parms.scalex;
}
}
}
// For now the 'drawer' parameter is a placeholder - this should be the way to handle it later to allow different drawers.
void DrawText(F2DDrawer *drawer, FFont* font, int normalcolor, double x, double y, const char* string, int tag_first, ...)
{
Va_List tags;
@ -220,15 +351,16 @@ void DrawText(F2DDrawer* drawer, FFont *font, int normalcolor, double x, double
return;
va_start(tags.list, tag_first);
bool res = ParseDrawTextureTags(nullptr, 0, 0, tag_first, tags, &parms, true);
bool res = ParseDrawTextureTags(drawer, nullptr, 0, 0, tag_first, tags, &parms, true);
va_end(tags.list);
if (!res)
{
return;
}
DrawTextCommon(drawer, font, normalcolor, x, y, (const uint8_t*)GStrings.localize(string), parms);
DrawTextCommon(drawer, font, normalcolor, x, y, (const uint8_t*)string, parms);
}
void DrawText(F2DDrawer *drawer, FFont* font, int normalcolor, double x, double y, const char32_t* string, int tag_first, ...)
{
Va_List tags;
@ -238,7 +370,7 @@ void DrawText(F2DDrawer* drawer, FFont *font, int normalcolor, double x, double
return;
va_start(tags.list, tag_first);
bool res = ParseDrawTextureTags(nullptr, 0, 0, tag_first, tags, &parms, true);
bool res = ParseDrawTextureTags(drawer, nullptr, 0, 0, tag_first, tags, &parms, true);
va_end(tags.list);
if (!res)
{
@ -247,25 +379,38 @@ void DrawText(F2DDrawer* drawer, FFont *font, int normalcolor, double x, double
DrawTextCommon(drawer, font, normalcolor, x, y, string, parms);
}
//==========================================================================
//
// V_DrawFrame
//
// Draw a frame around the specified area using the view border
// frame graphics. The border is drawn outside the area, not in it.
//
//==========================================================================
void DrawFrame(F2DDrawer* twod, PalEntry color, int left, int top, int width, int height, int thickness)
void DrawText(F2DDrawer *drawer, FFont *font, int normalcolor, double x, double y, const char *string, VMVa_List &args)
{
// Sanity check for incomplete gameinfo
int offset = thickness == -1 ? screen->GetHeight() / 400 : thickness;
int right = left + width;
int bottom = top + height;
DrawParms parms;
// Draw top and bottom sides.
twod->AddColorOnlyQuad(left, top - offset, width, offset, color);
twod->AddColorOnlyQuad(left - offset, top - offset, offset, height + 2 * offset, color);
twod->AddColorOnlyQuad(left, bottom, width, offset, color);
twod->AddColorOnlyQuad(right, top - offset, offset, height + 2 * offset, color);
if (font == NULL || string == NULL)
return;
uint32_t tag = ListGetInt(args);
bool res = ParseDrawTextureTags(drawer, nullptr, 0, 0, tag, args, &parms, true);
if (!res)
{
return;
}
DrawTextCommon(drawer, font, normalcolor, x, y, (const uint8_t*)string, parms);
}
DEFINE_ACTION_FUNCTION(_Screen, DrawText)
{
PARAM_PROLOGUE;
PARAM_POINTER_NOT_NULL(font, FFont);
PARAM_INT(cr);
PARAM_FLOAT(x);
PARAM_FLOAT(y);
PARAM_STRING(chr);
PARAM_VA_POINTER(va_reginfo) // Get the hidden type information array
if (!twod->HasBegun2D()) ThrowAbortException(X_OTHER, "Attempt to draw to screen outside a draw function");
VMVa_List args = { param + 5, 0, numparam - 6, va_reginfo + 5 };
const char *txt = chr[0] == '$' ? GStrings(&chr[1]) : chr.GetChars();
DrawText(twod, font, cr, x, y, txt, args);
return 0;
}

View file

@ -0,0 +1,67 @@
#pragma once
#include <stdint.h>
#include "palentry.h"
// for internal use
struct FColormap
{
PalEntry LightColor; // a is saturation (0 full, 31=b/w, other=custom colormap)
PalEntry FadeColor; // a is fadedensity>>1
uint8_t Desaturation;
uint8_t BlendFactor; // This is for handling Legacy-style colormaps which use a different formula to calculate how the color affects lighting.
uint16_t FogDensity;
void Clear()
{
LightColor = 0xffffff;
FadeColor = 0;
Desaturation = 0;
BlendFactor = 0;
FogDensity = 0;
}
void MakeWhite()
{
LightColor = 0xffffff;
}
void ClearColor()
{
LightColor = 0xffffff;
BlendFactor = 0;
Desaturation = 0;
}
void CopyLight(FColormap &from)
{
LightColor = from.LightColor;
Desaturation = from.Desaturation;
BlendFactor = from.BlendFactor;
}
void CopyFog(FColormap &from)
{
FadeColor = from.FadeColor;
FogDensity = from.FogDensity;
}
void Decolorize()
{
LightColor.Decolorize();
}
bool operator == (const FColormap &other)
{
return LightColor == other.LightColor && FadeColor == other.FadeColor && Desaturation == other.Desaturation &&
BlendFactor == other.BlendFactor && FogDensity == other.FogDensity;
}
bool operator != (const FColormap &other)
{
return !operator==(other);
}
};

View file

@ -33,9 +33,7 @@
*/
#include "stats.h"
#include "v_video.h"
#include "v_2ddrawer.h"
#include "drawparms.h"
#include "v_draw.h"
#include "v_text.h"
#include "v_font.h"
#include "c_console.h"
@ -96,12 +94,12 @@ void FStat::ToggleStat ()
m_Active = !m_Active;
}
void FStat::PrintStat ()
void FStat::PrintStat (F2DDrawer *drawer)
{
int textScale = active_con_scale();
int textScale = active_con_scale(drawer);
int fontheight = NewConsoleFont->GetHeight() + 1;
int y = screen->GetHeight() / textScale;
int y = drawer->GetHeight() / textScale;
int count = 0;
for (FStat *stat = FirstStat; stat != NULL; stat = stat->m_Next)
@ -118,9 +116,9 @@ void FStat::PrintStat ()
// Count number of linefeeds but ignore terminating ones.
if (stattext[i] == '\n') y -= fontheight;
}
DrawText(twod, NewConsoleFont, CR_GREEN, 5 / textScale, y, stattext,
DTA_VirtualWidth, screen->GetWidth() / textScale,
DTA_VirtualHeight, screen->GetHeight() / textScale,
DrawText(drawer, NewConsoleFont, CR_GREEN, 5 / textScale, y, stattext,
DTA_VirtualWidth, twod->GetWidth() / textScale,
DTA_VirtualHeight, twod->GetHeight() / textScale,
DTA_KeepRatio, true, TAG_DONE);
count++;
}

View file

@ -223,6 +223,7 @@ private:
};
class F2DDrawer;
class FStat
{
@ -238,7 +239,7 @@ public:
return m_Active;
}
static void PrintStat ();
static void PrintStat (F2DDrawer *drawer);
static FStat *FindStat (const char *name);
static void ToggleStat (const char *name);
static void EnableStat(const char* name, bool on);

View file

@ -1,3 +1,4 @@
#pragma once
/*
** v_font.h
**
@ -31,8 +32,6 @@
**
*/
#ifndef __V_FONT_H__
#define __V_FONT_H__
#include "filesystem.h"
#include "vectors.h"
@ -195,4 +194,3 @@ void V_InitFontColors();
char* CleanseString(char* str);
#endif //__V_FONT_H__

View file

@ -1,720 +0,0 @@
/*
** v_draw.cpp
** Draw patches and blocks to a canvas
**
**---------------------------------------------------------------------------
** Copyright 1998-2008 Randy Heit
** Copyright 2005-2019 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 <stdio.h>
#include <stdarg.h>
#include "c_cvars.h"
#include "drawparms.h"
#include "templates.h"
#include "v_draw.h"
#include "v_video.h"
CUSTOM_CVAR(Int, uiscale, 0, CVAR_ARCHIVE | CVAR_NOINITCALL)
{
if (self < 0)
{
self = 0;
return;
}
//setsizeneeded = true;
}
int GetUIScale(int altval)
{
int scaleval;
if (altval > 0) scaleval = altval;
else if (uiscale == 0)
{
// Default should try to scale to 640x400
int vscale = screen->GetHeight() / 400;
int hscale = screen->GetWidth() / 640;
scaleval = clamp(vscale, 1, hscale);
}
else scaleval = uiscale;
// block scales that result in something larger than the current screen.
int vmax = screen->GetHeight() / 200;
int hmax = screen->GetWidth() / 320;
int max = std::max(vmax, hmax);
return std::max(1,std::min(scaleval, max));
}
// The new console font is twice as high, so the scaling calculation must factor that in.
int GetConScale(int altval)
{
int scaleval;
if (altval > 0) scaleval = (altval+1) / 2;
else if (uiscale == 0)
{
// Default should try to scale to 640x400
int vscale = screen->GetHeight() / 800;
int hscale = screen->GetWidth() / 1280;
scaleval = clamp(vscale, 1, hscale);
}
else scaleval = (uiscale+1) / 2;
// block scales that result in something larger than the current screen.
int vmax = screen->GetHeight() / 400;
int hmax = screen->GetWidth() / 640;
int max = std::max(vmax, hmax);
return std::max(1, std::min(scaleval, max));
}
// [RH] Stretch values to make a 320x200 image best fit the screen
// without using fractional steppings
int CleanXfac, CleanYfac;
// [RH] Effective screen sizes that the above scale values give you
int CleanWidth, CleanHeight;
// Above minus 1 (or 1, if they are already 1)
int CleanXfac_1, CleanYfac_1, CleanWidth_1, CleanHeight_1;
//==========================================================================
//
// Draw parameter parsing
//
//==========================================================================
bool SetTextureParms(DrawParms *parms, FTexture *img, double xx, double yy)
{
if (img != NULL)
{
parms->x = xx;
parms->y = yy;
parms->texwidth = img->GetDisplayWidth();
parms->texheight = img->GetDisplayHeight();
if (parms->top == INT_MAX || parms->fortext)
{
parms->top = img->GetDisplayTopOffset();
}
if (parms->left == INT_MAX || parms->fortext)
{
parms->left = img->GetDisplayLeftOffset();
}
if (parms->destwidth == INT_MAX || parms->fortext)
{
parms->destwidth = img->GetDisplayWidth();
}
if (parms->destheight == INT_MAX || parms->fortext)
{
parms->destheight = img->GetDisplayHeight();
}
switch (parms->cleanmode)
{
default:
break;
case DTA_Clean:
parms->x = (parms->x - 160.0) * CleanXfac + (screen->GetWidth() * 0.5);
parms->y = (parms->y - 100.0) * CleanYfac + (screen->GetHeight() * 0.5);
parms->destwidth = parms->texwidth * CleanXfac;
parms->destheight = parms->texheight * CleanYfac;
break;
case DTA_CleanNoMove:
parms->destwidth = parms->texwidth * CleanXfac;
parms->destheight = parms->texheight * CleanYfac;
break;
case DTA_CleanNoMove_1:
parms->destwidth = parms->texwidth * CleanXfac_1;
parms->destheight = parms->texheight * CleanYfac_1;
break;
case DTA_Fullscreen:
parms->x = parms->y = 0;
break;
}
if (parms->virtWidth != screen->GetWidth() || parms->virtHeight != screen->GetHeight())
{
VirtualToRealCoords(parms->x, parms->y, parms->destwidth, parms->destheight,
parms->virtWidth, parms->virtHeight, parms->virtBottom, !parms->keepratio);
}
}
return false;
}
//==========================================================================
//
// template helpers
//
//==========================================================================
static void ListEnd(Va_List &tags)
{
va_end(tags.list);
}
static int ListGetInt(Va_List &tags)
{
return va_arg(tags.list, int);
}
static inline double ListGetDouble(Va_List &tags)
{
return va_arg(tags.list, double);
}
//==========================================================================
//
// Main taglist parsing
//
//==========================================================================
bool ParseDrawTextureTags(FTexture *img, double x, double y, uint32_t tag, Va_List& tags, DrawParms *parms, bool fortext)
{
int boolval;
int intval;
bool translationset = false;
bool fillcolorset = false;
if (!fortext)
{
if (img == NULL)
{
ListEnd(tags);
return false;
}
}
// Do some sanity checks on the coordinates.
if (x < -16383 || x > 16383 || y < -16383 || y > 16383)
{
ListEnd(tags);
return false;
}
parms->fortext = fortext;
parms->windowleft = 0;
parms->windowright = INT_MAX;
parms->dclip = screen->GetHeight();
parms->uclip = 0;
parms->lclip = 0;
parms->rclip = screen->GetWidth();
parms->left = INT_MAX;
parms->top = INT_MAX;
parms->destwidth = INT_MAX;
parms->destheight = INT_MAX;
parms->Alpha = 1.f;
parms->fillcolor = -1;
parms->colorOverlay = 0;
parms->alphaChannel = false;
parms->flipX = false;
parms->flipY = false;
parms->color = 0xffffffff;
//parms->shadowAlpha = 0;
parms->shadowColor = 0;
parms->virtWidth = screen->GetWidth();
parms->virtHeight = screen->GetHeight();
parms->keepratio = false;
parms->style.BlendOp = 255; // Dummy "not set" value
parms->masked = true;
parms->bilinear = false;
parms->desaturate = 0;
parms->cleanmode = DTA_Base;
parms->scalex = parms->scaley = 1;
parms->cellx = parms->celly = 0;
parms->maxstrlen = INT_MAX;
parms->virtBottom = false;
parms->srcx = 0.;
parms->srcy = 0.;
parms->srcwidth = 1.;
parms->srcheight = 1.;
parms->burn = false;
parms->monospace = EMonospacing::Off;
parms->spacing = 0;
parms->TranslationId = -1;
// Parse the tag list for attributes. (For floating point attributes,
// consider that the C ABI dictates that all floats be promoted to
// doubles when passed as function arguments.)
while (tag != TAG_DONE)
{
switch (tag)
{
default:
ListGetInt(tags);
break;
case DTA_DestWidth:
assert(fortext == false);
if (fortext) return false;
parms->cleanmode = DTA_Base;
parms->destwidth = ListGetInt(tags);
break;
case DTA_DestWidthF:
assert(fortext == false);
if (fortext) return false;
parms->cleanmode = DTA_Base;
parms->destwidth = ListGetDouble(tags);
break;
case DTA_DestHeight:
assert(fortext == false);
if (fortext) return false;
parms->cleanmode = DTA_Base;
parms->destheight = ListGetInt(tags);
break;
case DTA_DestHeightF:
assert(fortext == false);
if (fortext) return false;
parms->cleanmode = DTA_Base;
parms->destheight = ListGetDouble(tags);
break;
case DTA_Clean:
boolval = ListGetInt(tags);
if (boolval)
{
parms->scalex = 1;
parms->scaley = 1;
parms->cleanmode = tag;
}
break;
case DTA_CleanNoMove:
boolval = ListGetInt(tags);
if (boolval)
{
parms->scalex = CleanXfac;
parms->scaley = CleanYfac;
parms->cleanmode = tag;
}
break;
case DTA_CleanNoMove_1:
boolval = ListGetInt(tags);
if (boolval)
{
parms->scalex = CleanXfac_1;
parms->scaley = CleanYfac_1;
parms->cleanmode = tag;
}
break;
case DTA_320x200:
boolval = ListGetInt(tags);
if (boolval)
{
parms->cleanmode = DTA_Base;
parms->scalex = 1;
parms->scaley = 1;
parms->virtWidth = 320;
parms->virtHeight = 200;
}
break;
case DTA_Bottom320x200:
boolval = ListGetInt(tags);
if (boolval)
{
parms->cleanmode = DTA_Base;
parms->scalex = 1;
parms->scaley = 1;
parms->virtWidth = 320;
parms->virtHeight = 200;
}
parms->virtBottom = true;
break;
case DTA_HUDRules:
intval = ListGetInt(tags);
parms->cleanmode = intval == HUD_HorizCenter ? DTA_HUDRulesC : DTA_HUDRules;
break;
case DTA_VirtualWidth:
parms->cleanmode = DTA_Base;
parms->virtWidth = ListGetInt(tags);
break;
case DTA_VirtualWidthF:
parms->cleanmode = DTA_Base;
parms->virtWidth = ListGetDouble(tags);
break;
case DTA_VirtualHeight:
parms->cleanmode = DTA_Base;
parms->virtHeight = ListGetInt(tags);
break;
case DTA_VirtualHeightF:
parms->cleanmode = DTA_Base;
parms->virtHeight = ListGetDouble(tags);
break;
case DTA_Fullscreen:
boolval = ListGetInt(tags);
if (boolval)
{
assert(fortext == false);
if (img == NULL) return false;
parms->cleanmode = DTA_Fullscreen;
parms->virtWidth = img->GetDisplayWidth();
parms->virtHeight = img->GetDisplayHeight();
}
break;
case DTA_Alpha:
parms->Alpha = (float)(std::min<double>(1., ListGetDouble(tags)));
break;
case DTA_AlphaChannel:
parms->alphaChannel = ListGetInt(tags);
break;
case DTA_FillColor:
parms->fillcolor = ListGetInt(tags);
if (parms->fillcolor != ~0u)
{
fillcolorset = true;
}
break;
case DTA_TranslationIndex:
parms->TranslationId = ListGetInt(tags);
break;
case DTA_ColorOverlay:
parms->colorOverlay = ListGetInt(tags);
break;
case DTA_Color:
parms->color = ListGetInt(tags);
break;
case DTA_FlipX:
parms->flipX = ListGetInt(tags);
break;
case DTA_FlipY:
parms->flipY = ListGetInt(tags);
break;
case DTA_SrcX:
parms->srcx = ListGetDouble(tags) / img->GetDisplayWidth();
break;
case DTA_SrcY:
parms->srcy = ListGetDouble(tags) / img->GetDisplayHeight();
break;
case DTA_SrcWidth:
parms->srcwidth = ListGetDouble(tags) / img->GetDisplayWidth();
break;
case DTA_SrcHeight:
parms->srcheight = ListGetDouble(tags) / img->GetDisplayHeight();
break;
case DTA_TopOffset:
assert(fortext == false);
if (fortext) return false;
parms->top = ListGetInt(tags);
break;
case DTA_TopOffsetF:
assert(fortext == false);
if (fortext) return false;
parms->top = ListGetDouble(tags);
break;
case DTA_LeftOffset:
assert(fortext == false);
if (fortext) return false;
parms->left = ListGetInt(tags);
break;
case DTA_LeftOffsetF:
assert(fortext == false);
if (fortext) return false;
parms->left = ListGetDouble(tags);
break;
case DTA_CenterOffset:
assert(fortext == false);
if (fortext) return false;
if (ListGetInt(tags))
{
parms->left = img->GetDisplayWidth() * 0.5;
parms->top = img->GetDisplayHeight() * 0.5;
}
break;
case DTA_CenterBottomOffset:
assert(fortext == false);
if (fortext) return false;
if (ListGetInt(tags))
{
parms->left = img->GetDisplayWidth() * 0.5;
parms->top = img->GetDisplayHeight();
}
break;
case DTA_WindowLeft:
assert(fortext == false);
if (fortext) return false;
parms->windowleft = ListGetInt(tags);
break;
case DTA_WindowLeftF:
assert(fortext == false);
if (fortext) return false;
parms->windowleft = ListGetDouble(tags);
break;
case DTA_WindowRight:
assert(fortext == false);
if (fortext) return false;
parms->windowright = ListGetInt(tags);
break;
case DTA_WindowRightF:
assert(fortext == false);
if (fortext) return false;
parms->windowright = ListGetDouble(tags);
break;
case DTA_ClipTop:
parms->uclip = ListGetInt(tags);
if (parms->uclip < 0)
{
parms->uclip = 0;
}
break;
case DTA_ClipBottom:
parms->dclip = ListGetInt(tags);
if (parms->dclip > screen->GetHeight())
{
parms->dclip = screen->GetHeight();
}
break;
case DTA_ClipLeft:
parms->lclip = ListGetInt(tags);
if (parms->lclip < 0)
{
parms->lclip = 0;
}
break;
case DTA_ClipRight:
parms->rclip = ListGetInt(tags);
if (parms->rclip > screen->GetWidth())
{
parms->rclip = screen->GetWidth();
}
break;
case DTA_ShadowAlpha:
//parms->shadowAlpha = (float)std::min(1., ListGetDouble(tags));
break;
case DTA_ShadowColor:
parms->shadowColor = ListGetInt(tags);
break;
case DTA_Shadow:
boolval = ListGetInt(tags);
if (boolval)
{
//parms->shadowAlpha = 0.5;
parms->shadowColor = 0;
}
else
{
//parms->shadowAlpha = 0;
}
break;
case DTA_Masked:
parms->masked = ListGetInt(tags);
break;
case DTA_BilinearFilter:
parms->bilinear = ListGetInt(tags);
break;
case DTA_KeepRatio:
// I think this is a terribly misleading name, since it actually turns
// *off* aspect ratio correction.
parms->keepratio = ListGetInt(tags);
break;
case DTA_RenderStyle:
parms->style.AsDWORD = ListGetInt(tags);
break;
case DTA_LegacyRenderStyle: // mainly for ZScript which does not handle FRenderStyle that well.
parms->style = (ERenderStyle)ListGetInt(tags);
break;
case DTA_Desaturate:
parms->desaturate = ListGetInt(tags);
break;
case DTA_TextLen:
parms->maxstrlen = ListGetInt(tags);
break;
case DTA_CellX:
parms->cellx = ListGetInt(tags);
break;
case DTA_CellY:
parms->celly = ListGetInt(tags);
break;
case DTA_Monospace:
parms->monospace = ListGetInt(tags);
break;
case DTA_Spacing:
parms->spacing = ListGetInt(tags);
break;
case DTA_Burn:
parms->burn = true;
break;
}
tag = ListGetInt(tags);
}
ListEnd(tags);
if (parms->uclip >= parms->dclip || parms->lclip >= parms->rclip)
{
return false;
}
if (img != NULL)
{
SetTextureParms(parms, img, x, y);
if (parms->destwidth <= 0 || parms->destheight <= 0)
{
return false;
}
}
if (parms->style.BlendOp == 255)
{
if (fillcolorset)
{
if (parms->alphaChannel)
{
parms->style = STYLE_Shaded;
}
else if (parms->Alpha < 1.f)
{
parms->style = STYLE_TranslucentStencil;
}
else
{
parms->style = STYLE_Stencil;
}
}
else //if (parms->Alpha < 1.f)
{
parms->style = STYLE_Translucent;
}
/*
else
{
parms->style = STYLE_Normal;
}
*/
}
return true;
}
//==========================================================================
//
// Coordinate conversion
//
//==========================================================================
void VirtualToRealCoords(double &x, double &y, double &w, double &h,
double vwidth, double vheight, bool vbottom, bool handleaspect)
{
float myratio = handleaspect ? ActiveRatio (screen->GetWidth(), screen->GetHeight()) : (4.0f / 3.0f);
// if 21:9 AR, map to 16:9 for all callers.
// this allows for black bars and stops the stretching of fullscreen images
if (myratio > 1.7f) {
myratio = 16.0f / 9.0f;
}
double right = x + w;
double bottom = y + h;
if (myratio > 1.334f)
{ // The target surface is either 16:9 or 16:10, so expand the
// specified virtual size to avoid undesired stretching of the
// image. Does not handle non-4:3 virtual sizes. I'll worry about
// those if somebody expresses a desire to use them.
x = (x - vwidth * 0.5) * screen->GetWidth() * 960 / (vwidth * AspectBaseWidth(myratio)) + screen->GetWidth() * 0.5;
w = (right - vwidth * 0.5) * screen->GetWidth() * 960 / (vwidth * AspectBaseWidth(myratio)) + screen->GetWidth() * 0.5 - x;
}
else
{
x = x * screen->GetWidth() / vwidth;
w = right * screen->GetWidth() / vwidth - x;
}
if (AspectTallerThanWide(myratio))
{ // The target surface is 5:4
y = (y - vheight * 0.5) * screen->GetHeight() * 600 / (vheight * AspectBaseHeight(myratio)) + screen->GetHeight() * 0.5;
h = (bottom - vheight * 0.5) * screen->GetHeight() * 600 / (vheight * AspectBaseHeight(myratio)) + screen->GetHeight() * 0.5 - y;
if (vbottom)
{
y += (screen->GetHeight() - screen->GetHeight() * AspectMultiplier(myratio) / 48.0) * 0.5;
}
}
else
{
y = y * screen->GetHeight() / vheight;
h = bottom * screen->GetHeight() / vheight - y;
}
}

View file

@ -1,44 +0,0 @@
#pragma once
#include "drawparms.h"
#include "c_cvars.h"
#include "v_video.h"
// Undo Windows's forced #defines
#ifdef DrawText
#undef DrawText
#endif
extern int32_t xdim, ydim;
int GetUIScale(int altval);
int GetConScale(int altval);
// [RH] Stretch values to make a 320x200 image best fit the screen
// without using fractional steppings
extern int CleanXfac, CleanYfac;
// [RH] Effective screen sizes that the above scale values give you
extern int CleanWidth, CleanHeight;
// Above minus 1 (or 1, if they are already 1)
extern int CleanXfac_1, CleanYfac_1, CleanWidth_1, CleanHeight_1;
bool SetTextureParms(DrawParms *parms, FTexture *img, double xx, double yy);
bool ParseDrawTextureTags(FTexture *img, double x, double y, uint32_t tag, Va_List& tags, DrawParms *parms, bool fortext);
void VirtualToRealCoords(double &x, double &y, double &w, double &h, double vwidth, double vheight, bool vbottom, bool handleaspect);
//int ActiveFakeRatio(int width, int height);
float ActiveRatio(int width, int height, float* trueratio);
int CheckRatio(int width, int height, int* trueratio);
int AspectBaseWidth(float aspect);;
int AspectBaseHeight(float aspect);
double AspectPspriteOffset(float aspect);
int AspectMultiplier(float aspect);
bool AspectTallerThanWide(float aspect);
void ScaleWithAspect(int& w, int& h, int Width, int Height);
void V_UpdateModeSize(int width, int height);
EXTERN_CVAR(Int, con_scaletext) // Scale notify text at high resolutions?
EXTERN_CVAR(Int, con_scale)

View file

@ -1,77 +0,0 @@
/*
** v_text.h
**
**---------------------------------------------------------------------------
** Copyright 1998-2006 Randy Heit
** 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.
**---------------------------------------------------------------------------
**
*/
#ifndef __V_TEXT_H__
#define __V_TEXT_H__
#include "zstring.h"
#include "tarray.h"
#include "printf.h"
class FFont;
struct FBrokenLines
{
unsigned Width;
FString Text;
};
#define TEXTCOLOR_ESCAPE '\034'
#define TEXTCOLOR_ESCAPESTR "\034"
#define TEXTCOLOR_NORMAL "\034-"
#define TEXTCOLOR_BOLD "\034+"
#define TEXTCOLOR_CHAT "\034*"
#define TEXTCOLOR_TEAMCHAT "\034!"
#define OSDTEXT_DEFAULT TEXTCOLOR_GRAY
#define OSDTEXT_DARKRED TEXTCOLOR_DARKRED
#define OSDTEXT_GREEN TEXTCOLOR_GREEN
#define OSDTEXT_RED TEXTCOLOR_RED
#define OSDTEXT_YELLOW TEXTCOLOR_GOLD
#define OSDTEXT_BRIGHT ""
#define OSD_ERROR TEXTCOLOR_RED
extern int NumTextColors;
TArray<FBrokenLines> V_BreakLines (FFont *font, int maxwidth, const uint8_t *str, bool preservecolor = false);
inline TArray<FBrokenLines> V_BreakLines (FFont *font, int maxwidth, const char *str, bool preservecolor = false)
{ return V_BreakLines (font, maxwidth, (const uint8_t *)str, preservecolor); }
inline TArray<FBrokenLines> V_BreakLines (FFont *font, int maxwidth, const FString &str, bool preservecolor = false)
{ return V_BreakLines (font, maxwidth, (const uint8_t *)str.GetChars(), preservecolor); }
#endif //__V_TEXT_H__

View file

@ -60,6 +60,8 @@
#include "s_soundinternal.h"
#include "engineerrors.h"
#include "gamecontrol.h"
#include "v_video.h"
#include "v_draw.h"
#define LEFTMARGIN 8
#define RIGHTMARGIN 8
@ -276,7 +278,7 @@ public:
unsigned LengthCells = CalcCellSize((unsigned)Text.length());
int n = StartPosCells;
unsigned cols = ConCols / active_con_scale();
unsigned cols = ConCols / active_con_scale(twod);
if (StartPosCells >= LengthCells)
{ // Start of visible line is beyond end of line
@ -781,7 +783,7 @@ void FNotifyBuffer::AddString(int printlevel, FString source)
con_notifylines == 0)
return;
width = screen->GetWidth() / active_con_scaletext(generic_ui);
width = screen->GetWidth() / active_con_scaletext(twod, generic_ui);
FFont *font = generic_ui ? NewSmallFont : AlternativeSmallFont;
if (font == nullptr) return; // Without an initialized font we cannot handle the message (this is for those which come here before the font system is ready.)
@ -1101,7 +1103,7 @@ void FNotifyBuffer::Draw()
else
color = PrintColors[notify.PrintLevel];
int scale = active_con_scaletext(generic_ui);
int scale = active_con_scaletext(twod, generic_ui);
if (!center)
DrawText (twod, font, color, 0, line, notify.Text,
DTA_VirtualWidth, screen->GetWidth() / scale,
@ -1135,7 +1137,7 @@ void C_DrawConsole ()
static int oldbottom = 0;
int lines, left, offset;
int textScale = active_con_scale();
int textScale = active_con_scale(twod);
left = LEFTMARGIN;
lines = (ConBottom/textScale-CurrentConsoleFont->GetHeight()*2)/CurrentConsoleFont->GetHeight();
@ -1383,7 +1385,7 @@ static bool C_HandleKey (event_t *ev, FCommandBuffer &buffer)
case GK_PGUP:
if (ev->data3 & (GKM_SHIFT|GKM_CTRL))
{ // Scroll console buffer up one page
RowAdjust += (screen->GetHeight()-4)/active_con_scale() /
RowAdjust += (screen->GetHeight()-4)/active_con_scale(twod) /
((/*gamestate == GS_FULLCONSOLE || gamestate == GS_STARTUP*/false) ? CurrentConsoleFont->GetHeight() : CurrentConsoleFont->GetHeight()*2) - 3;
}
else if (RowAdjust < conbuffer->GetFormattedLineCount())
@ -1406,7 +1408,7 @@ static bool C_HandleKey (event_t *ev, FCommandBuffer &buffer)
case GK_PGDN:
if (ev->data3 & (GKM_SHIFT|GKM_CTRL))
{ // Scroll console buffer down one page
const int scrollamt = (screen->GetHeight()-4)/active_con_scale() /
const int scrollamt = (screen->GetHeight()-4)/active_con_scale(twod) /
((/*gamestate == GS_FULLCONSOLE || gamestate == GS_STARTUP*/false) ? CurrentConsoleFont->GetHeight() : CurrentConsoleFont->GetHeight()*2) - 3;
if (RowAdjust < scrollamt)
{
@ -2047,7 +2049,7 @@ static bool C_TabCompleteList ()
Printf ("%s%-*s", colorcode, int(maxwidth), TabCommands[i].TabName.GetChars());
x += maxwidth;
if (x > ConCols / active_con_scale() - maxwidth)
if (x > ConCols / active_con_scale(twod) - maxwidth)
{
x = 0;
Printf ("\n");

View file

@ -35,6 +35,7 @@
#include "v_draw.h"
#include "build.h"
#include "gamecvars.h"
#include "v_video.h"
int GUICapture = false;

View file

@ -43,6 +43,7 @@
#include "d_event.h"
#include "d_gui.h"
#include "input/m_joy.h"
#include "v_video.h"
#define NO_IMP
#include "optionmenuitems.h"

View file

@ -42,6 +42,7 @@
#include "baselayer.h"
#include "gamecontrol.h"
#include "build.h"
#include "v_video.h"
//=============================================================================
//

View file

@ -47,6 +47,7 @@
#include "savegamehelp.h"
#include "i_specialpaths.h"
#include "findfile.h"
#include "v_video.h"

View file

@ -55,6 +55,7 @@
#include "input/m_joy.h"
#include "raze_sound.h"
#include "texturemanager.h"
#include "v_video.h"
void RegisterDukeMenus();
void RegisterRedneckMenus();

View file

@ -4,12 +4,13 @@
#include "c_cvars.h"
#include "v_font.h"
#include "c_cvars.h"
#include "version.h"
#include "textures.h"
#include "zstring.h"
#include "baselayer.h"
#include "v_draw.h"
EXTERN_CVAR(Float, snd_menuvolume)
EXTERN_CVAR(Int, m_use_mouse);
@ -217,28 +218,7 @@ struct FListMenuDescriptor : public FMenuDescriptor
Reset();
}
void Reset()
{
// Reset the default settings (ignore all other values in the struct)
mSelectOfsX = 0;
mSelectOfsY = 0;
mSelector = nullptr;
mDisplayTop = 0;
mXpos = 0;
mYpos = 0;
mLinespacing = 0;
mNetgameMessage = "";
mFont = NULL;
mFontColor = CR_UNTRANSLATED;
mFontColor2 = CR_UNTRANSLATED;
mScriptId = -1;
mSecondaryId = 0;
mNativeFontNum = NIT_BigFont;
mNativePalNum = NIT_ActiveColor;
mNativeFontScale = 1.f;
mFlags = 0;
mSpacing = 0;
}
void Reset();
};
struct FOptionMenuSettings

View file

@ -49,6 +49,7 @@
#include "i_soundfont.h"
#include "zstring.h"
#include "texturemanager.h"
#include "v_video.h"
#include <zmusic.h>
// Menu-relevant content that gets filled in by scripts. This will get processed after the game has loaded.
@ -1539,3 +1540,26 @@ int M_GetDefaultSkill()
{
return gDefaultSkill;
}
void FListMenuDescriptor::Reset()
{
// Reset the default settings (ignore all other values in the struct)
mSelectOfsX = 0;
mSelectOfsY = 0;
mSelector = nullptr;
mDisplayTop = 0;
mXpos = 0;
mYpos = 0;
mLinespacing = 0;
mNetgameMessage = "";
mFont = NULL;
mFontColor = CR_UNTRANSLATED;
mFontColor2 = CR_UNTRANSLATED;
mScriptId = -1;
mSecondaryId = 0;
mNativeFontNum = NIT_BigFont;
mNativePalNum = NIT_ActiveColor;
mNativeFontScale = 1.f;
mFlags = 0;
mSpacing = 0;
}

View file

@ -40,6 +40,7 @@
#include "v_font.h"
#include "v_text.h"
#include "v_draw.h"
#include "v_video.h"
#define INPUTGRID_WIDTH 13
#define INPUTGRID_HEIGHT 5

View file

@ -41,6 +41,7 @@
#include "c_dispatch.h"
#include "statistics.h"
#include "v_2ddrawer.h"
#include "v_video.h"
extern FSaveGameNode *quickSaveSlot;

View file

@ -45,6 +45,7 @@
#include "menu/menu.h"
#include "v_draw.h"
#include "v_2ddrawer.h"
#include "v_video.h"
//=============================================================================
//

View file

@ -223,7 +223,7 @@ public:
{
if (mCenter)
{
indent = (screen->GetWidth() / 2);
indent = (twod->GetWidth() / 2);
}
drawLabel(indent, y, selected? OptionSettings.mFontColorSelection : OptionSettings.mFontColor, isGrayed());
@ -543,7 +543,7 @@ public:
{
const char *txt = GStrings.localize(mCurrent? mAltText.GetChars() : mLabel.GetChars());
int w = OptionWidth(txt) * CleanXfac_1;
int x = (screen->GetWidth() - w) / 2;
int x = (twod->GetWidth() - w) / 2;
drawText(x, y, mColor, txt);
return -1;
}
@ -631,7 +631,7 @@ public:
maxlen = NewSmallFont->StringWidth(textbuf) * CleanXfac_1;
}
mSliderShort = right + maxlen > screen->GetWidth();
mSliderShort = right + maxlen > twod->GetWidth();
if (!mSliderShort)
{
@ -646,7 +646,7 @@ public:
right -= 5*8*CleanXfac_1;
}
if (fracdigits >= 0 && right + maxlen <= screen->GetWidth())
if (fracdigits >= 0 && right + maxlen <= twod->GetWidth())
{
snprintf(textbuf, countof(textbuf), "%.*f", fracdigits, cur);
drawText(right, y, CR_DARKGRAY, textbuf);
@ -895,7 +895,7 @@ public:
// reposition the text so that the cursor is visible when in entering mode.
FString text = Represent();
int tlen = NewSmallFont->StringWidth(text) * CleanXfac_1;
int newindent = screen->GetWidth() - tlen - CursorSpace();
int newindent = twod->GetWidth() - tlen - CursorSpace();
if (newindent < indent) indent = newindent;
}
return FOptionMenuFieldBase::Draw(desc, y, indent, selected);

View file

@ -40,6 +40,7 @@
#include "printf.h"
#include "templates.h"
#include "palette.h"
#include "build.h"
#include "glbackend/glbackend.h"
#include "gl_load/gl_interface.h"

View file

@ -37,6 +37,7 @@
#include "templates.h"
#include "r_videoscale.h"
#include "cmdlib.h"
#include "v_draw.h"
#include "c_console.h"
#include "menu/menu.h"

View file

@ -112,6 +112,8 @@ void DFrameBuffer::SetSize(int width, int height)
{
Width = ViewportScaledWidth(width, height);
Height = ViewportScaledHeight(width, height);
twodgen.SetSize(Width, Height);
twodpsp.SetSize(Width, Height);
}
//==========================================================================
@ -129,7 +131,7 @@ void DFrameBuffer::DrawRateStuff ()
{
FString fpsbuff = gi->statFPS();
int textScale = active_con_scale();
int textScale = active_con_scale(twod);
int rate_x = Width / textScale - NewConsoleFont->StringWidth(&fpsbuff[0]);
twod->AddColorOnlyQuad(rate_x * textScale, 0, Width, NewConsoleFont->GetHeight() * textScale, MAKEARGB(255,0,0,0));
DrawText (twod, NewConsoleFont, CR_WHITE, rate_x, 0, (char *)&fpsbuff[0],

View file

@ -370,6 +370,7 @@ void V_InitScreen()
void V_Init2()
{
palettePostLoadLookups();
twod = &twodgen;
float gamma = static_cast<DDummyFrameBuffer *>(screen)->Gamma;
@ -408,153 +409,7 @@ void V_Init2()
//setsizeneeded = true;
}
// Helper for ActiveRatio and CheckRatio. Returns the forced ratio type, or -1 if none.
static int ActiveFakeRatio(int width, int height)
{
int fakeratio = -1;
if ((vid_aspect >= 1) && (vid_aspect <= 6))
{
// [SP] User wants to force aspect ratio; let them.
fakeratio = int(vid_aspect);
if (fakeratio == 3)
{
fakeratio = 0;
}
else if (fakeratio == 5)
{
fakeratio = 3;
}
}
return fakeratio;
}
// Active screen ratio based on cvars and size
float ActiveRatio(int width, int height, float *trueratio)
{
static float forcedRatioTypes[] =
{
4 / 3.0f,
16 / 9.0f,
16 / 10.0f,
17 / 10.0f,
5 / 4.0f,
17 / 10.0f,
21 / 9.0f
};
float ratio = width / (float)height;
int fakeratio = ActiveFakeRatio(width, height);
if (trueratio)
*trueratio = ratio;
return (fakeratio != -1) ? forcedRatioTypes[fakeratio] : ratio;
}
// Tries to guess the physical dimensions of the screen based on the
// screen's pixel dimensions. Can return:
// 0: 4:3
// 1: 16:9
// 2: 16:10
// 3: 17:10
// 4: 5:4
// 5: 17:10 (redundant, never returned)
// 6: 21:9
int CheckRatio (int width, int height, int *trueratio)
{
float aspect = width / (float)height;
static std::pair<float, int> ratioTypes[] =
{
{ 21 / 9.0f , 6 },
{ 16 / 9.0f , 1 },
{ 17 / 10.0f , 3 },
{ 16 / 10.0f , 2 },
{ 4 / 3.0f , 0 },
{ 5 / 4.0f , 4 },
{ 0.0f, 0 }
};
int ratio = ratioTypes[0].second;
float distance = fabs(ratioTypes[0].first - aspect);
for (int i = 1; ratioTypes[i].first != 0.0f; i++)
{
float d = fabs(ratioTypes[i].first - aspect);
if (d < distance)
{
ratio = ratioTypes[i].second;
distance = d;
}
}
int fakeratio = ActiveFakeRatio(width, height);
if (fakeratio == -1)
fakeratio = ratio;
if (trueratio)
*trueratio = ratio;
return fakeratio;
}
int AspectBaseWidth(float aspect)
{
return (int)round(240.0f * aspect * 3.0f);
}
int AspectBaseHeight(float aspect)
{
if (!AspectTallerThanWide(aspect))
return (int)round(200.0f * (320.0f / (AspectBaseWidth(aspect) / 3.0f)) * 3.0f);
else
return (int)round((200.0f * (4.0f / 3.0f)) / aspect * 3.0f);
}
double AspectPspriteOffset(float aspect)
{
if (!AspectTallerThanWide(aspect))
return 0.0;
else
return ((4.0 / 3.0) / aspect - 1.0) * 97.5;
}
int AspectMultiplier(float aspect)
{
if (!AspectTallerThanWide(aspect))
return (int)round(320.0f / (AspectBaseWidth(aspect) / 3.0f) * 48.0f);
else
return (int)round(200.0f / (AspectBaseHeight(aspect) / 3.0f) * 48.0f);
}
bool AspectTallerThanWide(float aspect)
{
return aspect < 1.333f;
}
void ScaleWithAspect (int &w, int &h, int Width, int Height)
{
int resRatio = CheckRatio (Width, Height);
int screenRatio;
CheckRatio (w, h, &screenRatio);
if (resRatio == screenRatio)
return;
double yratio;
switch(resRatio)
{
case 0: yratio = 4./3.; break;
case 1: yratio = 16./9.; break;
case 2: yratio = 16./10.; break;
case 3: yratio = 17./10.; break;
case 4: yratio = 5./4.; break;
case 6: yratio = 21./9.; break;
default: return;
}
double y = w/yratio;
if (y > h)
w = static_cast<int>(h * yratio);
else
h = static_cast<int>(y);
}
CCMD(vid_setsize)
{
@ -592,3 +447,6 @@ CCMD(vid_listadapters)
}
bool vid_hdr_active = false;
F2DDrawer twodpsp, twodgen;
CVAR(Float, transsouls, 1, 0)
CVAR(Int, uiscale, 0, CVAR_ARCHIVE)

View file

@ -412,38 +412,11 @@ void V_Init2 ();
void V_Shutdown ();
int CheckRatio (int width, int height, int *trueratio=NULL);
static inline int CheckRatio (double width, double height) { return CheckRatio(int(width), int(height)); }
inline bool IsRatioWidescreen(int ratio) { return (ratio & 3) != 0; }
float ActiveRatio (int width, int height, float *trueratio = NULL);
static inline double ActiveRatio (double width, double height) { return ActiveRatio(int(width), int(height)); }
int AspectBaseWidth(float aspect);
int AspectBaseHeight(float aspect);
double AspectPspriteOffset(float aspect);
int AspectMultiplier(float aspect);
bool AspectTallerThanWide(float aspect);
void ScaleWithAspect(int &w, int &h, int Width, int Height);
int GetUIScale(int altval);
int GetConScale(int altval);
extern bool setsizeneeded, setmodeneeded;
EXTERN_CVAR(Int, uiscale);
EXTERN_CVAR(Int, con_scaletext);
EXTERN_CVAR(Int, con_scale);
inline int active_con_scaletext(bool newconfont = false)
{
return newconfont? GetConScale(con_scaletext) : GetUIScale(con_scaletext);
}
inline int active_con_scale()
{
return GetConScale(con_scale);
}
#endif // __V_VIDEO_H__

View file

@ -8,6 +8,9 @@
#include "v_draw.h"
#include "serializer.h"
#include "mapinfo.h"
#include "v_video.h"
#include "v_text.h"
#include "c_cvars.h"
// Unlike in GZDoom we have to maintain this list here, because we got different game frontents that all store this info differently.
// So the games will have to report the credited secrets so that this code can keep track of how to display them.

View file

@ -30,6 +30,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "duke3d.h"
#include "sounds.h"
#include "v_text.h"
#include "printf.h"
BEGIN_DUKE_NS
@ -689,7 +691,7 @@ void A_DeleteSprite(int spriteNum)
{
if (EDUKE32_PREDICT_FALSE(block_deletesprite))
{
Printf(OSD_ERROR "A_DeleteSprite(): tried to remove sprite %d in EVENT_EGS\n", spriteNum);
Printf(TEXTCOLOR_RED "A_DeleteSprite(): tried to remove sprite %d in EVENT_EGS\n", spriteNum);
return;
}
@ -1402,7 +1404,7 @@ ACTOR_STATIC void G_MovePlayers(void)
if (ud.god == 0)
if (G_CheckForSpaceCeiling(pSprite->sectnum) || G_CheckForSpaceFloor(pSprite->sectnum))
{
Printf(OSD_ERROR "%s: player killed by space sector!\n", EDUKE32_FUNCTION);
Printf(TEXTCOLOR_RED "%s: player killed by space sector!\n", EDUKE32_FUNCTION);
P_QuickKill(pPlayer);
}
}

View file

@ -101,7 +101,7 @@ static int32_t G_OpenDemoRead(int32_t g_whichDemo) // 0 = mine
i = sv_loadsnapshot(g_demo_recFilePtr, -g_whichDemo, &saveh);
if (i)
{
Printf(OSD_ERROR "There were errors opening demo %d (code: %d).\n", g_whichDemo, i);
Printf(TEXTCOLOR_RED "There were errors opening demo %d (code: %d).\n", g_whichDemo, i);
g_demo_recFilePtr.Close();
return 0;
}
@ -656,7 +656,7 @@ RECHECK:
if (0)
{
corrupt:
Printf(OSD_ERROR "Demo %d is corrupt (code %d).\n", g_whichDemo-1, corruptcode);
Printf(TEXTCOLOR_RED "Demo %d is corrupt (code %d).\n", g_whichDemo-1, corruptcode);
nextdemo:
M_StartControlPanel(false);
nextdemo_nomenu:

View file

@ -674,7 +674,7 @@ void G_DrawRooms(int32_t playerNum, int32_t smoothRatio)
{
#ifdef DEBUGGINGAIDS
if (EDUKE32_PREDICT_FALSE(noDraw != 0))
Printf(OSD_ERROR "ERROR: EVENT_DISPLAYROOMSCAMERA return value must be 0 or 1, "
Printf(TEXTCOLOR_RED "ERROR: EVENT_DISPLAYROOMSCAMERA return value must be 0 or 1, "
"other values are reserved.\n");
#endif
@ -840,7 +840,7 @@ void G_DrawRooms(int32_t playerNum, int32_t smoothRatio)
{
#ifdef DEBUGGINGAIDS
if (EDUKE32_PREDICT_FALSE(noDraw != 0))
Printf(OSD_ERROR "ERROR: EVENT_DISPLAYROOMS return value must be 0 or 1, "
Printf(TEXTCOLOR_RED "ERROR: EVENT_DISPLAYROOMS return value must be 0 or 1, "
"other values are reserved.\n");
#endif
screen->BeginScene();
@ -2477,7 +2477,7 @@ int A_Spawn(int spriteNum, int tileNum)
if (EDUKE32_PREDICT_FALSE(pSprite->hitag && pSprite->picnum == WATERBUBBLEMAKER))
{
// JBF 20030913: Pisses off X_Move(), eg. in bobsp2
Printf(OSD_ERROR "WARNING: WATERBUBBLEMAKER %d @ %d,%d with hitag!=0. Applying fixup.\n",
Printf(TEXTCOLOR_RED "WARNING: WATERBUBBLEMAKER %d @ %d,%d with hitag!=0. Applying fixup.\n",
newSprite,TrackerCast(pSprite->x),TrackerCast(pSprite->y));
pSprite->hitag = 0;
}
@ -2735,7 +2735,7 @@ int A_Spawn(int spriteNum, int tileNum)
// use elevator sector's ceiling as heuristic
T4(newSprite) = sector[sectNum].ceilingz;
Printf(OSD_ERROR "WARNING: SE17 sprite %d using own sector's ceilingz to "
Printf(TEXTCOLOR_RED "WARNING: SE17 sprite %d using own sector's ceilingz to "
"determine when to warp. Sector %d adjacent to a door?\n",
newSprite, sectNum);
}
@ -2749,7 +2749,7 @@ int A_Spawn(int spriteNum, int tileNum)
// heuristic
T5(newSprite) = sector[sectNum].floorz;
Printf(OSD_ERROR "WARNING: SE17 sprite %d using own sector %d's floorz.\n",
Printf(TEXTCOLOR_RED "WARNING: SE17 sprite %d using own sector %d's floorz.\n",
newSprite, sectNum);
}
@ -2956,7 +2956,7 @@ int A_Spawn(int spriteNum, int tileNum)
}
if (EDUKE32_PREDICT_FALSE(spriteNum == -1))
{
Printf(OSD_ERROR "Found lonely Sector Effector (lotag 0) at (%d,%d)\n",
Printf(TEXTCOLOR_RED "Found lonely Sector Effector (lotag 0) at (%d,%d)\n",
TrackerCast(pSprite->x),TrackerCast(pSprite->y));
changespritestat(newSprite, STAT_ACTOR);
goto SPAWN_END;
@ -3998,7 +3998,7 @@ skip:
#ifdef DEBUGGINGAIDS
// A negative actor[i].dispicnum used to mean 'no floor shadow please', but
// that was a bad hack since the value could propagate to sprite[].picnum.
Printf(OSD_ERROR "actor[%d].dispicnum = %d\n", i, actor[i].dispicnum);
Printf(TEXTCOLOR_RED "actor[%d].dispicnum = %d\n", i, actor[i].dispicnum);
#endif
actor[i].dispicnum=0;
continue;

View file

@ -537,7 +537,7 @@ GAMEEXEC_STATIC void VM_AlterAng(int32_t const moveFlags)
{
AC_MOVE_ID(vm.pData) = 0;
Printf(OSD_ERROR "bad moveptr for actor %d (%d)!\n", vm.spriteNum, vm.pUSprite->picnum);
Printf(TEXTCOLOR_RED "bad moveptr for actor %d (%d)!\n", vm.spriteNum, vm.pUSprite->picnum);
return;
}
@ -694,7 +694,7 @@ GAMEEXEC_STATIC void VM_Move(void)
if (EDUKE32_PREDICT_FALSE((unsigned)AC_MOVE_ID(vm.pData) >= (unsigned)g_scriptSize-1))
{
AC_MOVE_ID(vm.pData) = 0;
Printf(OSD_ERROR "clearing bad moveptr for actor %d (%d)\n", vm.spriteNum, vm.pUSprite->picnum);
Printf(TEXTCOLOR_RED "clearing bad moveptr for actor %d (%d)\n", vm.spriteNum, vm.pUSprite->picnum);
return;
}
@ -1268,7 +1268,7 @@ static void SetArray(int const arrayNum, int const arrayIndex, int const newValu
{
if (EDUKE32_PREDICT_FALSE((unsigned)arrayNum >= (unsigned)g_gameArrayCount || (unsigned)arrayIndex >= (unsigned)aGameArrays[arrayNum].size))
{
Printf(OSD_ERROR "Gv_SetVar(): tried to set invalid array %d or index out of bounds from "
Printf(TEXTCOLOR_RED "Gv_SetVar(): tried to set invalid array %d or index out of bounds from "
"sprite %d (%d), player %d\n",
(int)arrayNum, vm.spriteNum, vm.pUSprite->picnum, vm.playerNum);
vm.flags |= VM_RETURN;
@ -1279,7 +1279,7 @@ static void SetArray(int const arrayNum, int const arrayIndex, int const newValu
if (EDUKE32_PREDICT_FALSE(arr.flags & GAMEARRAY_READONLY))
{
Printf(OSD_ERROR "Tried to set value in read-only array `%s'", arr.szLabel);
Printf(TEXTCOLOR_RED "Tried to set value in read-only array `%s'", arr.szLabel);
vm.flags |= VM_RETURN;
return;
}
@ -1310,7 +1310,7 @@ static void ResizeArray(int const arrayNum, int const newSize)
if (newSize == oldSize || newSize < 0)
return;
#if 0
Printf(OSDTEXT_GREEN "CON_RESIZEARRAY: resizing array %s from %d to %d\n",
Printf(TEXTCOLOR_GREEN "CON_RESIZEARRAY: resizing array %s from %d to %d\n",
array.szLabel, array.size, newSize);
#endif
if (newSize == 0)
@ -2834,7 +2834,7 @@ GAMEEXEC_STATIC void VM_Execute(int const loop /*= false*/)
return;
break;
badindex:
Printf(OSD_ERROR "Line %d, for %s: index %d out of range!\n", VM_DECODE_LINE_NUMBER(g_tw), iter_tokens[iterType].token, nIndex);
Printf(TEXTCOLOR_RED "Line %d, for %s: index %d out of range!\n", VM_DECODE_LINE_NUMBER(g_tw), iter_tokens[iterType].token, nIndex);
vm.flags |= VM_RETURN;
dispatch();
}
@ -5197,7 +5197,7 @@ badindex:
index = Gv_GetVar(*insptr++);
if (EDUKE32_PREDICT_TRUE((unsigned)index < (unsigned)aGameArrays[lVarID].size))
{
Printf(OSDTEXT_GREEN "CONLOGVAR: L=%d %s[%d] =%d\n", VM_DECODE_LINE_NUMBER(g_tw), aGameArrays[lVarID].szLabel, index,
Printf(TEXTCOLOR_GREEN "CONLOGVAR: L=%d %s[%d] =%d\n", VM_DECODE_LINE_NUMBER(g_tw), aGameArrays[lVarID].szLabel, index,
(int32_t)(m * Gv_GetArrayValue(lVarID, index)));
dispatch();
}
@ -5221,7 +5221,7 @@ badindex:
CON_ERRPRINTF("invalid array index\n");
abort_after_error();
}
Printf(OSDTEXT_GREEN "CONLOGVAR: L=%d %d %d\n", VM_DECODE_LINE_NUMBER(g_tw), index, Gv_GetVar(*insptr++, index, vm.playerNum));
Printf(TEXTCOLOR_GREEN "CONLOGVAR: L=%d %d %d\n", VM_DECODE_LINE_NUMBER(g_tw), index, Gv_GetVar(*insptr++, index, vm.playerNum));
dispatch();
}
}
@ -5259,7 +5259,7 @@ badindex:
Bstrcat(tempbuf, szBuf);
Bsprintf(szBuf, " =%d\n", Gv_GetVar(lVarID) * m);
Bstrcat(tempbuf, szBuf);
Printf(OSDTEXT_GREEN "%s", tempbuf);
Printf(TEXTCOLOR_GREEN "%s", tempbuf);
insptr++;
dispatch();
}

View file

@ -542,7 +542,7 @@ static int Gv_GetVarIndex(const char *szGameLabel)
if (EDUKE32_PREDICT_FALSE((unsigned)gameVar >= MAXGAMEVARS))
{
Printf(OSD_ERROR "Gv_GetVarIndex(): INTERNAL ERROR: couldn't find gamevar %s!\n", szGameLabel);
Printf(TEXTCOLOR_RED "Gv_GetVarIndex(): INTERNAL ERROR: couldn't find gamevar %s!\n", szGameLabel);
return 0;
}
@ -555,7 +555,7 @@ static int Gv_GetArrayIndex(const char *szArrayLabel)
if (EDUKE32_PREDICT_FALSE((unsigned)arrayIdx >= MAXGAMEARRAYS))
{
Printf(OSD_ERROR "Gv_GetArrayIndex(): INTERNAL ERROR: couldn't find array %s!\n", szArrayLabel);
Printf(TEXTCOLOR_RED "Gv_GetArrayIndex(): INTERNAL ERROR: couldn't find array %s!\n", szArrayLabel);
return 0;
}

View file

@ -46,7 +46,7 @@ static int osdcmd_levelwarp(CCmdFuncPtr parm)
int m = atoi(parm->parms[1]);
if (e == 0 || m == 0)
{
Printf(OSD_ERROR "Invalid level!: E%sL%s\n", parm->parms[0], parm->parms[1]);
Printf(TEXTCOLOR_RED "Invalid level!: E%sL%s\n", parm->parms[0], parm->parms[1]);
return OSDCMD_OK;
}
@ -82,7 +82,7 @@ static int osdcmd_map(CCmdFuncPtr parm)
if (!fileSystem.Lookup(mapname, "MAP"))
{
Printf(OSD_ERROR "map: file \"%s\" not found.\n", mapname.GetChars());
Printf(TEXTCOLOR_RED "map: file \"%s\" not found.\n", mapname.GetChars());
return OSDCMD_OK;
}
@ -98,7 +98,7 @@ static int osdcmd_map(CCmdFuncPtr parm)
}
if (VOLUMEONE)
{
Printf(OSD_ERROR "Cannot use user maps in shareware.\n");
Printf(TEXTCOLOR_RED "Cannot use user maps in shareware.\n");
return OSDCMD_OK;
}
// Treat as user map

View file

@ -4969,7 +4969,7 @@ void P_ProcessInput(int playerNum)
{
if (pSprite->extra > 0 && ud.noclip == 0)
{
Printf(OSD_ERROR "%s: player killed by cursectnum == -1!\n", EDUKE32_FUNCTION);
Printf(TEXTCOLOR_RED "%s: player killed by cursectnum == -1!\n", EDUKE32_FUNCTION);
P_QuickKill(pPlayer);
if (!FURY)
A_PlaySound(SQUISHED, pPlayer->i);
@ -5727,7 +5727,7 @@ RECHECK:
{
if (mashedPotato)
{
Printf(OSD_ERROR "%s: player killed by pushmove()!\n", EDUKE32_FUNCTION);
Printf(TEXTCOLOR_RED "%s: player killed by pushmove()!\n", EDUKE32_FUNCTION);
P_QuickKill(pPlayer);
return;
}

View file

@ -1272,7 +1272,7 @@ static void prelevel(int g)
}
if (missedCloudSectors > 0)
Printf(OSDTEXT_RED "Map warning: have %d unhandled CLOUDYSKIES ceilings.\n", missedCloudSectors);
Printf(TEXTCOLOR_RED "Map warning: have %d unhandled CLOUDYSKIES ceilings.\n", missedCloudSectors);
// NOTE: must be safe loop because callbacks could delete sprites.
for (int nextSprite, SPRITES_OF_STAT_SAFE(STAT_DEFAULT, i, nextSprite))
@ -1764,7 +1764,7 @@ int G_EnterLevel(int gameMode)
{
if (mm.fileName.IsEmpty())
{
Printf(OSDTEXT_RED "Map E%dL%d not defined!\n", ud.volume_number+1, ud.level_number+1);
Printf(TEXTCOLOR_RED "Map E%dL%d not defined!\n", ud.volume_number+1, ud.level_number+1);
return 1;
}
}
@ -1789,7 +1789,7 @@ int G_EnterLevel(int gameMode)
{
if (engineLoadBoard(boardfilename, 0, &p0.pos, &playerAngle, &p0.cursectnum) < 0)
{
Printf(OSD_ERROR "Map \"%s\" not found or invalid map version!\n", boardfilename);
Printf(TEXTCOLOR_RED "Map \"%s\" not found or invalid map version!\n", boardfilename);
return 1;
}
userMapRecord.name = "";
@ -1803,7 +1803,7 @@ int G_EnterLevel(int gameMode)
}
else if (engineLoadBoard(mm.fileName, VOLUMEONE, &p0.pos, &playerAngle, &p0.cursectnum) < 0)
{
Printf(OSD_ERROR "Map \"%s\" not found or invalid map version!\n", mm.fileName.GetChars());
Printf(TEXTCOLOR_RED "Map \"%s\" not found or invalid map version!\n", mm.fileName.GetChars());
return 1;
}
else
@ -1895,11 +1895,11 @@ int G_EnterLevel(int gameMode)
}
if (G_HaveUserMap())
Printf(OSDTEXT_YELLOW "%s: %s\n", GStrings("TXT_USERMAP"), boardfilename);
Printf(TEXTCOLOR_GOLD "%s: %s\n", GStrings("TXT_USERMAP"), boardfilename);
else if (FURY)
Printf(OSDTEXT_YELLOW "%s: %s\n", GStrings("TXT_ENTERING"), mm.DisplayName());
Printf(TEXTCOLOR_GOLD "%s: %s\n", GStrings("TXT_ENTERING"), mm.DisplayName());
else
Printf(OSDTEXT_YELLOW "E%dL%d: %s\n", ud.volume_number + 1, ud.level_number + 1, mm.DisplayName());
Printf(TEXTCOLOR_GOLD "E%dL%d: %s\n", ud.volume_number + 1, ud.level_number + 1, mm.DisplayName());
g_restorePalette = -1;

View file

@ -397,7 +397,7 @@ static void G_SetupCamTile(int spriteNum, int tileNum, int smoothRatio)
goto finishTileSetup;
#ifdef DEBUGGINGAIDS
else if (EDUKE32_PREDICT_FALSE(noDraw != 0)) // event return values other than 0 and 1 are reserved
Printf(OSD_ERROR "ERROR: EVENT_DISPLAYROOMSCAMERATILE return value must be 0 or 1, "
Printf(TEXTCOLOR_RED "ERROR: EVENT_DISPLAYROOMSCAMERATILE return value must be 0 or 1, "
"other values are reserved.\n");
#endif
screen->BeginScene();

View file

@ -355,7 +355,7 @@ void GameInterface::DoPrintMessage(int prio, const char* t)
if (p->ftq == QUOTE_RESERVED || p->ftq == QUOTE_RESERVED2) return;
if (p == g_player[screenpeek].ps)
Printf(prio | PRINT_NOTIFY, cq ? OSDTEXT_DEFAULT "%s\n" : "%s\n", t);
Printf(prio | PRINT_NOTIFY, cq ? TEXTCOLOR_TAN "%s\n" : "%s\n", t);
if (hud_messages == 1)
{

View file

@ -71,7 +71,7 @@ static int osdcmd_map(CCmdFuncPtr parm)
if (!fileSystem.Lookup(mapname, "MAP"))
{
Printf(OSD_ERROR "map: file \"%s\" not found.\n", mapname.GetChars());
Printf(TEXTCOLOR_RED "map: file \"%s\" not found.\n", mapname.GetChars());
return OSDCMD_OK;
}

View file

@ -42,6 +42,7 @@
#include "palette.h"
#include "flatvertices.h"
#include "build.h"
#include "v_video.h"
extern int16_t numshades;
extern TArray<VSMatrix> matrixArray;
@ -161,34 +162,13 @@ void GLInstance::Draw2D(F2DDrawer *drawer)
DisableScissor();
}
//state.SetFog(cmd.mColor1, 0);
SetColor(1, 1, 1);
//state.SetColor(1, 1, 1, 1, cmd.mDesaturate);
if (cmd.mTexture != nullptr)
{
auto tex = cmd.mTexture;
if (cmd.mType == F2DDrawer::DrawTypeRotateSprite)
{
// todo: Set up hictinting. (broken as the feature is...)
SetShade(cmd.mRemapIndex >> 16, numshades);
SetFadeDisable(false);
auto saved = curbasepal; // screw Build's dependencies on global state variables. We only need to change this for the following SetTexture call.
curbasepal = (cmd.mRemapIndex >> 8) & 0xff;
auto savedf = globalflags;
if (curbasepal > 0)
globalflags |= GLOBAL_NO_GL_FULLBRIGHT; // temp. hack to disable brightmaps.
SetTexture(-1, tex, cmd.mRemapIndex & 0xff, 4/*DAMETH_CLAMPED*/, cmd.mFlags & F2DDrawer::DTF_Wrap ? SamplerRepeat : SamplerClampXY);
curbasepal = saved;
globalflags = savedf;
}
else
{
SetFadeDisable(true);
SetShade(0, numshades);
SetNamedTexture(cmd.mTexture, cmd.mRemapIndex, cmd.mFlags & F2DDrawer::DTF_Wrap ? SamplerRepeat : SamplerClampXY);
}
SetNamedTexture(cmd.mTexture, cmd.mTranslationId, cmd.mFlags & F2DDrawer::DTF_Wrap ? SamplerRepeat : SamplerClampXY);
EnableBlend(!(cmd.mRenderStyle.Flags & STYLEF_Alpha1));
UseColorOnly(false);
}

View file

@ -517,7 +517,7 @@ void A_DeleteSprite(int spriteNum)
{
if (EDUKE32_PREDICT_FALSE(block_deletesprite))
{
Printf(OSD_ERROR "A_DeleteSprite(): tried to remove sprite %d in EVENT_EGS\n", spriteNum);
Printf(TEXTCOLOR_RED "A_DeleteSprite(): tried to remove sprite %d in EVENT_EGS\n", spriteNum);
return;
}

View file

@ -103,7 +103,7 @@ static int32_t G_OpenDemoRead(int32_t g_whichDemo) // 0 = mine
i = sv_loadsnapshot(g_demo_recFilePtr, -g_whichDemo, &saveh);
if (i)
{
Printf(OSD_ERROR "There were errors opening demo %d (code: %d).\n", g_whichDemo, i);
Printf(TEXTCOLOR_RED "There were errors opening demo %d (code: %d).\n", g_whichDemo, i);
g_demo_recFilePtr.Close();
return 0;
}
@ -659,7 +659,7 @@ RECHECK:
if (0)
{
corrupt:
Printf(OSD_ERROR "Demo %d is corrupt (code %d).\n", g_whichDemo-1, corruptcode);
Printf(TEXTCOLOR_RED "Demo %d is corrupt (code %d).\n", g_whichDemo-1, corruptcode);
nextdemo:
M_StartControlPanel(false);
nextdemo_nomenu:

View file

@ -2692,7 +2692,7 @@ rrbloodpool_fallthrough:
if (EDUKE32_PREDICT_FALSE(pSprite->hitag && pSprite->picnum == WATERBUBBLEMAKER))
{
// JBF 20030913: Pisses off X_Move(), eg. in bobsp2
Printf(OSD_ERROR "WARNING: WATERBUBBLEMAKER %d @ %d,%d with hitag!=0. Applying fixup.\n",
Printf(TEXTCOLOR_RED "WARNING: WATERBUBBLEMAKER %d @ %d,%d with hitag!=0. Applying fixup.\n",
newSprite,TrackerCast(pSprite->x),TrackerCast(pSprite->y));
pSprite->hitag = 0;
}
@ -3819,7 +3819,7 @@ rr_badguy:
// use elevator sector's ceiling as heuristic
T4(newSprite) = sector[sectNum].ceilingz;
Printf(OSD_ERROR "WARNING: SE17 sprite %d using own sector's ceilingz to "
Printf(TEXTCOLOR_RED "WARNING: SE17 sprite %d using own sector's ceilingz to "
"determine when to warp. Sector %d adjacent to a door?\n",
newSprite, sectNum);
}
@ -3833,7 +3833,7 @@ rr_badguy:
// heuristic
T5(newSprite) = sector[sectNum].floorz;
Printf(OSD_ERROR "WARNING: SE17 sprite %d using own sector %d's floorz.\n",
Printf(TEXTCOLOR_RED "WARNING: SE17 sprite %d using own sector %d's floorz.\n",
newSprite, sectNum);
}
@ -4057,7 +4057,7 @@ rr_badguy:
}
if (EDUKE32_PREDICT_FALSE(spriteNum == -1))
{
Printf(OSD_ERROR "Found lonely Sector Effector (lotag 0) at (%d,%d)\n",
Printf(TEXTCOLOR_RED "Found lonely Sector Effector (lotag 0) at (%d,%d)\n",
TrackerCast(pSprite->x),TrackerCast(pSprite->y));
changespritestat(newSprite, STAT_ACTOR);
goto SPAWN_END;
@ -5386,7 +5386,7 @@ skip:
#ifdef DEBUGGINGAIDS
// A negative actor[i].dispicnum used to mean 'no floor shadow please', but
// that was a bad hack since the value could propagate to sprite[].picnum.
Printf(OSD_ERROR "actor[%d].dispicnum = %d\n", i, actor[i].dispicnum);
Printf(TEXTCOLOR_RED "actor[%d].dispicnum = %d\n", i, actor[i].dispicnum);
#endif
actor[i].dispicnum=0;
continue;

View file

@ -515,7 +515,7 @@ GAMEEXEC_STATIC void VM_AlterAng(int32_t const moveFlags)
{
AC_MOVE_ID(vm.pData) = 0;
Printf(OSD_ERROR "bad moveptr for actor %d (%d)!\n", vm.spriteNum, vm.pUSprite->picnum);
Printf(TEXTCOLOR_RED "bad moveptr for actor %d (%d)!\n", vm.spriteNum, vm.pUSprite->picnum);
return;
}
@ -722,7 +722,7 @@ GAMEEXEC_STATIC void VM_Move(void)
if (EDUKE32_PREDICT_FALSE((unsigned)AC_MOVE_ID(vm.pData) >= (unsigned)g_scriptSize-1))
{
AC_MOVE_ID(vm.pData) = 0;
Printf(OSD_ERROR "clearing bad moveptr for actor %d (%d)\n", vm.spriteNum, vm.pUSprite->picnum);
Printf(TEXTCOLOR_RED "clearing bad moveptr for actor %d (%d)\n", vm.spriteNum, vm.pUSprite->picnum);
return;
}
@ -2825,7 +2825,7 @@ GAMEEXEC_STATIC void VM_Execute(native_t loop)
Bstrcat(tempbuf, szBuf);
Bsprintf(szBuf, " =%d\n", Gv_GetVar(lVarID) * m);
Bstrcat(tempbuf, szBuf);
Printf(OSDTEXT_GREEN "%s", tempbuf);
Printf(TEXTCOLOR_GREEN "%s", tempbuf);
insptr++;
continue;
}

View file

@ -368,7 +368,7 @@ static int Gv_GetVarIndex(const char *szGameLabel)
if (EDUKE32_PREDICT_FALSE((unsigned)gameVar >= MAXGAMEVARS))
{
Printf(OSD_ERROR "Gv_GetVarIndex(): INTERNAL ERROR: couldn't find gamevar %s!\n", szGameLabel);
Printf(TEXTCOLOR_RED "Gv_GetVarIndex(): INTERNAL ERROR: couldn't find gamevar %s!\n", szGameLabel);
return 0;
}

View file

@ -44,7 +44,7 @@ static int osdcmd_levelwarp(CCmdFuncPtr parm)
int m = atoi(parm->parms[1]);
if (e == 0 || m == 0)
{
Printf(OSD_ERROR "Invalid level!: E%sL%s\n", parm->parms[0], parm->parms[1]);
Printf(TEXTCOLOR_RED "Invalid level!: E%sL%s\n", parm->parms[0], parm->parms[1]);
return OSDCMD_OK;
}
@ -79,7 +79,7 @@ static int osdcmd_map(CCmdFuncPtr parm)
if (!fileSystem.Lookup(mapname, "MAP"))
{
Printf(OSD_ERROR "map: file \"%s\" not found.\n", mapname.GetChars());
Printf(TEXTCOLOR_RED "map: file \"%s\" not found.\n", mapname.GetChars());
return OSDCMD_OK;
}
@ -95,7 +95,7 @@ static int osdcmd_map(CCmdFuncPtr parm)
}
if (VOLUMEONE)
{
Printf(OSD_ERROR "Cannot use user maps in shareware.\n");
Printf(TEXTCOLOR_RED "Cannot use user maps in shareware.\n");
return OSDCMD_OK;
}
// Treat as user map

View file

@ -1489,7 +1489,7 @@ static void prelevel(char g)
}
if (missedCloudSectors > 0)
Printf(OSDTEXT_RED "Map warning: have %d unhandled CLOUDYSKIES ceilings.\n", missedCloudSectors);
Printf(TEXTCOLOR_RED "Map warning: have %d unhandled CLOUDYSKIES ceilings.\n", missedCloudSectors);
// NOTE: must be safe loop because callbacks could delete sprites.
if (!DEER)
@ -2323,7 +2323,7 @@ int G_EnterLevel(int gameMode)
if (mi.fileName.IsEmpty() && !Menu_HaveUserMap())
{
Printf(OSDTEXT_RED "Map E%dL%d not defined!\n", ud.volume_number+1, ud.level_number+1);
Printf(TEXTCOLOR_RED "Map E%dL%d not defined!\n", ud.volume_number+1, ud.level_number+1);
return 1;
}
@ -2343,7 +2343,7 @@ int G_EnterLevel(int gameMode)
{
if (engineLoadBoard(boardfilename, 0, &pPlayer->pos, &lbang, &pPlayer->cursectnum) < 0)
{
Printf(OSD_ERROR "Map \"%s\" not found or invalid map version!\n", boardfilename);
Printf(TEXTCOLOR_RED "Map \"%s\" not found or invalid map version!\n", boardfilename);
return 1;
}
userMapRecord.name = "";
@ -2356,7 +2356,7 @@ int G_EnterLevel(int gameMode)
}
else if (engineLoadBoard(mi.fileName, VOLUMEONE, &pPlayer->pos, &lbang, &pPlayer->cursectnum) < 0)
{
Printf(OSD_ERROR "Map \"%s\" not found or invalid map version!\n", mi.fileName.GetChars());
Printf(TEXTCOLOR_RED "Map \"%s\" not found or invalid map version!\n", mi.fileName.GetChars());
return 1;
}
else
@ -2493,11 +2493,11 @@ int G_EnterLevel(int gameMode)
if (G_HaveUserMap())
{
Printf(OSDTEXT_YELLOW "%s: %s\n", GStrings("TXT_USERMAP"), boardfilename);
Printf(TEXTCOLOR_GOLD "%s: %s\n", GStrings("TXT_USERMAP"), boardfilename);
}
else
{
Printf(OSDTEXT_YELLOW "E%dL%d: %s\n", ud.volume_number+1, ud.level_number+1,
Printf(TEXTCOLOR_GOLD "E%dL%d: %s\n", ud.volume_number+1, ud.level_number+1,
mapList[mii].DisplayName());
}

View file

@ -36,7 +36,7 @@ void InitFonts()
// Small font
for (int i = 0; i < 95; i++)
{
auto tile = TileFiles.GetTile(STARTALPHANUM + i);
auto tile = tileGetTexture(STARTALPHANUM + i);
if (tile && tile->GetTexelWidth() > 0 && tile->GetTexelHeight() > 0)
fontdata.Insert('!' + i, tile);
}
@ -46,29 +46,29 @@ void InitFonts()
// Big font
// This font is VERY messy...
fontdata.Insert('_', TileFiles.GetTile(BIGALPHANUM - 11));
fontdata.Insert('-', TileFiles.GetTile(BIGALPHANUM - 11));
for (int i = 0; i < 10; i++) fontdata.Insert('0' + i, TileFiles.GetTile(BIGALPHANUM - 10 + i));
for (int i = 0; i < 26; i++) fontdata.Insert('A' + i, TileFiles.GetTile(BIGALPHANUM + i));
fontdata.Insert('.', TileFiles.GetTile(BIGPERIOD));
fontdata.Insert(',', TileFiles.GetTile(BIGCOMMA));
fontdata.Insert('!', TileFiles.GetTile(BIGX_));
fontdata.Insert('?', TileFiles.GetTile(BIGQ));
fontdata.Insert(';', TileFiles.GetTile(BIGSEMI));
fontdata.Insert(':', TileFiles.GetTile(BIGCOLIN));
fontdata.Insert('\\', TileFiles.GetTile(BIGALPHANUM + 68));
fontdata.Insert('/', TileFiles.GetTile(BIGALPHANUM + 68));
fontdata.Insert('%', TileFiles.GetTile(BIGALPHANUM + 69));
fontdata.Insert('`', TileFiles.GetTile(BIGAPPOS));
fontdata.Insert('"', TileFiles.GetTile(BIGAPPOS));
fontdata.Insert('\'', TileFiles.GetTile(BIGAPPOS));
fontdata.Insert('_', tileGetTexture(BIGALPHANUM - 11));
fontdata.Insert('-', tileGetTexture(BIGALPHANUM - 11));
for (int i = 0; i < 10; i++) fontdata.Insert('0' + i, tileGetTexture(BIGALPHANUM - 10 + i));
for (int i = 0; i < 26; i++) fontdata.Insert('A' + i, tileGetTexture(BIGALPHANUM + i));
fontdata.Insert('.', tileGetTexture(BIGPERIOD));
fontdata.Insert(',', tileGetTexture(BIGCOMMA));
fontdata.Insert('!', tileGetTexture(BIGX_));
fontdata.Insert('?', tileGetTexture(BIGQ));
fontdata.Insert(';', tileGetTexture(BIGSEMI));
fontdata.Insert(':', tileGetTexture(BIGCOLIN));
fontdata.Insert('\\', tileGetTexture(BIGALPHANUM + 68));
fontdata.Insert('/', tileGetTexture(BIGALPHANUM + 68));
fontdata.Insert('%', tileGetTexture(BIGALPHANUM + 69));
fontdata.Insert('`', tileGetTexture(BIGAPPOS));
fontdata.Insert('"', tileGetTexture(BIGAPPOS));
fontdata.Insert('\'', tileGetTexture(BIGAPPOS));
BigFont = new ::FFont("BigFont", nullptr, "defbigfont", 0, 0, 0, -1, -1, false, false, false, &fontdata);
fontdata.Clear();
// Tiny font
for (int i = 0; i < 95; i++)
{
auto tile = TileFiles.GetTile(MINIFONT + i);
auto tile = tileGetTexture(MINIFONT + i);
if (tile && tile->GetTexelWidth() > 0 && tile->GetTexelHeight() > 0)
fontdata.Insert('!' + i, tile);
}
@ -76,9 +76,9 @@ void InitFonts()
fontdata.Clear();
// SBAR index font
for (int i = 0; i < 10; i++) fontdata.Insert('0' + i, TileFiles.GetTile(THREEBYFIVE + i));
fontdata.Insert(':', TileFiles.GetTile(THREEBYFIVE + 10));
fontdata.Insert('/', TileFiles.GetTile(THREEBYFIVE + 11));
for (int i = 0; i < 10; i++) fontdata.Insert('0' + i, tileGetTexture(THREEBYFIVE + i));
fontdata.Insert(':', tileGetTexture(THREEBYFIVE + 10));
fontdata.Insert('/', tileGetTexture(THREEBYFIVE + 11));
new ::FFont("IndexFont", nullptr, nullptr, 0, 0, 0, -1, -1, false, false, false, &fontdata);
}
@ -98,7 +98,7 @@ static int32_t sbarxr(int32_t x)
static int32_t sbary(int32_t y)
{
if (hud_position == 1 && ud.screen_size == 4 && ud.althud == 1) return sbarsc(y << 16);
else return (100<<16) - sbarsc(200<<16) + sbarsc(y<<16);
else return (200<<16) - sbarsc(200<<16) + sbarsc(y<<16);
}
int32_t sbarx16(int32_t x)
@ -123,7 +123,7 @@ static int32_t sbarxr16(int32_t x)
int32_t sbary16(int32_t y)
{
return (100<<16) - sbarsc(200<<16) + sbarsc(y);
return (200<<16) - sbarsc(200<<16) + sbarsc(y);
}
static void G_PatchStatusBar(int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t aspectCorrect = 1)

View file

@ -359,7 +359,7 @@ void GameInterface::DoPrintMessage(int prio, const char* t)
if (p->ftq == QUOTE_RESERVED || p->ftq == QUOTE_RESERVED2) return;
if (p == g_player[screenpeek].ps)
Printf(prio|PRINT_NOTIFY, cq ? OSDTEXT_DEFAULT "%s\n" : "%s\n", t);
Printf(prio|PRINT_NOTIFY, cq ? TEXTCOLOR_TAN "%s\n" : "%s\n", t);
if (hud_messages == 1)
{

View file

@ -40,7 +40,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "gstrings.h"
#include "common.h"
#include "core/2d/v_text.h"
#include "v_text.h"
#include "printf.h"
#include "cheats.h"
#include "demo.h" // g_firstDemoFile[]
@ -63,7 +64,7 @@ static int osdcmd_map(CCmdFuncPtr parm)
if (!fileSystem.Lookup(mapname, "MAP"))
{
Printf(OSD_ERROR "map: file \"%s\" not found.\n", mapname.GetChars());
Printf(TEXTCOLOR_RED "map: file \"%s\" not found.\n", mapname.GetChars());
return OSDCMD_OK;
}