summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 1a85cc1)
raw | patch | inline | side by side (parent: 1a85cc1)
author | DeaDDooMER <deaddoomer@deadsoftware.ru> | |
Sat, 11 Jun 2022 15:33:33 +0000 (18:33 +0300) | ||
committer | DeaDDooMER <deaddoomer@deadsoftware.ru> | |
Fri, 9 Jun 2023 08:42:56 +0000 (11:42 +0300) |
diff --git a/src/game/Doom2DF.lpr b/src/game/Doom2DF.lpr
index 6fdc3094a2b9844920eca1de146363107f052080..ba700515606c038b292305dc5c2f8e03591ebd2f 100644 (file)
--- a/src/game/Doom2DF.lpr
+++ b/src/game/Doom2DF.lpr
r_textures in 'renders/opengl/r_textures.pas',
r_draw in 'renders/opengl/r_draw.pas',
r_map in 'renders/opengl/r_map.pas',
+ r_fonts in 'renders/opengl/r_fonts.pas',
{$ELSE}
{$FATAL render driver not selected}
{$ENDIF}
index c2bfc245726f040e249c9455835317666c7726a3..5f01c5b4c10947afc90195ae181816ce3c7dfe68 100644 (file)
procedure r_Draw_FillRect (l, t, r, b: Integer; rr, gg, bb, aa: Byte);
procedure r_Draw_InvertRect (l, t, r, b: Integer; rr, gg, bb, aa: Byte);
+ procedure r_Draw_Text (const text: AnsiString; x, y: Integer; r, g, b, a: Byte; f: TGLFont);
+
implementation
uses
glEnd;
end;
+ procedure r_Draw_Text (const text: AnsiString; x, y: Integer; r, g, b, a: Byte; f: TGLFont);
+ var i, xoff: Integer; t: TGLTexture; ch: AnsiChar;
+ begin
+ xoff := x;
+ for i := 1 to Length(text) do
+ begin
+ ch := text[i];
+ t := f.GetChar(ch);
+ if t <> nil then
+ r_Draw_Texture(t, xoff, y, t.width, t.height, false, r, g, b, a, false);
+ Inc(xoff, f.GetWidth(ch) + f.GetSpace());
+ end;
+ end;
+
end.
diff --git a/src/game/renders/opengl/r_fonts.pas b/src/game/renders/opengl/r_fonts.pas
--- /dev/null
@@ -0,0 +1,82 @@
+(* Copyright (C) Doom 2D: Forever Developers
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 3 of the License ONLY.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *)
+{$INCLUDE ../../../shared/a_modes.inc}
+unit r_fonts;
+
+interface
+
+ type
+ TFontInfo = record
+ w, h: Integer;
+ kern: Integer;
+ ch: array [AnsiChar] of record
+ w: Byte;
+ end;
+ end;
+
+ TFont = class abstract
+ end;
+
+ function r_Font_LoadInfoFromFile (const filename: AnsiString; var f: TFontInfo): Boolean;
+
+implementation
+
+ uses
+ Math, SysUtils,
+ WADREADER, CONFIG, utils,
+ e_log
+ ;
+
+ function r_Font_LoadInfoFromMemory (data: Pointer; size: LongInt; var f: TFontInfo): Boolean;
+ var cfg: TConfig; c: AnsiChar;
+ begin
+ result := false;
+ if data <> nil then
+ begin
+ cfg := TConfig.CreateMem(data, size);
+ if cfg <> nil then
+ begin
+ f.w := MIN(MAX(cfg.ReadInt('FontMap', 'CharWidth', 0), 0), 255);
+ f.h := MIN(MAX(cfg.ReadInt('FontMap', 'CharHeight', 0), 0), 255);
+ f.kern := MIN(MAX(cfg.ReadInt('FontMap', 'Kerning', 0), -128), 127);
+ for c := #0 to #255 do
+ begin
+ f.ch[c].w := MIN(MAX(cfg.ReadInt(IntToStr(ORD(c)), 'Width', 0), 0), 255);
+ end;
+ result := (f.w > 0) and (f.h > 0);
+ cfg.Free;
+ end;
+ end;
+ end;
+
+ function r_Font_LoadInfoFromFile (const filename: AnsiString; var f: TFontInfo): Boolean;
+ var wad: TWADFile; wadName, resName: AnsiString; data: Pointer; size: Integer;
+ begin
+ result := false;
+ wadName := g_ExtractWadName(filename);
+ wad := TWADFile.Create();
+ if wad.ReadFile(wadName) then
+ begin
+ resName := g_ExtractFilePathName(filename);
+ if wad.GetResource(resName, data, size, false) then
+ begin
+ result := r_Font_LoadInfoFromMemory(data, size, f);
+ FreeMem(data);
+ end;
+ wad.Free;
+ end;
+ end;
+
+end.
index c974664acf4e043c7f1f96edfb988b8878b8b556..11be032553b5fe48717cb92f1dfc25730b3fe871 100644 (file)
SetLength(Models[i].gibs.rect, m.GibsCount);
for a := 0 to m.GibsCount - 1 do
Models[i].gibs.rect[a] := DefaultGibSize;
- if r_Textures_LoadStreamFromFile(prefix + m.GibsResource, 32, 32, m.GibsCount, Models[i].gibs.base, Models[i].gibs.rect) then
+ if r_Textures_LoadStreamFromFile(prefix + m.GibsResource, 32, 32, m.GibsCount, m.GibsCount, Models[i].gibs.base, Models[i].gibs.rect) then
begin
- if r_Textures_LoadStreamFromFile(prefix + m.GibsMask, 32, 32, m.GibsCount, Models[i].gibs.mask, nil) then
+ if r_Textures_LoadStreamFromFile(prefix + m.GibsMask, 32, 32, m.GibsCount, m.GibsCount, Models[i].gibs.mask, nil) then
begin
// ok
end;
index 2a385a15b4724838172a520fb0d2bf0ed2214b13..249867d920e51482f181ee2f7b459b7faa7d1f89 100644 (file)
SysUtils, Classes, Math,
e_log, utils,
g_game, g_options, g_console,
- r_textures, r_map
+ r_draw, r_textures, r_fonts, r_map
;
var
menuBG: TGLTexture;
+ stdfont: TGLFont;
+ smallfont: TGLFont;
+ menufont: TGLFont;
procedure r_Render_LoadTextures;
begin
r_Map_FreeTextures;
end;
+ function r_Render_LoadFont (const name: AnsiString): TGLFont;
+ var info: TFontInfo; skiphack: Integer;
+ begin
+ result := nil;
+ if name = 'STD' then skiphack := 144 else skiphack := 0;
+ if r_Font_LoadInfoFromFile(GameWad + ':FONTS/' + name + 'TXT', info) then
+ result := r_Textures_LoadFontFromFile(GameWad + ':FONTS/' + name + 'FONT', info, skiphack, true);
+ if result = nil then
+ e_logwritefln('failed to load font %s', [name]);
+ end;
+
procedure r_Render_Load;
begin
menuBG := r_Textures_LoadFromFile(GameWAD + ':' + 'TEXTURES/TITLE');
+ stdfont := r_Render_LoadFont('STD');
+ smallfont := r_Render_LoadFont('SMALL');
+ menufont := r_Render_LoadFont('MENU');
r_Map_Load;
end;
procedure r_Render_Free;
begin
r_Map_Free;
+ menufont.Free;
+ smallfont.Free;
+ stdfont.Free;
menuBG.Free;
end;
index ce71ebc727d7e96b0001e0a44a512ba1b9269846..5950e36f6f272bf67b39af7fd2cfac386291ae6a 100644 (file)
{$ENDIF}
g_base, // TRectHW
utils,
- r_atlas
+ r_atlas, r_fonts
;
type
TRectArray = array of TRectWH;
+ TGLFont = class sealed (TFont)
+ private
+ info: TFontInfo;
+ ch: TGLTextureArray;
+
+ public
+ destructor Destroy; override;
+ function GetChar (c: AnsiChar): TGLTexture;
+ function GetWidth (c: AnsiChar): Integer;
+ function GetSpace (): Integer;
+ end;
+
procedure r_Textures_Initialize;
procedure r_Textures_Finalize;
function r_Textures_LoadFromFile (const filename: AnsiString; log: Boolean = True): TGLTexture;
function r_Textures_LoadMultiFromFile (const filename: AnsiString; log: Boolean = True): TGLMultiTexture;
function r_Textures_LoadMultiFromFileAndInfo (const filename: AnsiString; w, h, count: Integer; backanim: Boolean; log: Boolean = True): TGLMultiTexture;
- function r_Textures_LoadStreamFromFile (const filename: AnsiString; w, h, count: Integer; st: TGLTextureArray; rs: TRectArray; log: Boolean = True): Boolean;
+ function r_Textures_LoadStreamFromFile (const filename: AnsiString; w, h, count, cw: Integer; st: TGLTextureArray; rs: TRectArray; log: Boolean = True): Boolean;
+
+ function r_Textures_LoadFontFromFile (const filename: AnsiString; constref f: TFontInfo; skipch: Integer; log: Boolean = true): TGLFont;
implementation
function r_Textures_LoadFromImage (var img: TImageData): TGLTexture;
var t: TGLTexture; n: TGLAtlasNode; c: TDynImageDataArray; cw, ch, i, j: LongInt;
begin
- // e_logwritefln('r_Textures_CreateFromImage: w=%s h=%s', [img.width, img.height]);
result := nil;
if SplitImage(img, c, maxTileSize, maxTileSize, cw, ch, False) then
begin
end;
end;
- function r_Textures_LoadStreamFromImage (var img: TImageData; w, h, c: Integer; st: TGLTextureArray; rs: TRectArray): Boolean;
- var i: Integer; t: TImageData;
+ function r_Textures_LoadStreamFromImage (var img: TImageData; w, h, c, cw: Integer; st: TGLTextureArray; rs: TRectArray): Boolean;
+ var i, x, y: Integer; t: TImageData;
begin
ASSERT(w >= 0);
ASSERT(h >= 0);
ASSERT(c >= 1);
+ ASSERT(cw >= 1);
ASSERT((st <> nil) and (Length(st) >= c));
ASSERT((rs = nil) or (Length(rs) >= c));
result := true;
for i := 0 to c - 1 do
begin
+ x := i mod cw;
+ y := i div cw;
InitImage(t);
st[i] := nil;
if NewImage(w, h, img.Format, t) then
begin
- if CopyRect(img, w * i, 0, w, h, t, 0, 0) then
+ if CopyRect(img, x * w, y * h, w, h, t, 0, 0) then
begin
if rs <> nil then
rs[i] := r_Textures_GetRect(t);
end;
end;
- function r_Textures_LoadStreamFromMemory (data: Pointer; size: LongInt; w, h, c: Integer; st: TGLTextureArray; rs: TRectArray): Boolean;
+ function r_Textures_LoadStreamFromMemory (data: Pointer; size: LongInt; w, h, c, cw: Integer; st: TGLTextureArray; rs: TRectArray): Boolean;
var img: TImageData;
begin
ASSERT(w >= 0);
ASSERT(h >= 0);
ASSERT(c >= 1);
+ ASSERT(cw >= 1);
ASSERT((st <> nil) and (Length(st) >= c));
ASSERT((rs = nil) or (Length(rs) >= c));
result := false;
InitImage(img);
try
if LoadImageFromMemory(data, size, img) then
+ begin
if r_Textures_FixImageData(img) then
- result := r_Textures_LoadStreamFromImage(img, w, h, c, st, rs)
+ begin
+ result := r_Textures_LoadStreamFromImage(img, w, h, c, cw, st, rs)
+ end;
+ end;
except
end;
FreeImage(img);
end;
end;
- function r_Textures_LoadStreamFromFile (const filename: AnsiString; w, h, count: Integer; st: TGLTextureArray; rs: TRectArray; log: Boolean = True): Boolean;
+ function r_Textures_LoadStreamFromFile (const filename: AnsiString; w, h, count, cw: Integer; st: TGLTextureArray; rs: TRectArray; log: Boolean = True): Boolean;
var wad: TWADFile; wadName, resName: AnsiString; data: Pointer; size: Integer;
begin
ASSERT(w > 0);
ASSERT(h > 0);
ASSERT(count >= 1);
+ ASSERT(cw >= 1);
ASSERT((st <> nil) and (Length(st) >= count));
ASSERT((rs = nil) or (Length(rs) >= count));
result := false;
resName := g_ExtractFilePathName(filename);
if wad.GetResource(resName, data, size, log) then
begin
- result := r_Textures_LoadStreamFromMemory(data, size, w, h, count, st, rs);
+ result := r_Textures_LoadStreamFromMemory(data, size, w, h, count, cw, st, rs);
FreeMem(data);
end;
wad.Free
- end
+ end;
+ end;
+
+ (* --------- TGLFont --------- *)
+
+ function r_Textures_LoadFontFromFile (const filename: AnsiString; constref f: TFontInfo; skipch: Integer; log: Boolean = true): TGLFont;
+ var i: Integer; st: TGLTextureArray; font: TGLFont; t: TGLTexture;
+ begin
+ ASSERT(skipch >= 0);
+ result := nil;
+ SetLength(st, 256);
+ if r_Textures_LoadStreamFromFile(filename, f.w, f.h, 256, 16, st, nil, log) then
+ begin
+ if skipch > 0 then
+ begin
+ for i := 0 to 255 do
+ begin
+ t := st[i];
+ st[i] := st[(i + skipch) mod 256];
+ st[(i + skipch) mod 256] := t;
+ end;
+ end;
+ font := TGLFont.Create();
+ font.info := f;
+ font.ch := st;
+ result := font;
+ end;
+ end;
+
+ destructor TGLFont.Destroy;
+ var i: Integer;
+ begin
+ if self.ch <> nil then
+ for i := 0 to High(self.ch) do
+ self.ch[i].Free;
+ self.ch := nil;
+ end;
+
+ function TGLFont.GetChar (c: AnsiChar): TGLTexture;
+ begin
+ result := self.ch[ORD(c)];
+ end;
+
+ function TGLFont.GetWidth (c: AnsiChar): Integer;
+ begin
+ result := self.info.ch[c].w;
+ if result = 0 then
+ result := self.info.w;
+ end;
+
+ function TGLFont.GetSpace (): Integer;
+ begin
+ result := self.info.kern;
end;
end.