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

CrystalShire Bubble Chat on EO 2.0


Mondo
 Share

Recommended Posts

Hello,

UPDATE: JULY 8th, 2012… If you already applied this tutorial and you're having centering text issues you MIGHT want to review it and apply it again, I've modified the tutorial to get rid of some old deprecated functions in favor for something better.

However if you're already satisfied with what you have then by all means leave it AS IS.

This is my first tutorial so I urge you to bear with me. 

I never found a Chat Bubble tutorial and found no information on how to build one except for a quick suggestion from Robin on how to make it work and some comments regarding this already being available on CrystalShire.

So I went and hacked my way through CrystalShire to get one for my game… And now that I got it I thought I'd be able to give a little helping hand back to the EO community, from whom I've learned a lot, by sharing what I learned.

As always, credits for this superb piece of software engineering go to Robin Perris, author of EO and CrystalShire where I grabbed the Bubble Chat code from, and Debbie The Fabulous for her 7's Upgraded Minimap Tutorial  (http://www.touchofdeathforums.com/smf/index.php/topic,75443.0.html) from where I learned how to work the Direct Draw Surfaces.

On that note I invite you to review as many tutorials as you can and try not just to copy/paste what you see in them. Go a step further and try to understand what the code actually does in hope that you can understand how pieces work, and how they'd behave if you combine them differently.

In the end you'll get something like this...

