DEADSOFTWARE

hopefully no more windows
[d2df-editor.git] / src / engine / e_graphics.pas
index e4eb35a89ed96385e90571c40c9d4d8d6959f5bc..63a9e5bc113c6569f0cda0a65bcf5bc5d63c9bd6 100644 (file)
@@ -1,9 +1,26 @@
+(* 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, either version 3 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 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/>.
+ *)
+{$MODE DELPHI}
 unit e_graphics;
 
 interface
 
 uses
-  windows, SysUtils, Math, e_log, e_textures, dglOpenGL;
+  SysUtils, Classes, Math, e_log, e_textures, GL, GLExt, MAPDEF,
+  ImagingTypes, Imaging, ImagingUtility;
 
 type
   TMirrorType=(M_NONE, M_HORIZONTAL, M_VERTICAL);
@@ -13,11 +30,16 @@ type
     X, Y: Integer;
   end;
 
+  TPoint = MAPDEF.TPoint; // TODO: create an utiltypes.pas or something
+                          //       for other types like rect as well
+
   TPoint2f = record
     X, Y: Double;
   end;
 
-  TRect = windows.TRect;
+  TRect = record
+    Left, Top, Right, Bottom: Integer;
+  end;
 
   TRectWH = record
    X, Y: Integer;
@@ -37,7 +59,7 @@ type
 //------------------------------------------------------------------
 // ïðîòîòèïû ôóíêöèé
 //------------------------------------------------------------------
-procedure e_InitGL(VSync: Boolean);
+procedure e_InitGL();
 procedure e_SetViewPort(X, Y, Width, Height: Word);
 procedure e_ResizeWindow(Width, Height: Integer);
 
