Jump to content
Search In
  • More options...
Find results that contain...
Find results in...

[EO] Memory Leak-free Text Rendering


Yxxe
 Share

Recommended Posts

Over the last few months a few users on here have been wondering how to change the font in EO v2\. All that's come back from those thread has been Robin replying "You can't" down to the memory leak in the text rendering. Here is the fix, so you can use other fonts without the memory leak.

Everything is done client-side, of course.

First, go to modText. At the top you will see five function declarations. Underneath the last one, paste this:

```
Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
```
Now we want to go to the "SetFont" procedure, just underneath that. Remove it, and replace it with this:

```
' Used to set a font for GDI text drawing
Public Sub SetFont(ByVal Font As String, ByVal Size As Byte)
    ' If debug mode, handle error then exit out
    If Options.Debug = 1 Then On Error GoTo errorhandler

    GameFont = CreateFont(Size, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "Georgia")
    frmMain.Font = "Georgia"
    frmMain.FontSize = Size - 5

    ' Error handler
    Exit Sub
errorhandler:
    HandleError "SetFont", "modText", Err.Number, Err.Description, Err.Source, Err.HelpContext
    Err.Clear
    Exit Sub
End Sub
```
Replace both copies of "Georgia" with whatever font you like.

Lastly, we want to go to the "DrawText" procedure, underneath the "SetFont" procedure. Remove it, and add this instead:

```
' GDI text drawing onto buffer
Public Sub DrawText(ByVal hdc As Long, ByVal x, ByVal y, ByVal text As String, Color As Long)
    ' If debug mode, handle error then exit out
    Dim OldFont As Long ' HFONT

    If Options.Debug = 1 Then On Error GoTo errorhandler

    Call SetFont(FONT_NAME, FONT_SIZE)
    OldFont = SelectObject(hdc, GameFont)
    Call SetBkMode(hdc, vbTransparent)
    Call SetTextColor(hdc, 0)
    Call TextOut(hdc, x + 1, y + 1, text, Len(text))
    Call SetTextColor(hdc, Color)
    Call TextOut(hdc, x, y, text, Len(text))
    Call SelectObject(hdc, OldFont)
    Call DeleteObject(GameFont)

    ' Error handler
    Exit Sub
errorhandler:
    HandleError "DrawText", "modText", Err.Number, Err.Description, Err.Source, Err.HelpContext
    Err.Clear
    Exit Sub
End Sub
```
Now, the font is declared every time it is drawn, and removed once the drawing of the text has stopped. It is removed by the line "Call DeleteObject(GameFont)". This way the object is removed every time, stopping the memory leak. You could also get rid of the useless "Font" parameter in SetFont.

Credit goes to myself (Lightning), Stephan for fixing up my DrawText procedure and GPWiki for the function declaration.

Best of luck,

Lightning
Link to comment
Share on other sites

You are still not using GDI correctly. Here's an example in C to point out what I mean:

```
// Mysterious allocation of objNew here.
objOld = SelectObject(objContext, objNew);

// ...

SelectObject(objContext, objOld);
DeleteObject(objNew);
```

Regards,
  Stephan.
Link to comment
Share on other sites

@S.J.R.:

> You are still not using GDI correctly. Here's an example in C to point out what I mean:
>
> ```
> // Mysterious allocation of objNew here.
> objOld = SelectObject(objContext, objNew);
>
> // ...
>
> SelectObject(objContext, objOld);
> DeleteObject(objNew);
> ```
>
> Regards,
>   Stephan.

```
' GDI text drawing onto buffer
Public Sub DrawText(ByVal hdc As Long, ByVal x, ByVal y, ByVal text As String, Color As Long)
    ' If debug mode, handle error then exit out
    Dim objNew As Long

    If Options.Debug = 1 Then On Error GoTo errorhandler

    Call SetFont(FONT_NAME, FONT_SIZE)
    objNew = SelectObject(hdc, GameFont)
    Call SetBkMode(hdc, vbTransparent)
    Call SetTextColor(hdc, 0)
    Call TextOut(hdc, x + 1, y + 1, text, Len(text))
    Call SetTextColor(hdc, Color)
    Call TextOut(hdc, x, y, text, Len(text))
    Call DeleteObject(objNew)

    ' Error handler
    Exit Sub
errorhandler:
    HandleError "DrawText", "modText", Err.Number, Err.Description, Err.Source, Err.HelpContext
    Err.Clear
    Exit Sub
End Sub
```
Link to comment
Share on other sites

@Lightning:

> - snip -

More like:
```
' GDI text drawing onto buffer
Public Sub DrawText(ByVal hdc As Long, ByVal x, ByVal y, ByVal text As String, Color As Long)
    ' If debug mode, handle error then exit out
    Dim OldFont As Long ' HFONT

    If Options.Debug = 1 Then On Error GoTo errorhandler

    Call SetFont(FONT_NAME, FONT_SIZE)
    OldFont = SelectObject(hdc, GameFont)
    Call SetBkMode(hdc, vbTransparent)
    Call SetTextColor(hdc, 0)
    Call TextOut(hdc, x + 1, y + 1, text, Len(text))
    Call SetTextColor(hdc, Color)
    Call TextOut(hdc, x, y, text, Len(text))
    Call SelectObject(hdc, OldFont)
    Call DeleteObject(GameFont)

    ' Error handler
    Exit Sub
errorhandler:
    HandleError "DrawText", "modText", Err.Number, Err.Description, Err.Source, Err.HelpContext
    Err.Clear
    Exit Sub
End Sub
```