![](http://www.touchofdeathforums.com/smf/index.php?action=dlattach;topic=79790.0;attach=20955;image)

**Disclaimer: Please keep in mind this is a crude implementation and it needs major tweaking, I'm sharing it in hope that it will help anyone who is looking for simple the Bubble Chats to build from.**

What you'll need:

VB6 Enterprise Edition
EO 2.0 Source Code _**with the Font Memory Leak fix ALREADY applied ( http://www.touchofdeathforums.com/smf/index.php/topic,71691.0.html) if you haven't applied it then DO SO before you begin with this.**_
Debugging skills (yep, you'll need to know how to set a breakpoint and understand errors).
Tons of patience.

So lets get messy…

**SERVER SIDE**

**STEP 1\. On modEnumerations modify the ServerPackets**

Find:

```
    ' Make sure SMSG_COUNT is below everything else
    SMSG_COUNT

```
Add the following code ABOVE that:

```
    ' CHAT BUBBLE HACK
    SChatBubble
    ' CHAT BUBBLE HACK

```
**STEP 2\. On ModHandleData Edit HandleSayMsg Sub**

Find the following code at the end of the subroutine:

```
Set Buffer = Nothing

```
Add the following code ABOVE that.

```
    ' CHAT BUBBLE HACK
    Call SendChatBubble(GetPlayerMap(index), index, TARGET_TYPE_PLAYER, Msg, White)
    ' CHAT BUBBLE HACK

```
**STEP 3\. On modServerTCP add Sub SendChatBubble anywhere in the module.**

```
' CHAT BUBBLE HACK
Sub SendChatBubble(ByVal mapNum As Long, ByVal target As Long, ByVal targetType As Long, ByVal message As String, ByVal Colour As Long)
Dim Buffer As clsBuffer

    Set Buffer = New clsBuffer
    Buffer.WriteLong SChatBubble
    Buffer.WriteLong target
    Buffer.WriteLong targetType
    Buffer.WriteString message
    Buffer.WriteLong Colour
    SendDataToMap mapNum, Buffer.ToArray()
    Set Buffer = Nothing
End Sub
' CHAT BUBBLE HACK

```
And thats it on this end.

**CLIENT SIDE**

MOST IMPORTANT Download the attached file "chatbubble.bmp" to your folder /data files/graphics

**STEP 1\. On modEnumerations modify the ServerPackets**

Find:

```
    ' Make sure SMSG_COUNT is below everything else
    SMSG_COUNT

```
Add the following code ABOVE that:

```
    ' CHAT BUBBLE HACK
    SChatBubble
    ' CHAT BUBBLE HACK

```
**STEP 2\. on modHandleData add the following code on the InitMessages**

Find:

```
    ' Error handler
    Exit Sub

```
Add the following code ABOVE that.

```
    ' CHAT BUBBLE HACK
    HandleDataSub(SChatBubble) = GetAddress(AddressOf HandleChatBubble)
    ' CHAT BUBBLE HACK

```
**STEP 3\. On modHandleData add the following subroutine anywhere in the module.**

```
' CHAT BUBBLE HACK
Private Sub HandleChatBubble(ByVal Index As Long, ByRef Data() As Byte, ByVal StartAddr As Long, ByVal ExtraVar As Long)
Dim Buffer As clsBuffer, targetType As Long, target As Long, message As String, colour As Long

    Set Buffer = New clsBuffer
    Buffer.WriteBytes Data()

    target = Buffer.ReadLong
    targetType = Buffer.ReadLong
    message = Buffer.ReadString
    colour = Buffer.ReadLong

    AddChatBubble target, targetType, message, colour
    Set Buffer = Nothing
End Sub
' CHAT BUBBLE HACK

```
**STEP 4\. On modTEXT add the following sub at the bottom of the module**

```
' BUBBLE CHAT HACK
Public Sub WordWrap_Array(ByVal text As String, ByVal MaxLineLen As Long, ByRef theArray() As String)
Dim lineCount As Long, i As Long, size As Long, lastSpace As Long, b As Long

    'Too small of text
    If Len(text) < 2 Then
        ReDim theArray(1 To 1) As String
        theArray(1) = text
        Exit Sub
    End If

    ' default values
    b = 1
    lastSpace = 1
    size = 0

    For i = 1 To Len(text)
        ' if it's a space, store it
        Select Case Mid$(text, i, 1)
            Case " ": lastSpace = i
            Case "_": lastSpace = i
            Case "-": lastSpace = i
        End Select

        'Add up the size
        size = size + getWidth(TexthDC, Mid$(Text, i, 1))

        'Check for too large of a size
        If size > MaxLineLen Then
            'Check if the last space was too far back
            If i - lastSpace > 12 Then
                'Too far away to the last space, so break at the last character
                lineCount = lineCount + 1
                ReDim Preserve theArray(1 To lineCount) As String
                theArray(lineCount) = Trim$(Mid$(text, b, (i - 1) - b))
                b = i - 1
                size = 0
            Else
                'Break at the last space to preserve the word
                lineCount = lineCount + 1
                ReDim Preserve theArray(1 To lineCount) As String
                theArray(lineCount) = Trim$(Mid$(text, b, lastSpace - b))
                b = lastSpace + 1

                'Count all the words we ignored (the ones that weren't printed, but are before "i")
                size = getWidth(TexthDC, Mid$(text, lastSpace, i - lastSpace))
            End If
        End If

        ' Remainder
        If i = Len(text) Then
            If b <> i Then
                lineCount = lineCount + 1
                ReDim Preserve theArray(1 To lineCount) As String
                theArray(lineCount) = theArray(lineCount) & Mid$(text, b, i)
            End If
        End If
    Next
End Sub

Public Function WordWrap(ByVal text As String, ByVal MaxLineLen As Integer) As String
Dim TempSplit() As String
Dim TSLoop As Long
Dim lastSpace As Long
Dim size As Long
Dim i As Long
Dim b As Long

    'Too small of text
    If Len(text) < 2 Then
        WordWrap = text
        Exit Function
    End If

    'Check if there are any line breaks - if so, we will support them
    TempSplit = Split(text, vbNewLine)

    For TSLoop = 0 To UBound(TempSplit)

        'Clear the values for the new line
        size = 0
        b = 1
        lastSpace = 1

        'Add back in the vbNewLines
        If TSLoop < UBound(TempSplit()) Then TempSplit(TSLoop) = TempSplit(TSLoop) & vbNewLine

        'Only check lines with a space
        If InStr(1, TempSplit(TSLoop), " ") Or InStr(1, TempSplit(TSLoop), "-") Or InStr(1, TempSplit(TSLoop), "_") Then

            'Loop through all the characters
            For i = 1 To Len(TempSplit(TSLoop))

                'If it is a space, store it so we can easily break at it
                Select Case Mid$(TempSplit(TSLoop), i, 1)
                    Case " ": lastSpace = i
                    Case "_": lastSpace = i
                    Case "-": lastSpace = i
                End Select

                'Add up the size
                size = size + getwidth(TexthDC, Mid$(TempSplit(TSLoop), i, 1)))

                'Check for too large of a size
                If size > MaxLineLen Then
                    'Check if the last space was too far back
                    If i - lastSpace > 12 Then
                        'Too far away to the last space, so break at the last character
                        WordWrap = WordWrap & Trim$(Mid$(TempSplit(TSLoop), b, (i - 1) - b)) & vbNewLine
                        b = i - 1
                        size = 0
                    Else
                        'Break at the last space to preserve the word
                        WordWrap = WordWrap & Trim$(Mid$(TempSplit(TSLoop), b, lastSpace - b)) & vbNewLine
                        b = lastSpace + 1

                        'Count all the words we ignored (the ones that weren't printed, but are before "i")
                        size = getwidth(TexthDC, Mid$(TempSplit(TSLoop), lastSpace, i - lastSpace))
                    End If
                End If

                'This handles the remainder
                If i = Len(TempSplit(TSLoop)) Then
                    If b <> i Then
                        WordWrap = WordWrap & Mid$(TempSplit(TSLoop), b, i)
                    End If
                End If
            Next i
        Else
            WordWrap = WordWrap & TempSplit(TSLoop)
        End If
    Next TSLoop
End Function

Public Function getWidth(ByVal DC As Long, ByVal text As String) As Long
    ' If debug mode, handle error then exit out
    If Options.Debug = 1 Then On Error GoTo errorhandler

    getWidth = frmMain.TextWidth(text) \ 2

    ' Error handler
    Exit Function
errorhandler:
    HandleError "getWidth", "modText", Err.Number, Err.Description, Err.Source, Err.HelpContext
    Err.Clear
    Exit Function
End Function

' CHANGE FONT FIX
' PLEASE NOTE THIS WILL FAIL MISERABLY IF YOU DIDN'T APPLY THE FONT MEMORY LEAK FIX FIRST
' CHAT BUBBLE HACK
' I ONLY DID THIS COZ THE CHATBUBBLE TEXT LOOKS BETTER WITHOUT SHADOW OVER WHITE BUBBLES!
Public Sub DrawTextNoShadow(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, color)
    Call TextOut(hdc, x, y, text, Len(text))
    Call SelectObject(hdc, OldFont)
    Call DeleteObject(GameFont)

    ' Error handler
    Exit Sub
errorhandler:
    HandleError "DrawTextNoShadow", "modText", Err.Number, Err.Description, Err.Source, Err.HelpContext
    Err.Clear
    Exit Sub
End Sub
' CHAT BUBBLE HACK
' CHANGE FONT FIX

```
**STEP 5\. On modTypes add the following type anywhere**

```
' CHAT BUBBLE HACK
Public Type ChatBubbleRec
    Msg As String
    colour As Long
    target As Long
    targetType As Byte
    timer As Long
    active As Boolean
End Type
' CHAT BUBBLE HACK

```
**Step 6\. On modGameLogic add this subroutine anywhere in the module**

```
' CHAT BUBBLE HACK
Public Sub AddChatBubble(ByVal target As Long, ByVal targetType As Byte, ByVal Msg As String, ByVal colour As Long)
Dim i As Long, Index As Long

    ' set the global index
    chatBubbleIndex = chatBubbleIndex + 1
    If chatBubbleIndex < 1 Or chatBubbleIndex > MAX_BYTE Then chatBubbleIndex = 1

    ' default to new bubble
    Index = chatBubbleIndex

    ' loop through and see if that player/npc already has a chat bubble
    For i = 1 To MAX_BYTE
        If chatBubble(i).targetType = targetType Then
            If chatBubble(i).target = target Then
                ' reset master index
                If chatBubbleIndex > 1 Then chatBubbleIndex = chatBubbleIndex - 1
                ' we use this one now, yes?
                Index = i
                Exit For
            End If
        End If
    Next

    ' set the bubble up
    With chatBubble(Index)
        .target = target
        .targetType = targetType
        .Msg = Msg
        .colour = colour
        .timer = GetTickCount
        .active = True
    End With
End Sub
' CHAT BUBBLE HACK

```
**STEP 7\. On modConstants add the following constant anywhere in the module.**

```
' CHAT BUBBLE HACK
Public Const ChatBubbleWidth As Long = 200
Public Const Font_Default As String = "Default"
' CHAT BUBBLE HACK

```
**STEP 8\. On modGlobals add the following global variables anywhere in the module.**

```
' chat bubble hack
Public chatBubble(1 To MAX_BYTE) As ChatBubbleRec
Public chatBubbleIndex As Long
' chat bubble hack

```
**STEP 9\. On modDirectDraw7 add the following variables on the declarations section (anywhere on top  of the module).**

```
' CHAT BUBBLE HACK
Public DDS_ChatBubble As DirectDrawSurface7
Public DDSD_ChatBubble As DDSURFACEDESC2
' CHAT BUBBLE HACK

```
**STEP 10\. On modDirectDraw7 add the following code in the InitSurfaces subroutine.**

Find:

```
    ' count the blood sprites
    BloodCount = DDSD_Blood.lWidth / 32

```
Add this code ABOVE that.

```
    ' CHAT BUBBLE HACK
    If FileExist(App.Path & "\data files\graphics\chatbubble.bmp", True) Then Call InitDDSurf("chatbubble", DDSD_ChatBubble, DDS_ChatBubble)
    ' CHAT BUBBLE HACK

```
**STEP 11\. On modDirectDraw7 add the following code to the DestroyDirectDraw subroutine.**

Find:

```
    Set DDS_BackBuffer = Nothing

```
Add the following code ABOVE that.

```
    ' CHAT BUBBLE HACK
    Set DDS_ChatBubble = Nothing
    ZeroMemory ByVal VarPtr(DDSD_ChatBubble), LenB(DDSD_ChatBubble)
    ' CHAT BUBBLE HACK

```
**STEP 12\. on modDirectDraw7 add the following code on the Render_Graphics subroutine**

Find:

```
    ' Release DC
    DDS_BackBuffer.ReleaseDC TexthDC

```
Add the following code BELOW that:

```
    ' CHAT BUBBLES HACK
    ' draw the messages at the very top!
    For i = 1 To MAX_BYTE
        If chatBubble(i).active Then
            DrawChatBubble i
        End If
    Next
    ' CHAT BUBBLES HACK

```
**STEP 13\. On modDirectDraw7 add the following subroutine anywhere in the module.**

```
' CHAT BUBBLE HACK
Public Sub DrawChatBubble(ByVal Index As Long)
Dim theArray() As String, x As Long, Y As Long, i As Long, MaxWidth As Long, xwidth As Long, yheight As Long, colour As Long, x3 As Long, y3 As Long

Dim MMx As Long
Dim MMy As Long

Dim TOPLEFTrect As RECT
Dim TOPCENTERrect As RECT
Dim TOPRIGHTrect As RECT
Dim MIDDLELEFTrect As RECT
Dim MIDDLECENTERrect As RECT
Dim MIDDLERIGHTrect As RECT
Dim BOTTOMLEFTrect As RECT
Dim BOTTOMCENTERrect As RECT
Dim BOTTOMRIGHTrect As RECT
Dim TIPrect As RECT

' DESIGNATE CHATBUBBLE SECTIONS FROM CHATBUBBLE IMAGE
With TOPRIGHTrect
    .top = 0
    .Bottom = .top + 4
    .Left = 0
    .Right = .Left + 4
End With

With TOPCENTERrect
    .top = 0
    .Bottom = .top + 4
    .Left = 4
    .Right = .Left + 4
End With

With TOPLEFTrect
    .top = 0
    .Bottom = .top + 4
    .Left = 8
    .Right = .Left + 4
End With

With MIDDLERIGHTrect
    .top = 4
    .Bottom = .top + 4
    .Left = 0
    .Right = .Left + 4
End With

With MIDDLECENTERrect
    .top = 4
    .Bottom = .top + 4
    .Left = 4
    .Right = .Left + 4
End With

With MIDDLELEFTrect
    .top = 4
    .Bottom = .top + 4
    .Left = 8
    .Right = .Left + 4
End With

With BOTTOMRIGHTrect
    .top = 8
    .Bottom = .top + 4
    .Left = 0
    .Right = .Left + 4
End With

With BOTTOMCENTERrect
    .top = 8
    .Bottom = .top + 4
    .Left = 4
    .Right = .Left + 4
End With

With BOTTOMLEFTrect
    .top = 8
    .Bottom = .top + 4
    .Left = 8
    .Right = .Left + 4
End With

With TIPrect
    .top = 12
    .Bottom = .top + 4
    .Left = 0
    .Right = .Left + 4
End With

    Call DDS_BackBuffer.SetForeColor(RGB(255, 255, 255))

    With chatBubble(Index)
        If .targetType = TARGET_TYPE_PLAYER Then
            ' it's a player
            If GetPlayerMap(.target) = GetPlayerMap(MyIndex) Then
                ' change the colour depending on access
                colour = QBColor(Yellow)

                ' it's on our map - get co-ords
                x = ConvertMapX((Player(.target).x * 32) + Player(.target).XOffset) + 16
                Y = ConvertMapY((Player(.target).Y * 32) + Player(.target).YOffset) - 16

                ' word wrap the text
                WordWrap_Array .Msg, ChatBubbleWidth, theArray

                ' find max width
                For i = 1 To UBound(theArray)
                    If getWidth(TexthDC, theArray(i)) > MaxWidth Then MaxWidth = getWidth(TexthDC, theArray(i))
                Next

                ' calculate the new position xwidth relative to DDS_ChatBubble and yheight relative to DDS_ChatBubble
                xwidth = 10 + MaxWidth ' the first five is just air.
                yheight = 3 + (UBound(theArray) * 7) ' the first three are just air.

                ' Compensate the yheight drift
                Y = Y - yheight

                ' render bubble

                ' top left
                ' RenderTexture Tex_GUI(37), xwidth - 9, yheight - 5, 0, 0, 9, 5, 9, 5
                Call Engine_BltFast(x + (xwidth + 4), Y - (yheight - 4), DDS_ChatBubble, TOPLEFTrect, DDBLTFAST_WAIT Or DDBLTFAST_SRCCOLORKEY)

                ' top center
                ' RenderTexture Tex_GUI(37), xwidth + MaxWidth, yheight - 5, 119, 0, 9, 5, 9, 5
                For x3 = x - (xwidth - 8) To x + (xwidth)
                    Call Engine_BltFast(x3, Y - (yheight - 4), DDS_ChatBubble, TOPCENTERrect, DDBLTFAST_WAIT Or DDBLTFAST_SRCCOLORKEY)
                Next x3

                ' top right
                ' RenderTexture Tex_GUI(37), xwidth, yheight - 5, 9, 0, MaxWidth, 5, 5, 5
                Call Engine_BltFast(x - (xwidth - 4), Y - (yheight - 4), DDS_ChatBubble, TOPRIGHTrect, DDBLTFAST_WAIT Or DDBLTFAST_SRCCOLORKEY)

                ' middle left
                ' RenderTexture Tex_GUI(37), xwidth - 9, y, 0, 19, 9, 6, 9, 6
                For y3 = Y - (yheight - 8) To Y + (yheight)
                    Call Engine_BltFast(x + (xwidth + 4), y3, DDS_ChatBubble, MIDDLELEFTrect, DDBLTFAST_WAIT Or DDBLTFAST_SRCCOLORKEY)
                Next y3

                ' middle center
                ' RenderTexture Tex_GUI(37), xwidth + MaxWidth, y, 119, 19, 9, 6, 9, 6
                For y3 = Y - (yheight - 8) To Y + (yheight)
                    For x3 = x - (xwidth - 8) To x + (xwidth)
                        Call Engine_BltFast(x3, y3, DDS_ChatBubble, MIDDLECENTERrect, DDBLTFAST_WAIT Or DDBLTFAST_SRCCOLORKEY)
                    Next x3
                Next y3

                ' middle right
                ' RenderTexture Tex_GUI(37), xwidth, y, 9, 19, (MaxWidth \ 2) - 5, 6, 9, 6
                For y3 = Y - (yheight - 8) To Y + (yheight)
                    Call Engine_BltFast(x - (xwidth - 4), y3, DDS_ChatBubble, MIDDLERIGHTrect, DDBLTFAST_WAIT Or DDBLTFAST_SRCCOLORKEY)
                Next y3

                ' bottom left
                ' RenderTexture Tex_GUI(37), xwidth + (MaxWidth \ 2) + 6, y, 9, 19, (MaxWidth \ 2) - 5, 6, 9, 6
                Call Engine_BltFast(x + (xwidth + 4), Y + (yheight + 4), DDS_ChatBubble, BOTTOMLEFTrect, DDBLTFAST_WAIT Or DDBLTFAST_SRCCOLORKEY)

                ' bottom center
                ' RenderTexture Tex_GUI(37), xwidth - 9, yheight, 0, 6, 9, (UBound(theArray) * 12), 9, 1
                For x3 = x - (xwidth - 8) To x + (xwidth)
                    Call Engine_BltFast(x3, Y + (yheight + 4), DDS_ChatBubble, BOTTOMCENTERrect, DDBLTFAST_WAIT Or DDBLTFAST_SRCCOLORKEY)
                Next x3

                ' bottom right
                ' RenderTexture Tex_GUI(37), xwidth + MaxWidth, yheight, 119, 6, 9, (UBound(theArray) * 12), 9, 1
                Call Engine_BltFast(x - (xwidth - 4), Y + (yheight + 4), DDS_ChatBubble, BOTTOMRIGHTrect, DDBLTFAST_WAIT Or DDBLTFAST_SRCCOLORKEY)

                ' little pointy bit
                ' RenderTexture Tex_GUI(37), x - 5, y, 58, 19, 11, 11, 11, 11
                Call Engine_BltFast(x, Y + (yheight + 8), DDS_ChatBubble, TIPrect, DDBLTFAST_WAIT Or DDBLTFAST_SRCCOLORKEY)

                ' Lock the backbuffer so we can draw text and names
                TexthDC = DDS_BackBuffer.GetDC

                ' render each line centralised
                Y = Y - (yheight - 5)
                For i = 1 To UBound(theArray)
                    DrawTextNoShadow TexthDC, x - (getWidth(TexthDC, theArray(i)) - 10), Y, theArray(i), QBColor(Black) ' .colour
                    Y = Y + 12
                Next

                ' Release DC
                DDS_BackBuffer.ReleaseDC TexthDC

            End If
        End If

        ' check if it's timed out - close it if so
        If .Timer + 5000 < GetTickCount Then
            .active = False
        End If
    End With
End Sub
' CHAT BUBBLE HACK

```
And we're done!

_**WARNING: I ADDED A DRAWTEXTNOSHADOW FUNCTION ~~COZ~~ BECAUSE THE CHATBUBBLE TEXT LOOKS BETTER WITHOUT SHADOW OVER WHITE BUBBLES! IF YOU HAVE NOT APPLIED THE  FONT MEMORY LEAK FIX YOU'LL NEED TO DO SO OTHERWISE THIS ROUTINE WILL FAIL!**_

The How's and Why's…

On the server side we did the following create a new package so we can send it to the client whenever we'll fire a message from a user into the map (handled by HandleSayMsg subroutine), and the function that sends this package and the message to the client.

On the client side we created a new package so we can understand the server, created a Direct Draw Surface named BubbleChat where we'll do the drawing and texting.

Added a couple constants so we know the chat bubble size and for compatibility with a function that expects a font name.

Added a Chat bubble rec type, where we store message, player that owns it, color, etc.

Added a function that handles the reception of the bubble chat package.

Added a routine to add a new bubble if it does not exist or recycle an old bubble.

Modified the rendering routine to add for the call to the chatboxes if they're active

Added a function to split the length of the message to fit in 200 pixels which we said it was our biggest chat bubble.

~~This one deserves extra attention, since I didn't know how replicate the EngineGetTextWidth function on DD7 (yet!) the Word Wrapper routines would not work. So I build a routine named LetterWidth and this routine will provide an "estimate" pixel size per character (by default I set it to 4 pixels per letter) for characters that are "slim" like ": | ' , . : ;" etc… the bubble size is not 100% accurate, so you might want to build a better map of character sizes for it to be more precise...~~

Added the getWidth function, which uses the textwidth function on the main form to calculate the size of the text, and then just splits that value in half to get a center, I believe you can actually tweak it to be more precise if you specify the form font to match the font you'll be using in your chatbubbles, but I leave that to you.

Then added a draw the chat bubbles function that takes a tile, chops it in to 10 pieces each comprising a a side of the bubble, the center and the little tip of it. Each section of the chat bubble is a 4x4 pixel piece, you may modify this by changing the size and then the respective RECTs and recalculate your positions accordingly.

And finally added a function that draws text without a shadow so that black text won't look funky with black shadow.

And thats it!

If you have any questions I'll be happy to try and respond them (provided you give me enough information and not just say "it does not work for me"), and if you run into some problems I'll do my best to assist, but **be reminded this tutorial is delivered AS-IS… it might not work for you, but if you tweak it enough it just might.**

Cheers!
Link to comment
Share on other sites

  • Replies 108
  • Created
  • Last Reply

Top Posters In This Topic

@Justn:

> Very cool mondo.. does this work/look any better with text rendering memory leak fix?

Well it should work with any DrawText function you provide… You only need to change the DrawTextNoShadow with in the DrawChatBubble function with whatever you use to draw text now...

I didn't know there was a text rendering memory leak fix!
Link to comment
Share on other sites

@Justn:

> K gonna play around with it later thanks for sharing
>
> This is what I was asking about http://www.touchofdeathforums.com/smf/index.php/topic,71691.0.html

Awesome! Now I can use a different font! :D

I tested it the Chat Bubbles with the Font Fix and it works ok, however you'll need to modify the DrawTextNoShadow. Copy the Memory Leak Free DrawText function in it, and then remove the shadow effect again.
Link to comment
Share on other sites

@Mondo:

> My bad, thank you!

No problem!
Very nice tutorial, by the way, this should help a lot of people as it appears to be a rather common request.

Warning - while you were typing a new reply has been posted. You may wish to review your post.

@Erwin:

> Very nice, lots of people were complaining about this, good job releasing this tutorial. ;)

Pretty much this.
Link to comment
Share on other sites

http://echostorms.net/Mirage/MS%20Tutorials/Temporary%20Archive%20(Read%20Only)/Speech%20Bubble.html

That's a 6 year old tutorial for speech bubbles :P. Anyway, your way of doing it (or I guess robin's) is way way better than what the tut I linked suggests, nice first tutorial.
Link to comment
Share on other sites

> WARNING: I ADDED A DRAWTEXTNOSHADOW FUNCTION COZ THE CHATBUBBLE TEXT LOOKS BETTER WITHOUT SHADOW OVER WHITE BUBBLES! IF YOU ALREADY APPLIED THE  FONT MEMORY LEAK FIX YOU'LL NEED TO FIX THIS FUNCTION TOO… OTHERWISE IT WILL LEAK!

First its Cause and second shouldn't you automatically add the fix for the leak to the tutorial instead of forcing people to add it?
Link to comment
Share on other sites

@crzy:

> First its Cause and second shouldn't you automatically add the fix for the leak to the tutorial instead of forcing people to add it?

First thank you for correcting my grammar the last thing I want is to confuse someone with my poor spelling.

Second, no I won't do a tutorial of something that's already been explained elsewhere. However I will fix my noshadow routine to include the fix and indicate that its a prerequisite for this tutorial that you MUST have the Font Memory Leak fix in place in order for this to work.

Thank you for your input.
Link to comment
Share on other sites

@Erwin:

> This still doesn't work perfect, I get Sub or Function not Defined at:
> ```
> Call DeleteObject(GameFont)
> ```

This requires that your EO 2.0 be loaded with the the Font Memory Leak fix ALREADY applied ( http://www.touchofdeathforums.com/smf/index.php/topic,71691.0.html) if you haven't applied the FIX then DO SO before you begin with this.

The Font Memory Leak Fix has that declaration:

```
Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
```
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...