@@ -57,22 +79,16 @@ procedure e_DrawQuad(X1, Y1, X2, Y2: Integer; Red, Green, Blue: Byte; Alpha: Byt
 procedure e_DrawFillQuad(X1, Y1, X2, Y2: Integer; Red, Green, Blue, Alpha: Byte;
                          Blending: TBlending = B_NONE);
 
+function e_CreateTextureImg (var img: TImageData; var ID: DWORD): Boolean;
 function e_CreateTexture(FileName: string; var ID: DWORD): Boolean;
 function e_CreateTextureEx(FileName: string; var ID: DWORD; fX, fY, fWidth, fHeight: Word): Boolean;
-function e_CreateTextureMem(pData: Pointer; var ID: DWORD): Boolean;
-function e_CreateTextureMemEx(pData: Pointer; var ID: DWORD; fX, fY, fWidth, fHeight: Word): Boolean;
+function e_CreateTextureMem(pData: Pointer; dataSize: LongInt; var ID: DWORD): Boolean;
+function e_CreateTextureMemEx(pData: Pointer; dataSize: LongInt; var ID: DWORD; fX, fY, fWidth, fHeight: Word): Boolean;
 procedure e_GetTextureSize(ID: DWORD; Width, Height: PWord);
 function e_GetTextureSize2(ID: DWORD): TRectWH;
 procedure e_DeleteTexture(ID: DWORD);
 procedure e_RemoveAllTextures();
 
-// SimpleFont
-function e_SimpleFontCreate(FontName: PChar; Size: Byte; Weight: Word; DC: HDC): DWORD;
-procedure e_SimpleFontFree(Font: DWORD);
-procedure e_SimpleFontPrint(X, Y: SmallInt; Text: PChar; Font: Integer; Red, Green, Blue: Byte);
-procedure e_SimpleFontPrintEx(X, Y: SmallInt; Text: PChar; Font: DWORD; Red, Green, Blue,
-                      sRed, sGreen, sBlue, sWidth: Byte);
-
 // CharFont
 function e_CharFont_Create(sp: ShortInt=0): DWORD;
 procedure e_CharFont_AddChar(FontID: DWORD; Texture: Integer; c: Char; w: Byte);
@@ -88,7 +104,7 @@ procedure e_CharFont_Remove(FontID: DWORD);
 procedure e_CharFont_RemoveAll();
 
 // TextureFont
-procedure e_TextureFontBuild(Texture: DWORD; var FontID: DWORD; XCount, YCount: Word;
+procedure e_TextureFontBuild(Tex: DWORD; var FontID: DWORD; XCount, YCount: Word;
                              Space: ShortInt=0);
 procedure e_TextureFontKill(FontID: DWORD);
 procedure e_TextureFontPrint(X, Y: GLint; Text: string; FontID: DWORD);
@@ -98,38 +114,46 @@ procedure e_TextureFontPrintFmt(X, Y: GLint; Text: string; FontID: DWORD; Shadow
 procedure e_TextureFontGetSize(ID: DWORD; var CharWidth, CharHeight: Byte);
 procedure e_RemoveAllTextureFont();
 
+function e_TextureFontCharWidth (ch: Char; FontID: DWORD): Integer;
+procedure e_TextureFontPrintCharEx (X, Y: Integer; Ch: Char; FontID: DWORD; Shadow: Boolean = False);
+
 procedure e_ReleaseEngine();
 procedure e_BeginRender();
-procedure e_Clear(Mask: TGLbitfield; Red, Green, Blue: Single);
+procedure e_Clear(Mask: TGLbitfield; Red, Green, Blue: Single); overload;
+procedure e_Clear(); overload;
 procedure e_EndRender();
 
-function e_GetGamma(DC: HDC): Byte;
-procedure e_SetGamma(Gamma: Byte; DC: HDC);
-
-procedure e_MakeScreenshot(FileName: string; Width, Height: Word);
-
 function _RGB(Red, Green, Blue: Byte): TRGB;
 function _Point(X, Y: Integer): TPoint2i;
 function _Rect(X, Y: Integer; Width, Height: Word): TRectWH;
+function _TRect(L, T, R, B: LongInt): TRect;
 
+//function e_getTextGLId (ID: DWORD): GLuint;
 
 var
   e_Colors: TRGB;
+  e_NoGraphics: Boolean = False;
+  e_FastScreenshots: Boolean = true; // it's REALLY SLOW with `false`
+
 
 implementation
 
+uses
+  paszlib, crc, utils;
+
+
 type
   TTexture = record
-   ID:     DWORD;
-   Width:  Word;
-   Height: Word;
+   tx:     GLTexture;
   end;
 
   TTextureFont = record
-   TextureID:  DWORD;
-   Base:       GLuint;
-   CharWidth:  Byte;
-   CharHeight: Byte;
+   Texture:     DWORD;
+   TextureID:   DWORD;
+   Base:        Uint32;
+   CharWidth:   Byte;
+   CharHeight:  Byte;
+   XC, YC, SPC: Word;
   end;
 
   TCharFont = record
@@ -143,25 +167,35 @@ type
    Live: Boolean;
   end;
 
+  TSavedTexture = record
+    TexID:  DWORD;
+    OldID:  DWORD;
+    Pixels: Pointer;
+  end;
+
 var
   e_Textures: array of TTexture = nil;
   e_TextureFonts: array of TTextureFont = nil;
   e_CharFonts: array of TCharFont;
+  //e_SavedTextures: array of TSavedTexture;
+
+//function e_getTextGLId (ID: DWORD): GLuint; begin result := e_Textures[ID].tx.id; end;
 
 //------------------------------------------------------------------
 // Èíèöèàëèçèðóåò OpenGL
 //------------------------------------------------------------------
-procedure e_InitGL(VSync: Boolean);
+procedure e_InitGL();
 begin
-  if VSync then
-    wglSwapIntervalEXT(1)
-  else
-    wglSwapIntervalEXT(0);
-  glDisable(GL_DEPTH_TEST);
-  glEnable(GL_SCISSOR_TEST);
+  if e_NoGraphics then
+  begin
+    e_DummyTextures := True;
+    Exit;
+  end;
   e_Colors.R := 255;
   e_Colors.G := 255;
   e_Colors.B := 255;
+  glDisable(GL_DEPTH_TEST);
+  glEnable(GL_SCISSOR_TEST);
   glClearColor(0, 0, 0, 0);
 end;
 
@@ -170,6 +204,7 @@ var
   mat: Array [0..15] of GLDouble;
 
 begin
+  if e_NoGraphics then Exit;
   glLoadIdentity();
   glScissor(X, Y, Width, Height);
   glViewport(X, Y, Width, Height);
@@ -200,7 +235,7 @@ begin
   glLoadMatrixd(@mat[0]);
 
   glMatrixMode(GL_MODELVIEW);
-  glLoadIdentity();   
+  glLoadIdentity();
 end;
 
 //------------------------------------------------------------------
@@ -212,7 +247,7 @@ var
 begin
  if e_Textures <> nil then
  for i := 0 to High(e_Textures) do
-  if e_Textures[i].Width = 0 then
+  if e_Textures[i].tx.Width = 0 then
   begin
    Result := i;
    Exit;
@@ -236,6 +271,7 @@ end;
 function e_CreateTexture(FileName: String; var ID: DWORD): Boolean;
 var
   find_id: DWORD;
+  fmt:     Word;
 begin
  Result := False;
 
@@ -243,8 +279,8 @@ begin
 
  find_id := FindTexture();
 
- if not LoadTexture(FileName, e_Textures[find_id].ID, e_Textures[find_id].Width,
-                    e_Textures[find_id].Height) then Exit;
+ if not LoadTexture(FileName, e_Textures[find_id].tx, e_Textures[find_id].tx.Width,
+                    e_Textures[find_id].tx.Height, @fmt) then Exit;
 
  ID := find_id;
 
@@ -254,81 +290,92 @@ end;
 function e_CreateTextureEx(FileName: String; var ID: DWORD; fX, fY, fWidth, fHeight: Word): Boolean;
 var
   find_id: DWORD;
+  fmt:     Word;
 begin
  Result := False;
 
  find_id := FindTexture();
 
- if not LoadTextureEx(FileName, e_Textures[find_id].ID, fX, fY, fWidth, fHeight) then Exit;
-
- e_Textures[find_id].Width := fWidth;
- e_Textures[find_id].Height := fHeight;
+ if not LoadTextureEx(FileName, e_Textures[find_id].tx, fX, fY, fWidth, fHeight, @fmt) then exit;
 
  ID := find_id;
 
  Result := True;
 end;
 
-function e_CreateTextureMem(pData: Pointer; var ID: DWORD): Boolean;
+function e_CreateTextureMem(pData: Pointer; dataSize: LongInt; var ID: DWORD): Boolean;
 var
   find_id: DWORD;
+  fmt:     Word;
 begin
  Result := False;
 
  find_id := FindTexture;
 
- if not LoadTextureMem(pData, e_Textures[find_id].ID, e_Textures[find_id].Width,
-                   e_Textures[find_id].Height) then Exit;
+ if not LoadTextureMem(pData, dataSize, e_Textures[find_id].tx, e_Textures[find_id].tx.Width, e_Textures[find_id].tx.Height, @fmt) then exit;
 
  id := find_id;
 
  Result := True;
 end;
 
-function e_CreateTextureMemEx(pData: Pointer; var ID: DWORD; fX, fY, fWidth, fHeight: Word): Boolean;
+function e_CreateTextureMemEx(pData: Pointer; dataSize: LongInt; var ID: DWORD; fX, fY, fWidth, fHeight: Word): Boolean;
 var
   find_id: DWORD;
+  fmt:     Word;
 begin
  Result := False;
 
  find_id := FindTexture();
 
- if not LoadTextureMemEx(pData, e_Textures[find_id].ID, fX, fY, fWidth, fHeight) then Exit;
-
- e_Textures[find_id].Width := fWidth;
- e_Textures[find_id].Height := fHeight;
+ if not LoadTextureMemEx(pData, dataSize, e_Textures[find_id].tx, fX, fY, fWidth, fHeight, @fmt) then exit;
 
  ID := find_id;
 
  Result := True;
 end;
 
+function e_CreateTextureImg (var img: TImageData; var ID: DWORD): Boolean;
+var
+  find_id: DWORD;
+  fmt, tw, th: Word;
+begin
+  result := false;
+  find_id := FindTexture();
+  if not LoadTextureImg(img, e_Textures[find_id].tx, tw, th, @fmt) then exit;
+  ID := find_id;
+  result := True;
+end;
+
 procedure e_GetTextureSize(ID: DWORD; Width, Height: PWord);
 begin
- if Width <> nil then Width^ := e_Textures[ID].Width;
- if Height <> nil then Height^ := e_Textures[ID].Height;
+ if Width <> nil then Width^ := e_Textures[ID].tx.Width;
+ if Height <> nil then Height^ := e_Textures[ID].tx.Height;
 end;
 
 function e_GetTextureSize2(ID: DWORD): TRectWH;
 var
-  data: Pointer;
+  data: PChar;
   x, y: Integer;
   w, h: Word;
   a: Boolean;
   lastline: Integer;
 begin
- w := e_Textures[ID].Width;
- h := e_Textures[ID].Height;
- data := GetMemory(w*h*4);
- glEnable(GL_TEXTURE_2D);
- glBindTexture(GL_TEXTURE_2D, e_Textures[ID].ID);
- glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
+ w := e_Textures[ID].tx.Width;
+ h := e_Textures[ID].tx.Height;
 
  Result.Y := 0;
  Result.X := 0;
  Result.Width := w;
  Result.Height := h;
 
+ if e_NoGraphics then Exit;
+
+ data := GetMemory(w*h*4);
+ glEnable(GL_TEXTURE_2D);
+ glBindTexture(GL_TEXTURE_2D, e_Textures[ID].tx.id);
+ glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
+
  for y := h-1 downto 0 do
  begin
   lastline := y;
@@ -336,7 +383,7 @@ begin
 
   for x := 1 to w-4 do
   begin
-   a := Byte(Pointer(Integer(data)+y*w*4+x*4+3)^) <> 0;
+   a := Byte((data+y*w*4+x*4+3)^) <> 0;
    if a then Break;
   end;
 
@@ -354,7 +401,7 @@ begin
 
   for x := 1 to w-4 do
   begin
-   a := Byte(Pointer(Integer(data)+y*w*4+x*4+3)^) <> 0;
+   a := Byte((data+y*w*4+x*4+3)^) <> 0;
    if a then Break;
   end;
 
@@ -372,7 +419,7 @@ begin
 
   for y := 1 to h-4 do
   begin
-   a := Byte(Pointer(Integer(data)+y*w*4+x*4+3)^) <> 0;
+   a := Byte((data+y*w*4+x*4+3)^) <> 0;
    if a then Break;
   end;
 
@@ -390,7 +437,7 @@ begin
 
   for y := 1 to h-4 do
   begin
-   a := Byte(Pointer(Integer(data)+y*w*4+x*4+3)^) <> 0;
+   a := Byte((data+y*w*4+x*4+3)^) <> 0;
    if a then Break;
   end;
 
@@ -411,11 +458,27 @@ begin
   e_SetViewPort(0, 0, Width, Height);
 end;
 
+procedure drawTxQuad (x0, y0, w, h: Integer; u, v: single; Mirror: TMirrorType);
+var
+  x1, y1, tmp: Integer;
+begin
+  if (w < 1) or (h < 1) then exit;
+  x1 := x0+w;
+  y1 := y0+h;
+       if Mirror = M_HORIZONTAL then begin tmp := x1; x1 := x0; x0 := tmp; end
+  else if Mirror = M_VERTICAL then begin tmp := y1; y1 := y0; y0 := tmp; end;
+  glTexCoord2f(0, v); glVertex2i(x0, y0);
+  glTexCoord2f(0, 0); glVertex2i(x0, y1);
+  glTexCoord2f(u, 0); glVertex2i(x1, y1);
+  glTexCoord2f(u, v); glVertex2i(x1, y0);
+end;
+
 procedure e_Draw(ID: DWORD; X, Y: Integer; Alpha: Byte; AlphaChannel: Boolean;
                  Blending: Boolean; Mirror: TMirrorType = M_NONE);
-begin  
+begin
+  if e_NoGraphics then Exit;
   glColor4ub(e_Colors.R, e_Colors.G, e_Colors.B, 255);
-     
+
   if (Alpha > 0) or (AlphaChannel) or (Blending) then
     glEnable(GL_BLEND)
   else
@@ -431,32 +494,39 @@ begin
     glBlendFunc(GL_SRC_ALPHA, GL_ONE);
 
   glEnable(GL_TEXTURE_2D);
-  glBindTexture(GL_TEXTURE_2D, e_Textures[ID].ID);
+  glBindTexture(GL_TEXTURE_2D, e_Textures[ID].tx.id);
   glBegin(GL_QUADS);
 
+  drawTxQuad(X, Y, e_Textures[id].tx.width, e_Textures[id].tx.height, e_Textures[ID].tx.u, e_Textures[ID].tx.v, Mirror);
+
+  //u := e_Textures[ID].tx.u;
+  //v := e_Textures[ID].tx.v;
+
+  {
   if Mirror = M_NONE then
     begin
-      glTexCoord2i(1,  0); glVertex2i(X + e_Textures[id].Width, Y);
-      glTexCoord2i(0,  0); glVertex2i(X,                        Y);
-      glTexCoord2i(0, -1); glVertex2i(X,                        Y + e_Textures[id].Height);
-      glTexCoord2i(1, -1); glVertex2i(X + e_Textures[id].Width, Y + e_Textures[id].Height);
+      glTexCoord2f(u,  0); glVertex2i(X + e_Textures[id].tx.Width, Y);
+      glTexCoord2f(0,  0); glVertex2i(X,                        Y);
+      glTexCoord2f(0, -v); glVertex2i(X,                        Y + e_Textures[id].tx.Height);
+      glTexCoord2f(u, -v); glVertex2i(X + e_Textures[id].tx.Width, Y + e_Textures[id].tx.Height);
     end
   else
     if Mirror = M_HORIZONTAL then
       begin
-        glTexCoord2i(1,  0); glVertex2i(X,                        Y);
-        glTexCoord2i(0,  0); glVertex2i(X + e_Textures[id].Width, Y);
-        glTexCoord2i(0, -1); glVertex2i(X + e_Textures[id].Width, Y + e_Textures[id].Height);
-        glTexCoord2i(1, -1); glVertex2i(X,                        Y + e_Textures[id].Height);
+        glTexCoord2f(u,  0); glVertex2i(X,                        Y);
+        glTexCoord2f(0,  0); glVertex2i(X + e_Textures[id].tx.Width, Y);
+        glTexCoord2f(0, -v); glVertex2i(X + e_Textures[id].tx.Width, Y + e_Textures[id].tx.Height);
+        glTexCoord2f(u, -v); glVertex2i(X,                        Y + e_Textures[id].tx.Height);
       end
     else
       if Mirror = M_VERTICAL then
       begin
-        glTexCoord2i(1, -1); glVertex2i(X + e_Textures[id].Width, Y);
-        glTexCoord2i(0, -1); glVertex2i(X,                        Y);
-        glTexCoord2i(0,  0); glVertex2i(X,                        Y + e_Textures[id].Height);
-        glTexCoord2i(1,  0); glVertex2i(X + e_Textures[id].Width, Y + e_Textures[id].Height);
+        glTexCoord2f(u, -v); glVertex2i(X + e_Textures[id].tx.Width, Y);
+        glTexCoord2f(0, -v); glVertex2i(X,                        Y);
+        glTexCoord2f(0,  0); glVertex2i(X,                        Y + e_Textures[id].tx.Height);
+        glTexCoord2f(u,  0); glVertex2i(X + e_Textures[id].tx.Width, Y + e_Textures[id].tx.Height);
       end;
+  }
 
   glEnd();
 
@@ -465,7 +535,10 @@ end;
 
 procedure e_DrawSize(ID: DWORD; X, Y: Integer; Alpha: Byte; AlphaChannel: Boolean;
                      Blending: Boolean; Width, Height: Word; Mirror: TMirrorType = M_NONE);
+var
+  u, v: Single;
 begin
+  if e_NoGraphics then Exit;
   glColor4ub(e_Colors.R, e_Colors.G, e_Colors.B, 255);
 
   if (Alpha > 0) or (AlphaChannel) or (Blending) then
@@ -483,13 +556,16 @@ begin
     glBlendFunc(GL_SRC_ALPHA, GL_ONE);
 
   glEnable(GL_TEXTURE_2D);
-  glBindTexture(GL_TEXTURE_2D, e_Textures[ID].ID);
+  glBindTexture(GL_TEXTURE_2D, e_Textures[ID].tx.id);
+
+  u := e_Textures[ID].tx.u;
+  v := e_Textures[ID].tx.v;
 
   glBegin(GL_QUADS);
-    glTexCoord2i(0, 1); glVertex2i(X,         Y);
-    glTexCoord2i(1, 1); glVertex2i(X + Width, Y);
-    glTexCoord2i(1, 0); glVertex2i(X + Width, Y + Height);
-    glTexCoord2i(0, 0); glVertex2i(X,         Y + Height);
+    glTexCoord2f(0, v); glVertex2i(X,         Y);
+    glTexCoord2f(u, v); glVertex2i(X + Width, Y);
+    glTexCoord2f(u, 0); glVertex2i(X + Width, Y + Height);
+    glTexCoord2f(0, 0); glVertex2i(X,         Y + Height);
   glEnd();
 
   glDisable(GL_BLEND);
@@ -498,6 +574,7 @@ end;
 procedure e_DrawSizeMirror(ID: DWORD; X, Y: Integer; Alpha: Byte; AlphaChannel: Boolean;
                            Blending: Boolean; Width, Height: Word; Mirror: TMirrorType = M_NONE);
 begin
+  if e_NoGraphics then Exit;
   glColor4ub(e_Colors.R, e_Colors.G, e_Colors.B, 255);
 
   if (Alpha > 0) or (AlphaChannel) or (Blending) then
@@ -515,33 +592,9 @@ begin
     glBlendFunc(GL_SRC_ALPHA, GL_ONE);
 
   glEnable(GL_TEXTURE_2D);
-  glBindTexture(GL_TEXTURE_2D, e_Textures[ID].ID);
+  glBindTexture(GL_TEXTURE_2D, e_Textures[ID].tx.id);
   glBegin(GL_QUADS);
-
-  if Mirror = M_NONE then
-    begin
-      glTexCoord2i(1,  0); glVertex2i(X + Width, Y);
-      glTexCoord2i(0,  0); glVertex2i(X,         Y);
-      glTexCoord2i(0, -1); glVertex2i(X,         Y + Height);
-      glTexCoord2i(1, -1); glVertex2i(X + Width, Y + Height);
-    end
-  else
-    if Mirror = M_HORIZONTAL then
-      begin
-        glTexCoord2i(1,  0); glVertex2i(X,         Y);
-        glTexCoord2i(0,  0); glVertex2i(X + Width, Y);
-        glTexCoord2i(0, -1); glVertex2i(X + Width, Y + Height);
-        glTexCoord2i(1, -1); glVertex2i(X,         Y + Height);
-      end
-    else
-      if Mirror = M_VERTICAL then
-      begin
-        glTexCoord2i(1, -1); glVertex2i(X + Width, Y);
-        glTexCoord2i(0, -1); glVertex2i(X,         Y);
-        glTexCoord2i(0,  0); glVertex2i(X,         Y + Height);
-        glTexCoord2i(1,  0); glVertex2i(X + Width, Y + Height);
-      end;
-
+  drawTxQuad(X, Y, Width, Height, e_Textures[ID].tx.u, e_Textures[ID].tx.v, Mirror);
   glEnd();
 
   glDisable(GL_BLEND);
@@ -550,9 +603,10 @@ end;
 procedure e_DrawFill(ID: DWORD; X, Y: Integer; XCount, YCount: Word; Alpha: Integer;
                      AlphaChannel: Boolean; Blending: Boolean);
 var
-  X2, Y2: Integer;
-  
+  X2, Y2, dx, w, h: Integer;
+  u, v: Single;
 begin
+  if e_NoGraphics then Exit;
   glColor4ub(e_Colors.R, e_Colors.G, e_Colors.B, 255);
 
   if (Alpha > 0) or (AlphaChannel) or (Blending) then
@@ -576,31 +630,64 @@ begin
     YCount := 1;
 
   glEnable(GL_TEXTURE_2D);
-  glBindTexture(GL_TEXTURE_2D, e_Textures[ID].ID);
+  glBindTexture(GL_TEXTURE_2D, e_Textures[ID].tx.id);
 
-  X2 := X + e_Textures[ID].Width * XCount;
-  Y2 := Y + e_Textures[ID].Height * YCount;
-  glBegin(GL_QUADS);
-    glTexCoord2i(0,      YCount); glVertex2i(X,  Y);
-    glTexCoord2i(XCount, YCount); glVertex2i(X2, Y);
-    glTexCoord2i(XCount, 0);      glVertex2i(X2, Y2);
-    glTexCoord2i(0,      0);      glVertex2i(X,  Y2);
-  glEnd();
+  X2 := X + e_Textures[ID].tx.width * XCount;
+  Y2 := Y + e_Textures[ID].tx.height * YCount;
+
+  //k8: this SHOULD work... i hope
+  if (e_Textures[ID].tx.width = e_Textures[ID].tx.glwidth) and (e_Textures[ID].tx.height = e_Textures[ID].tx.glheight) then
+  begin
+    glBegin(GL_QUADS);
+      glTexCoord2i(0,      YCount); glVertex2i(X,  Y);
+      glTexCoord2i(XCount, YCount); glVertex2i(X2, Y);
+      glTexCoord2i(XCount, 0);      glVertex2i(X2, Y2);
+      glTexCoord2i(0,      0);      glVertex2i(X,  Y2);
+    glEnd();
+  end
+  else
+  begin
+    glBegin(GL_QUADS);
+    // hard day's night
+    u := e_Textures[ID].tx.u;
+    v := e_Textures[ID].tx.v;
+    w := e_Textures[ID].tx.width;
+    h := e_Textures[ID].tx.height;
+    while YCount > 0 do
+    begin
+      dx := XCount;
+      x2 := X;
+      while dx > 0 do
+      begin
+        glTexCoord2f(0, v); glVertex2i(X,  Y);
+        glTexCoord2f(u, v); glVertex2i(X+w, Y);
+        glTexCoord2f(u, 0); glVertex2i(X+w, Y+h);
+        glTexCoord2f(0, 0); glVertex2i(X,  Y+h);
+        Inc(X, w);
+        Dec(dx);
+      end;
+      X := x2;
+      Inc(Y, h);
+      Dec(YCount);
+    end;
+    glEnd();
+  end;
 
   glDisable(GL_BLEND);
 end;
 
 procedure e_DrawAdv(ID: DWORD; X, Y: Integer; Alpha: Byte; AlphaChannel: Boolean;
                     Blending: Boolean; Angle: Single; RC: PPoint; Mirror: TMirrorType = M_NONE);
-begin  
+begin
+  if e_NoGraphics then Exit;
+
   glColor4ub(e_Colors.R, e_Colors.G, e_Colors.B, 255);
 
   if (Alpha > 0) or (AlphaChannel) or (Blending) then
     glEnable(GL_BLEND)
   else
     glDisable(GL_BLEND);
-      
+
   if (AlphaChannel) or (Alpha > 0) then
     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 
@@ -619,33 +706,10 @@ begin
   end;
 
   glEnable(GL_TEXTURE_2D);
-  glBindTexture(GL_TEXTURE_2D, e_Textures[id].ID);
+  glBindTexture(GL_TEXTURE_2D, e_Textures[id].tx.id);
   glBegin(GL_QUADS);                           //0-1        1-1
                                                //00         10
-  if Mirror = M_NONE then
-    begin
-      glTexCoord2i(1,  0); glVertex2i(X + e_Textures[id].Width, Y);
-      glTexCoord2i(0,  0); glVertex2i(X,                        Y);
-      glTexCoord2i(0, -1); glVertex2i(X,                        Y + e_Textures[id].Height);
-      glTexCoord2i(1, -1); glVertex2i(X + e_Textures[id].Width, Y + e_Textures[id].Height);
-    end
-  else
-    if Mirror = M_HORIZONTAL then
-      begin
-        glTexCoord2i(1,  0); glVertex2i(X,                        Y);
-        glTexCoord2i(0,  0); glVertex2i(X + e_Textures[id].Width, Y);
-        glTexCoord2i(0, -1); glVertex2i(X + e_Textures[id].Width, Y + e_Textures[id].Height);
-        glTexCoord2i(1, -1); glVertex2i(X,                        Y + e_Textures[id].Height);
-      end
-    else
-      if Mirror = M_VERTICAL then
-      begin
-        glTexCoord2i(1, -1); glVertex2i(X + e_Textures[id].Width, Y);
-        glTexCoord2i(0, -1); glVertex2i(X,                        Y);
-        glTexCoord2i(0,  0); glVertex2i(X,                        Y + e_Textures[id].Height);
-        glTexCoord2i(1,  0); glVertex2i(X + e_Textures[id].Width, Y + e_Textures[id].Height);
-      end;
-
+  drawTxQuad(X, Y, e_Textures[id].tx.width, e_Textures[id].tx.height, e_Textures[ID].tx.u, e_Textures[ID].tx.v, Mirror);
   glEnd();
 
   if Angle <> 0 then
@@ -656,10 +720,11 @@ end;
 
 procedure e_DrawPoint(Size: Byte; X, Y: Integer; Red, Green, Blue: Byte);
 begin
+  if e_NoGraphics then Exit;
   glDisable(GL_TEXTURE_2D);
   glColor3ub(Red, Green, Blue);
   glPointSize(Size);
-  
+
   if (Size = 2) or (Size = 4) then
     X := X + 1;
 
@@ -670,45 +735,9 @@ begin
   glColor4ub(e_Colors.R, e_Colors.G, e_Colors.B, 255);
 end;
 
-procedure e_LineCorrection(var X1, Y1, X2, Y2: Integer);
-begin
-  // Make lines only top-left/bottom-right and top-right/bottom-left
-  if Y2 < Y1 then
-  begin
-    X1 := X1 xor X2;
-    X2 := X1 xor X2;
-    X1 := X1 xor X2;
-
-    Y1 := Y1 xor Y2;
-    Y2 := Y1 xor Y2;
-    Y1 := Y1 xor Y2;
-  end;
-
-  // Pixel-perfect hack
-  if X1 < X2 then
-    Inc(X2)
-  else
-    Inc(X1);
-  Inc(Y2);
-end;
-
 procedure e_DrawQuad(X1, Y1, X2, Y2: Integer; Red, Green, Blue: Byte; Alpha: Byte = 0);
-var
-  nX1, nY1, nX2, nY2: Integer;
 begin
-  // Only top-left/bottom-right quad
-  if X1 > X2 then
-  begin
-    X1 := X1 xor X2;
-    X2 := X1 xor X2;
-    X1 := X1 xor X2;
-  end;
-  if Y1 > Y2 then
-  begin
-    Y1 := Y1 xor Y2;
-    Y2 := Y1 xor Y2;
-    Y1 := Y1 xor Y2;
-  end;
+  if e_NoGraphics then Exit;
 
   if Alpha > 0 then
   begin
@@ -721,30 +750,11 @@ begin
   glColor4ub(Red, Green, Blue, 255-Alpha);
   glLineWidth(1);
 
-  glBegin(GL_LINES);
-    nX1 := X1; nY1 := Y1;
-    nX2 := X2; nY2 := Y1;
-    e_LineCorrection(nX1, nY1, nX2, nY2); // Pixel-perfect lines
-    glVertex2i(nX1, nY1);
-    glVertex2i(nX2, nY2);
-
-    nX1 := X2; nY1 := Y1;
-    nX2 := X2; nY2 := Y2;
-    e_LineCorrection(nX1, nY1, nX2, nY2);
-    glVertex2i(nX1, nY1);
-    glVertex2i(nX2, nY2);
-
-    nX1 := X2; nY1 := Y2;
-    nX2 := X1; nY2 := Y2;
-    e_LineCorrection(nX1, nY1, nX2, nY2);
-    glVertex2i(nX1, nY1);
-    glVertex2i(nX2, nY2);
-
-    nX1 := X1; nY1 := Y2;
-    nX2 := X1; nY2 := Y1;
-    e_LineCorrection(nX1, nY1, nX2, nY2);
-    glVertex2i(nX1, nY1);
-    glVertex2i(nX2, nY2);
+  glBegin(GL_LINE_LOOP);
+    glVertex2f(X1 + 0.5, Y1 + 0.5);
+    glVertex2f(X2 + 0.5, Y1 + 0.5);
+    glVertex2f(X2 + 0.5, Y2 + 0.5);
+    glVertex2f(X1 + 0.5, Y2 + 0.5);
   glEnd();
 
   glColor4ub(e_Colors.R, e_Colors.G, e_Colors.B, 255);
@@ -755,6 +765,7 @@ end;
 procedure e_DrawFillQuad(X1, Y1, X2, Y2: Integer; Red, Green, Blue, Alpha: Byte;
                          Blending: TBlending = B_NONE);
 begin
+  if e_NoGraphics then Exit;
   if (Alpha > 0) or (Blending <> B_NONE) then
     glEnable(GL_BLEND)
   else
@@ -792,9 +803,10 @@ end;
 
 procedure e_DrawLine(Width: Byte; X1, Y1, X2, Y2: Integer; Red, Green, Blue: Byte; Alpha: Byte = 0);
 begin
+  if e_NoGraphics then Exit;
   // Pixel-perfect lines
-  if Width = 1 then
-    e_LineCorrection(X1, Y1, X2, Y2);
+  //if Width = 1 then
+  //  e_LineCorrection(X1, Y1, X2, Y2);
 
   if Alpha > 0 then
   begin
@@ -822,10 +834,11 @@ end;
 //------------------------------------------------------------------
 procedure e_DeleteTexture(ID: DWORD);
 begin
-  glDeleteTextures(1, @e_Textures[ID].ID);
-  e_Textures[ID].ID := 0;
-  e_Textures[ID].Width := 0;
-  e_Textures[ID].Height := 0;
+  if not e_NoGraphics then
+    glDeleteTextures(1, @e_Textures[ID].tx.id);
+  e_Textures[ID].tx.id := 0;
+  e_Textures[ID].tx.Width := 0;
+  e_Textures[ID].tx.Height := 0;
 end;
 
 //------------------------------------------------------------------
@@ -838,7 +851,7 @@ begin
  if e_Textures = nil then Exit;
 
  for i := 0 to High(e_Textures) do
-  if e_Textures[i].Width <> 0 then e_DeleteTexture(i);
+  if e_Textures[i].tx.Width <> 0 then e_DeleteTexture(i);
  e_Textures := nil;
 end;
 
@@ -853,196 +866,29 @@ end;
 
 procedure e_BeginRender();
 begin
+  if e_NoGraphics then Exit;
   glEnable(GL_ALPHA_TEST);
   glAlphaFunc(GL_GREATER, 0.0);
 end;
 
-procedure e_Clear(Mask: TGLbitfield; Red, Green, Blue: Single);
-begin
- glClearColor(Red, Green, Blue, 0);
- glClear(Mask);
-end;
-
-procedure e_EndRender();
-begin
-  glPopMatrix();
-end;
-
-procedure e_MakeScreenshot(FileName: String; Width, Height: Word);
-type
-  aRGB  = Array [0..1] of TRGB;
-  PaRGB = ^aRGB;
-
-  TByteArray = Array [0..1] of Byte;
-  PByteArray = ^TByteArray;
-
-var
-  FILEHEADER: BITMAPFILEHEADER;
-  INFOHEADER: BITMAPINFOHEADER;
-  pixels: PByteArray;
-  tmp:    Byte;
-  i:      Integer;
-  F:      File of Byte;
-
-begin
-  if (Width mod 4) > 0 then
-    Width := Width + 4 - (Width mod 4);
-
-  GetMem(pixels, Width*Height*3);
-  glReadPixels(0, 0, Width, Height, GL_RGB, GL_UNSIGNED_BYTE, pixels);
-
-  {$R-}
-  for i := 0 to Width * Height - 1 do
-    with PaRGB(pixels)[i] do
-    begin
-      tmp := R;
-      R := B;
-      B := tmp;
-    end;
-  {$R+}
-
-  with FILEHEADER do
-  begin
-    bfType := $4D42; // "BM"
-    bfSize := Width*Height*3 + SizeOf(BITMAPFILEHEADER) + SizeOf(BITMAPINFOHEADER);
-    bfReserved1 := 0;
-    bfReserved2 := 0;
-    bfOffBits := SizeOf(BITMAPFILEHEADER) + SizeOf(BITMAPINFOHEADER);
-  end;
-
-  with INFOHEADER do
-  begin
-    biSize := SizeOf(BITMAPINFOHEADER);
-    biWidth := Width;
-    biHeight := Height;
-    biPlanes := 1;
-    biBitCount := 24;
-    biCompression := 0;
-    biSizeImage := Width*Height*3;
-    biXPelsPerMeter := 0;
-    biYPelsPerMeter := 0;
-    biClrUsed := 0;
-    biClrImportant := 0;
-  end;
-
-  AssignFile(F, FileName);
-  Rewrite(F);
-
-  BlockWrite(F, FILEHEADER, SizeOf(FILEHEADER));
-  BlockWrite(F, INFOHEADER, SizeOf(INFOHEADER));
-  BlockWrite(F, pixels[0], Width*Height*3);
-
-  CloseFile(F);
-
-  FreeMem(pixels);
-end;
-
-function e_GetGamma(DC: HDC): Byte;
-var
-  ramp: array [0..256*3-1] of Word;
-  rgb: array [0..2] of Double;
-  sum: double;
-  count: integer;
-  min: integer;
-  max: integer;
-  A, B: double;
-  i, j: integer;
-begin
- rgb[0] := 1.0;
- rgb[1] := 1.0;
- rgb[2] := 1.0;
-
- GetDeviceGammaRamp(DC, ramp);
-
- for i := 0 to 2 do
- begin
-  sum := 0;
-  count := 0;
-  min := 256 * i;
-  max := min + 256;
-
-  for j := min to max - 1 do
-  if ramp[j] > 0 then
-  begin
-   B := (j mod 256)/256;
-   A := ramp[j]/65536;
-   sum := sum + ln(A)/ln(B);
-   inc(count);
-  end;
-  rgb[i] := sum / count;
- end;
-
- Result := 100 - Trunc(((rgb[0] + rgb[1] + rgb[2])/3 - 0.23) * 100/(2.7 - 0.23));
-end;
-
-procedure e_SetGamma(Gamma: Byte; DC: HDC);
-var
-  ramp: array [0..256*3-1] of Word;
-  i: integer;
-  r: double;
-  g: double;
-begin
- g := (100 - Gamma)*(2.7 - 0.23)/100 + 0.23;
-
- for i := 0 to 255 do
- begin
-  r := Exp(g * ln(i/256))*65536;
-  if r < 0 then r := 0
-   else if r > 65535 then r := 65535;
-  ramp[i] := trunc(r);
-  ramp[i + 256] := trunc(r);
-  ramp[i + 512] := trunc(r);
- end;
-
- SetDeviceGammaRamp(DC, ramp);
-end;
-
-function e_SimpleFontCreate(FontName: PChar; Size: Byte; Weight: Word; DC: HDC): DWORD;
-var
- font: HFONT;
-begin
- Result := glGenLists(96);                           // Generate enough display lists to hold
- font := CreateFont(-Size,                             // height of font
-                    0,                             // average character width
-                    0,                             // angle of escapement
-                               0,                             // base-line orientation angle
-                               Weight,                       // font weight
-                    0,                             // italic
-                               0,                             // underline
-                               0,                                  // strikeout
-                               RUSSIAN_CHARSET,               // character set
-                               OUT_TT_PRECIS,              // output precision
-                    CLIP_DEFAULT_PRECIS,           // clipping precision
-                    ANTIALIASED_QUALITY,           // output quality
-                               FF_DONTCARE or DEFAULT_PITCH,  // pitch and family
-                               FontName);                      // font
- SelectObject(DC, font);                   // Sets the new font as the current font in the device context
- wglUseFontBitmaps(DC, 32, 224, Result); // Creates a set display lists containing the bitmap fonts
-end;
-
-procedure e_SimpleFontFree(Font: DWORD);
+procedure e_Clear(Mask: TGLbitfield; Red, Green, Blue: Single); overload;
 begin
- glDeleteLists(Font, 223);             // Delete the font display lists, returning used memory
+  if e_NoGraphics then Exit;
+  glClearColor(Red, Green, Blue, 0);
+  glClear(Mask);
 end;
 
-procedure e_SimpleFontPrint(X, Y: SmallInt; Text: PChar; Font: Integer; Red, Green, Blue: Byte);
+procedure e_Clear(); overload;
 begin
- glPopAttrib(); // Rendering bug workaround
-
- glColor3ub(Red, Green, Blue);
- glDisable(GL_TEXTURE_2D);     // Turn off textures, don't want our text textured
- glRasterPos2i(X, Y);                                // Position the Text
- glPushAttrib(GL_LIST_BIT);                          // Save's the current base list
-  glListBase(DWORD(Font-32));                              // Set the base list to our character list
-  glCallLists(Length(Text), GL_UNSIGNED_BYTE, Text);  // Display the text
- glPopAttrib();                                     // Restore the old base list
+  if e_NoGraphics then Exit;
+  glClearColor(0, 0, 0, 0);
+  glClear(GL_COLOR_BUFFER_BIT);
 end;
 
-procedure e_SimpleFontPrintEx(X, Y: SmallInt; Text: PChar; Font: DWORD; Red, Green, Blue,
-                      sRed, sGreen, sBlue, sWidth: Byte);
+procedure e_EndRender();
 begin
e_SimpleFontPrint(X, Y, Text, Font, Red, Green, Blue);
e_SimpleFontPrint(X+sWidth, Y+sWidth, Text, Font, sRed, sGreen, sBlue);
 if e_NoGraphics then Exit;
 glPopMatrix();
 end;
 
 function e_CharFont_Create(sp: ShortInt=0): DWORD;
@@ -1096,6 +942,7 @@ procedure e_CharFont_Print(FontID: DWORD; X, Y: Integer; Text: string);
 var
   a: Integer;
 begin
+ if e_NoGraphics then Exit;
  if Text = '' then Exit;
  if e_CharFonts = nil then Exit;
  if Integer(FontID) > High(e_CharFonts) then Exit;
@@ -1118,6 +965,7 @@ var
   a: Integer;
   c: TRGB;
 begin
+ if e_NoGraphics then Exit;
  if Text = '' then Exit;
  if e_CharFonts = nil then Exit;
  if Integer(FontID) > High(e_CharFonts) then Exit;
@@ -1152,6 +1000,7 @@ var
   tc, c: TRGB;
   w, h: Word;
 begin
+  if e_NoGraphics then Exit;
   if Text = '' then Exit;
   if e_CharFonts = nil then Exit;
   if Integer(FontID) > High(e_CharFonts) then Exit;
@@ -1356,18 +1205,19 @@ begin
  if e_CharFonts = nil then Exit;
 
  for a := 0 to High(e_CharFonts) do
-  e_CharFont_Remove(a); 
+  e_CharFont_Remove(a);
 
  e_CharFonts := nil;
 end;
 
-procedure e_TextureFontBuild(Texture: DWORD; var FontID: DWORD; XCount, YCount: Word;
+procedure e_TextureFontBuild(Tex: DWORD; var FontID: DWORD; XCount, YCount: Word;
                              Space: ShortInt=0);
 var
   loop1 : GLuint;
   cx, cy : real;
   i, id: DWORD;
 begin
+ if e_NoGraphics then Exit;
  e_WriteLog('Creating texture font...', MSG_NOTIFY);
 
  id := DWORD(-1);
@@ -1389,33 +1239,37 @@ begin
  with e_TextureFonts[id] do
  begin
   Base := glGenLists(XCount*YCount);
-  TextureID := e_Textures[Texture].ID;
-  CharWidth := (e_Textures[Texture].Width div XCount)+Space;
-  CharHeight := e_Textures[Texture].Height div YCount;
+  TextureID := e_Textures[Tex].tx.id;
+  CharWidth := (e_Textures[Tex].tx.Width div XCount)+Space;
+  CharHeight := e_Textures[Tex].tx.Height div YCount;
+  XC := XCount;
+  YC := YCount;
+  Texture := Tex;
+  SPC := Space;
  end;
- glBindTexture(GL_TEXTURE_2D, e_Textures[Texture].ID);
+
+ glBindTexture(GL_TEXTURE_2D, e_Textures[Tex].tx.id);
  for loop1 := 0 to XCount*YCount-1 do
  begin
   cx := (loop1 mod XCount)/XCount;
-       cy := (loop1 div YCount)/YCount;
+  cy := (loop1 div YCount)/YCount;
 
-       glNewList(e_TextureFonts[id].Base+loop1, GL_COMPILE);
-        glBegin(GL_QUADS);
+  glNewList(e_TextureFonts[id].Base+loop1, GL_COMPILE);
+   glBegin(GL_QUADS);
     glTexCoord2f(cx, 1.0-cy-1/YCount);
-    glVertex2d(0, e_Textures[Texture].Height div YCount);
+    glVertex2d(0, e_Textures[Tex].tx.Height div YCount);
 
-         glTexCoord2f(cx+1/XCount, 1.0-cy-1/YCount);
-    glVertex2i(e_Textures[Texture].Width div XCount, e_Textures[Texture].Height div YCount);
+    glTexCoord2f(cx+1/XCount, 1.0-cy-1/YCount);
+    glVertex2i(e_Textures[Tex].tx.Width div XCount, e_Textures[Tex].tx.Height div YCount);
 
-               glTexCoord2f(cx+1/XCount, 1.0-cy);
-    glVertex2i(e_Textures[Texture].Width div XCount, 0);
+    glTexCoord2f(cx+1/XCount, 1.0-cy);
+    glVertex2i(e_Textures[Tex].tx.Width div XCount, 0);
 
-               glTexCoord2f(cx, 1.0-cy);
+    glTexCoord2f(cx, 1.0-cy);
     glVertex2i(0, 0);
    glEnd();
-        glTranslated((e_Textures[Texture].Width div XCount)+Space, 0, 0);
-       glEndList();
+   glTranslated((e_Textures[Tex].tx.Width div XCount)+Space, 0, 0);
+  glEndList();
  end;
 
  FontID := id;
@@ -1423,12 +1277,14 @@ end;
 
 procedure e_TextureFontKill(FontID: DWORD);
 begin
-       glDeleteLists(e_TextureFonts[FontID].Base, 256);
+  if e_NoGraphics then Exit;
+  glDeleteLists(e_TextureFonts[FontID].Base, 256);
   e_TextureFonts[FontID].Base := 0;
 end;
 
 procedure e_TextureFontPrint(X, Y: GLint; Text: string; FontID: DWORD);
 begin
+  if e_NoGraphics then Exit;
   if Integer(FontID) > High(e_TextureFonts) then Exit;
   if Text = '' then Exit;
 
@@ -1452,6 +1308,7 @@ end;
 // god forgive me for this, but i cannot figure out how to do it without lists
 procedure e_TextureFontPrintChar(X, Y: Integer; Ch: Char; FontID: DWORD; Shadow: Boolean = False);
 begin
+  if e_NoGraphics then Exit;
   glPushMatrix;
 
   if Shadow then
@@ -1470,12 +1327,31 @@ begin
   glPopMatrix;
 end;
 
+procedure e_TextureFontPrintCharEx (X, Y: Integer; Ch: Char; FontID: DWORD; Shadow: Boolean = False);
+begin
+  glBindTexture(GL_TEXTURE_2D, e_TextureFonts[FontID].TextureID);
+  glEnable(GL_TEXTURE_2D);
+  //glListBase(DWORD(Integer(e_TextureFonts[FontID].Base)-32));
+
+  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+  glEnable(GL_BLEND);
+  e_TextureFontPrintChar(X, Y, Ch, FontID, Shadow);
+  glDisable(GL_TEXTURE_2D);
+  glDisable(GL_BLEND);
+end;
+
+function e_TextureFontCharWidth (ch: Char; FontID: DWORD): Integer;
+begin
+  result := e_TextureFonts[FontID].CharWidth;
+end;
+
 procedure e_TextureFontPrintFmt(X, Y: Integer; Text: string; FontID: DWORD; Shadow: Boolean = False);
 var
   a, TX, TY, len: Integer;
   tc, c: TRGB;
   w: Word;
 begin
+  if e_NoGraphics then Exit;
   if Text = '' then Exit;
   if e_TextureFonts = nil then Exit;
   if Integer(FontID) > High(e_TextureFonts) then Exit;
@@ -1565,6 +1441,7 @@ end;
 procedure e_TextureFontPrintEx(X, Y: GLint; Text: string; FontID: DWORD; Red, Green,
                     Blue: Byte; Scale: Single; Shadow: Boolean = False);
 begin
+  if e_NoGraphics then Exit;
   if Text = '' then Exit;
 
   glPushMatrix;
@@ -1598,6 +1475,9 @@ end;
 
 procedure e_TextureFontGetSize(ID: DWORD; var CharWidth, CharHeight: Byte);
 begin
+  CharWidth := 16;
+  CharHeight := 16;
+  if e_NoGraphics then Exit;
   if Integer(ID) > High(e_TextureFonts) then
     Exit;
   CharWidth := e_TextureFonts[ID].CharWidth;
@@ -1608,6 +1488,7 @@ procedure e_RemoveAllTextureFont();
 var
  i: integer;
 begin
+ if e_NoGraphics then Exit;
  if e_TextureFonts = nil then Exit;
 
  for i := 0 to High(e_TextureFonts) do
@@ -1641,6 +1522,12 @@ begin
  Result.Height := Height;
 end;
 
+function _TRect(L, T, R, B: LongInt): TRect;
+begin
+ Result.Top := T;
+ Result.Left := L;
+ Result.Right := R;
+ Result.Bottom := B;
+end;
 
 end.
-