Regards,
  Stephan.
Link to comment
Share on other sites

@Apple:

> The name is not aligned properly,is there a fix?

Aligned in what sense? Horizontal left, centre and right; vertical top, centre, bottom?

If you need that functionality, then I recommend you to use [DrawText](http://msdn.microsoft.com/en-us/library/dd162498%28v=VS.85%29.aspx) or [DrawTextEx](http://msdn.microsoft.com/en-us/library/dd162499%28v=VS.85%29.aspx).

If you meant that the names that are being rendered, aren't properly rendered at the top of the player, then that has to do with the calculations used for calculating the coordinates (since it probably uses the incorrect individual glyph width), in which case you still want to use [DrawText](http://msdn.microsoft.com/en-us/library/dd162498%28v=VS.85%29.aspx) or [DrawTextEx](http://msdn.microsoft.com/en-us/library/dd162499%28v=VS.85%29.aspx) (basically you tell GDI to draw the text in a rectangle, with a specific format (alignment, word wrapping, etc.).

Regards,
  Stephan.
Link to comment
Share on other sites

I fell on to this thru lightning's sig and i cant help but wonder what this is for?
I changed my game font to Virdana by simply setting the font to virdana in the frmmain and other frm i wanted and then i went to modConstant (client side) and found:
```
' Font variables
Public Const FONT_NAME As String = "Verdana" '<-- perviously Georgia
Public Const FONT_SIZE As Byte = 14
```Am i going to experience "memory leak"? my game seems to work fine tho?
Link to comment
Share on other sites

The font system was removed from the latest version due to a memory leak.

If that actually worked then you're using an old version. Either that or you're too dense to notice that the font used isn't Georgia.
Link to comment
Share on other sites

> Over the last few months a few users on here have been wondering how to change the font in EO v2.

I have EO 2 (the latest version i think. downloaded it like 2 weeks ago) but the guy wrote EOv2 so i thought the memory leak was also in my current version. But i guess mine has the fix already.
Link to comment
Share on other sites

@Greendude120:

> but the guy wrote EOv2 so i thought the memory leak was also in my current version. But i guess mine has the fix already.

If it's EOv2 then the memory leak was fixed by _removing the ability to change the font._
Link to comment
Share on other sites

@Robin:

> If it's EOv2 then the memory leak was fixed by _removing the ability to change the font._

And then re-fixed in the first post, if you hadn't realised. It just lets people change their font without needing to worry about memory leaks. ;]
Link to comment
Share on other sites

@Lightning:

> And then re-fixed in the first post, if you hadn't realised. It just lets people change their font without needing to worry about memory leaks. ;]

Yes, I'm just flabbergasted by the amount of people who claim that I didn't remove the ability to change fonts.

@QWERTYUIoP:

> -snip-

**I KNOW HOW MY OWN CODE WORKS. I REMOVED THE ABILITY TO CHANGE THE FONT BECAUSE IT CAUSED A MEMORY LEAK DUE TO THE WAY THE OBJECT WORKED. WHATEVER SEKARU TOLD YOU TO DO DOES NOT 'FIX' THE LEAK, IT SIMPLY REVERSES THE CHANGES I DID TO STOP THE LEAK.**

I've said this so many times now that it's depressing. I'm also sick and tired of you constantly claiming that you know my own source code better than I do. Jesus fucking Christ.
Link to comment
Share on other sites

@Robin:

> **I KNOW HOW MY OWN CODE WORKS.
> I never said you didn't. Hence why I said "_to anybody else who wants to know_"
>
> > I REMOVED THE ABILITY TO CHANGE THE FONT BECAUSE IT CAUSED A MEMORY LEAK DUE TO THE WAY THE OBJECT WORKED.
>
> Well, I dunno what you're screaming at me for, but seeing as you removed it, how was I able to change it?
>
> > WHATEVER SEKARU TOLD YOU TO DO DOES NOT 'FIX' THE LEAK, IT SIMPLY REVERSES THE CHANGES I DID TO STOP THE LEAK.
>
> I never said it fixed anything. All I said was that it would change the font.
>
> > I've said this so many times now that it's depressing. I'm also sick and tired of you constantly claiming that you know my own source code better than I do.
>
> I've never directly claimed that I know your source better than you. If I've ever said anything that implied it, well, I didn't mean it that way, but please, calm down!**
Link to comment
Share on other sites

Robin removed the code that changes the font. All you're fucking doing is readding that code. Robin cannot completely remove the feature because it is coded into GDI.

Readding the exact code does nothing to solve the memory leak. Although, the code in this topic is not the same code.
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...