Mondo Posted April 29, 2012 Author Share Posted April 29, 2012 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 EditionEO 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 HACKSub 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 = NothingEnd 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 HACKPrivate 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 = NothingEnd Sub' CHAT BUBBLE HACK```**STEP 4\. On modTEXT add the following sub at the bottom of the module**```' BUBBLE CHAT HACKPublic 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 NextEnd SubPublic Function WordWrap(ByVal text As String, ByVal MaxLineLen As Integer) As StringDim TempSplit() As StringDim TSLoop As LongDim lastSpace As LongDim size As LongDim i As LongDim 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 TSLoopEnd FunctionPublic 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 Functionerrorhandler: HandleError "getWidth", "modText", Err.Number, Err.Description, Err.Source, Err.HelpContext Err.Clear Exit FunctionEnd 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 Suberrorhandler: HandleError "DrawTextNoShadow", "modText", Err.Number, Err.Description, Err.Source, Err.HelpContext Err.Clear Exit SubEnd Sub' CHAT BUBBLE HACK' CHANGE FONT FIX```**STEP 5\. On modTypes add the following type anywhere**```' CHAT BUBBLE HACKPublic Type ChatBubbleRec Msg As String colour As Long target As Long targetType As Byte timer As Long active As BooleanEnd Type' CHAT BUBBLE HACK```**Step 6\. On modGameLogic add this subroutine anywhere in the module**```' CHAT BUBBLE HACKPublic 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 WithEnd Sub' CHAT BUBBLE HACK```**STEP 7\. On modConstants add the following constant anywhere in the module.**```' CHAT BUBBLE HACKPublic Const ChatBubbleWidth As Long = 200Public Const Font_Default As String = "Default"' CHAT BUBBLE HACK```**STEP 8\. On modGlobals add the following global variables anywhere in the module.**```' chat bubble hackPublic chatBubble(1 To MAX_BYTE) As ChatBubbleRecPublic 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 HACKPublic DDS_ChatBubble As DirectDrawSurface7Public 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 HACKPublic 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 LongDim MMx As LongDim MMy As LongDim TOPLEFTrect As RECTDim TOPCENTERrect As RECTDim TOPRIGHTrect As RECTDim MIDDLELEFTrect As RECTDim MIDDLECENTERrect As RECTDim MIDDLERIGHTrect As RECTDim BOTTOMLEFTrect As RECTDim BOTTOMCENTERrect As RECTDim BOTTOMRIGHTrect As RECTDim TIPrect As RECT' DESIGNATE CHATBUBBLE SECTIONS FROM CHATBUBBLE IMAGEWith TOPRIGHTrect .top = 0 .Bottom = .top + 4 .Left = 0 .Right = .Left + 4End WithWith TOPCENTERrect .top = 0 .Bottom = .top + 4 .Left = 4 .Right = .Left + 4End WithWith TOPLEFTrect .top = 0 .Bottom = .top + 4 .Left = 8 .Right = .Left + 4End WithWith MIDDLERIGHTrect .top = 4 .Bottom = .top + 4 .Left = 0 .Right = .Left + 4End WithWith MIDDLECENTERrect .top = 4 .Bottom = .top + 4 .Left = 4 .Right = .Left + 4End WithWith MIDDLELEFTrect .top = 4 .Bottom = .top + 4 .Left = 8 .Right = .Left + 4End WithWith BOTTOMRIGHTrect .top = 8 .Bottom = .top + 4 .Left = 0 .Right = .Left + 4End WithWith BOTTOMCENTERrect .top = 8 .Bottom = .top + 4 .Left = 4 .Right = .Left + 4End WithWith BOTTOMLEFTrect .top = 8 .Bottom = .top + 4 .Left = 8 .Right = .Left + 4End WithWith TIPrect .top = 12 .Bottom = .top + 4 .Left = 0 .Right = .Left + 4End 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 WithEnd 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 activeAdded 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 More sharing options...
evilbunnie Posted April 29, 2012 Share Posted April 29, 2012 Glad to see you released this mate. Link to comment Share on other sites More sharing options...
Owen F Posted April 29, 2012 Share Posted April 29, 2012 You say credits go to "Rober Perris"You might want to fix that. (It's Robin Perris by the way) Link to comment Share on other sites More sharing options...
Justn Posted April 29, 2012 Share Posted April 29, 2012 Very cool mondo.. does this work/look any better with text rendering memory leak fix? Link to comment Share on other sites More sharing options...
Mondo Posted April 29, 2012 Author Share Posted April 29, 2012 @Owen:> You say credits go to "Rober Perris"> You might want to fix that. (It's Robin Perris by the way)My bad, thank you! Link to comment Share on other sites More sharing options...
Mondo Posted April 29, 2012 Author Share Posted April 29, 2012 @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 More sharing options...
Justn Posted April 29, 2012 Share Posted April 29, 2012 K gonna play around with it later thanks for sharingThis is what I was asking about http://www.touchofdeathforums.com/smf/index.php/topic,71691.0.html Link to comment Share on other sites More sharing options...
Mondo Posted April 29, 2012 Author Share Posted April 29, 2012 @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.htmlAwesome! Now I can use a different font! :DI 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 More sharing options...
Wilfre Posted April 29, 2012 Share Posted April 29, 2012 good. now i only have one reason to make my engine in dx8\. anyway great tutorial. Link to comment Share on other sites More sharing options...
erkro1 Posted April 29, 2012 Share Posted April 29, 2012 Very nice, lots of people were complaining about this, good job releasing this tutorial. ;) Link to comment Share on other sites More sharing options...
Owen F Posted April 29, 2012 Share Posted April 29, 2012 @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 More sharing options...
Joost Posted April 29, 2012 Share Posted April 29, 2012 http://echostorms.net/Mirage/MS%20Tutorials/Temporary%20Archive%20(Read%20Only)/Speech%20Bubble.htmlThat'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 More sharing options...
crzyone9584 Posted April 29, 2012 Share Posted April 29, 2012 > 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 More sharing options...
Mondo Posted April 29, 2012 Author Share Posted April 29, 2012 @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 More sharing options...
crzyone9584 Posted April 30, 2012 Share Posted April 30, 2012 @Mondo:> 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.Thats what I ment about the fix. Link to comment Share on other sites More sharing options...
erkro1 Posted May 1, 2012 Share Posted May 1, 2012 This still doesn't work perfect, I get Sub or Function not Defined at:```Call DeleteObject(GameFont)``` Link to comment Share on other sites More sharing options...
Killa_ Posted May 1, 2012 Share Posted May 1, 2012 ```size = size + EngineGetTextWidth(Mid$(text, i, 1))```argument not optional Link to comment Share on other sites More sharing options...
erkro1 Posted May 1, 2012 Share Posted May 1, 2012 @Killa_:> ```> size = size + EngineGetTextWidth(Mid$(text, i, 1))> ```argument not optionalChange it to:```size = size + EngineGetTextWidth(GameFont, Mid$(text, i, 1))``` Link to comment Share on other sites More sharing options...
Killa_ Posted May 1, 2012 Share Posted May 1, 2012 ```size = size + EngineGetTextWidth(GameFont, Mid$(text, i, 1))```ByRef argument type mismatch Link to comment Share on other sites More sharing options...
erkro1 Posted May 1, 2012 Share Posted May 1, 2012 @Killa_:> ```> size = size + EngineGetTextWidth(GameFont, Mid$(text, i, 1))> ```ByRef argument type mismatch```size = size + EngineGetTextWidth(Font_Default, Mid$(text, i, 1))``` Link to comment Share on other sites More sharing options...
Killa_ Posted May 1, 2012 Share Posted May 1, 2012 It works,thx very much =)But it works only on the map channel,will try to fix that. Link to comment Share on other sites More sharing options...
Mondo Posted May 1, 2012 Author Share Posted May 1, 2012 @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 More sharing options...
Mondo Posted May 1, 2012 Author Share Posted May 1, 2012 @Erwin:> ```> size = size + EngineGetTextWidth(Font_Default, Mid$(text, i, 1))> ```That is correct, I missed that one. :DFixed on the Tutorial. Link to comment Share on other sites More sharing options...
DarkDino Posted May 2, 2012 Share Posted May 2, 2012 dont display bubble :S how to fix D:? Link to comment Share on other sites More sharing options...
juvanio Posted May 2, 2012 Share Posted May 2, 2012 @DarkDino:> dont display bubble :S how to fix D:?Did you even edit both client and server?Nice tutorial by the way :> Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now