Skip to content

Commit c062d15

Browse files
committed
Fixed Major Memory Leaks
1 parent 2086564 commit c062d15

File tree

7 files changed

+158
-95
lines changed

7 files changed

+158
-95
lines changed

constants.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ def loadImageAsSurf(ipath):
2626
def createBlankSurf(width, height):
2727
return sdl2.SDL_CreateRGBSurfaceWithFormat(0, width, height, 32, sdl2.SDL_PIXELFORMAT_ABGR32)
2828

29-
3029
def convertSurfToTex(surf):
3130
return sdl2.SDL_CreateTextureFromSurface(const.renderer.sdlrenderer, surf)
3231

@@ -41,6 +40,9 @@ def convertTexToSurf(texture, width, height, pFormat):
4140
sdl2.SDL_SetRenderTarget(const.renderer.sdlrenderer, None)
4241
return surf
4342

43+
def createEmptyTexture():
44+
return sdl2.SDL_CreateTexture(const.renderer.sdlrenderer, sdl2.SDL_PIXELFORMAT_UNKNOWN, sdl2.SDL_TEXTUREACCESS_STATIC, 0, 0)
45+
4446
class filePaths:
4547
def __init__(self):
4648
self.pxattr = ''
@@ -109,7 +111,6 @@ def updateWindowSize(self, mptWidth, mptHeight, attrWidth):
109111

110112
sdl2.SDL_SetWindowSize(self.window.window, self.windowWidth, self.windowHeight)
111113
sdl2.SDL_RenderSetLogicalSize(self.renderer.sdlrenderer, self.windowWidth, self.windowHeight)
112-
recreateTextures(self.surfaceFunctions)
113114
self.setViewport()
114115

115116
def setViewport(self):

fakeWindow.py

Lines changed: 59 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88
#make variation of window that shows text only.
99
#add blinking cursor animation for text editing
1010

11-
buttonsTexture = convertSurfToTex(loadImageAsSurf(paths.buttons))
11+
buttonsSurf = loadImageAsSurf(paths.buttons)
12+
buttonsTexture = convertSurfToTex(buttonsSurf)
13+
sdl2.SDL_FreeSurface(buttonsSurf)
1214

1315
class inputField: #contains the header for field section and the attributes
1416
#type 0 = int, type 1 = directory, type 2 = bool, type 3 = string, type 4 = file path
@@ -18,6 +20,8 @@ def __init__(self, text, defaultInput, type):
1820
self.realInput = defaultInput
1921
self.defaultInput = self.encode(defaultInput)
2022
self.userInput = ''
23+
24+
self.textTex = createEmptyTexture()
2125

2226
self.active = False #if active then render highlighted
2327

@@ -44,6 +48,8 @@ def createText(self, color, typeInput): #generates text texture and also checks
4448
typeInput = self.defaultInput
4549
elif typeInput == 1:
4650
typeInput = self.userInput
51+
52+
sdl2.SDL_DestroyTexture(self.textTex)
4753
if len(str(typeInput)) == 0: #No text at all, so don't generate text texture because it will create a null pointer.
4854
self.textTex = sdl2.SDL_CreateTexture(const.renderer.sdlrenderer,
4955
sdl2.SDL_PIXELFORMAT_RGBA8888,
@@ -52,16 +58,16 @@ def createText(self, color, typeInput): #generates text texture and also checks
5258
12)
5359
self.textSrcRect = rect(0, 0, 10, 12)
5460
self.textDestRect = rect(self.textXPos, self.textYPos, 10, 12)
55-
dontConvertToTex = True
5661
else: #generate text because it WON'T result in a null pointer
57-
self.textTex = generateText(typeInput, color, 'normal')
58-
if self.textTex.contents.w <= 46: #text width is less than 46 means it fits into the box so it's not cropped
59-
self.textSrcRect = rect(0, 0, self.textTex.contents.w, 12)
60-
self.textDestRect = rect(self.textXPos, self.textYPos, self.textTex.contents.w, 12)
62+
textSurf = generateText(typeInput, color, 'normal')
63+
if textSurf.contents.w <= 46: #text width is less than 46 means it fits into the box so it's not cropped
64+
self.textSrcRect = rect(0, 0, textSurf.contents.w, 12)
65+
self.textDestRect = rect(self.textXPos, self.textYPos, textSurf.contents.w, 12)
6166
else: #text is too long to fit in box so it's cropped
62-
self.textSrcRect = rect(self.textTex.contents.w - 46, 0, self.textTex.contents.w, 12)
67+
self.textSrcRect = rect(textSurf.contents.w - 46, 0, textSurf.contents.w, 12)
6368
self.textDestRect = rect(self.textXPos - 2, self.textYPos, 46, 12)
64-
self.textTex = convertSurfToTex(self.textTex)
69+
self.textTex = convertSurfToTex(textSurf)
70+
sdl2.SDL_FreeSurface(textSurf)
6571

6672
def disable(self):
6773
self.disabled = True
@@ -112,6 +118,21 @@ def destroy(self): #delete surface
112118
const.surfaceFunctions.remove(self)
113119
mouse.resetSurfaces()
114120

121+
sdl2.SDL_DestroyTexture(self.windowTex)
122+
123+
124+
sdl2.SDL_DestroyTexture(self.inputFieldNormalTex)
125+
sdl2.SDL_DestroyTexture(self.inputFieldHighlightedTex)
126+
127+
sdl2.SDL_DestroyTexture(self.inputFieldButtonsTex)
128+
sdl2.SDL_DestroyTexture(self.inputFieldTextTex)
129+
130+
for tex in self.buttons: #tex is a tuple, [1] is texture index
131+
sdl2.SDL_DestroyTexture(tex[1])
132+
133+
for entry in self.inputFields:
134+
for tex in entry.fieldAreaTextTextures:
135+
sdl2.SDL_DestroyTexture(tex)
115136

116137
# for inputField in self.inputFields:
117138
# for field in inputField.inputFields:
@@ -133,31 +154,36 @@ def calculateWindowSize(self):
133154

134155
textColor = sdl2.SDL_Color(207, 219, 199)
135156

136-
self.headerTextTex = generateText(self.headerText, textColor, 'bold')
137-
headerWidth = self.headerTextTex.contents.w * 2 #sprite is 2 times big.
138-
headerHeight = self.headerTextTex.contents.h * 2
157+
self.headerTextSurf = generateText(self.headerText, textColor, 'bold')
158+
headerWidth = self.headerTextSurf.contents.w * 2 #sprite is 2 times big.
159+
headerHeight = self.headerTextSurf.contents.h * 2
160+
139161
windowHeaderLength = headerWidth
140-
self.headerTextTex = convertSurfToTex(self.headerTextTex)
162+
self.headerTextTex = convertSurfToTex(self.headerTextSurf)
163+
sdl2.SDL_FreeSurface(self.headerTextSurf)
141164

142165

143166
self.height = 29 #header height
144167
#self.height accumulates height through this loop:
145168
for entry in self.inputFields:
146-
entryTextTex = generateText(entry.headerText, textColor, 'bold')
147-
if entryTextTex.contents.w > inputStarterHeaderLength:
148-
inputStarterHeaderLength = entryTextTex.contents.w
169+
entryTextSurf = generateText(entry.headerText, textColor, 'bold')
170+
if entryTextSurf.contents.w > inputStarterHeaderLength:
171+
inputStarterHeaderLength = entryTextSurf.contents.w
149172
self.height += 18 #input field header height
150-
entryTextTex = convertSurfToTex(entryTextTex)
173+
entryTextTex = convertSurfToTex(entryTextSurf)
174+
sdl2.SDL_FreeSurface(entryTextSurf)
175+
151176
self.fieldHeaderTextTextures.append(entryTextTex)
152-
153177
for attribute in entry.inputFields:
154-
attributeTextTex = generateText(attribute.text, textColor, 'bold')
155-
if attributeTextTex.contents.w + 67 > inputFieldTextLength:
156-
inputFieldTextLength = attributeTextTex.contents.w + 67
178+
attributeTextSurf = generateText(attribute.text, textColor, 'bold')
179+
if attributeTextSurf.contents.w + 67 > inputFieldTextLength:
180+
inputFieldTextLength = attributeTextSurf.contents.w + 67
157181
self.height += 17 #input field height
158182

159-
attributeTextTex = convertSurfToTex(attributeTextTex)
183+
attributeTextTex = convertSurfToTex(attributeTextSurf)
160184
entry.fieldAreaTextTextures.append(attributeTextTex)
185+
sdl2.SDL_FreeSurface(attributeTextSurf)
186+
161187
self.height += 17 #height until next header.
162188
self.height += 30 #height to botom.
163189

@@ -236,6 +262,9 @@ def calculateWindowSize(self):
236262
textYPos += 16
237263
fieldAreaIndex = 0
238264
fieldHeaderIndex += 1
265+
266+
for tex in self.fieldHeaderTextTextures:
267+
sdl2.SDL_DestroyTexture(tex)
239268

240269
#BUTTONS:
241270

@@ -321,13 +350,15 @@ def calculateWindowSize(self):
321350

322351
def drawButton(self, text):
323352
#texture is twice as big for both normalTex and pressedTex
324-
textTex = generateText(text, sdl2.SDL_Color(207, 219, 199), 'bold')
325-
width = textTex.contents.w + 16
353+
width = ctypes.c_int()
354+
sdl2.sdlttf.TTF_SizeText(const.fontKeroM, bytes(text, 'utf-8'), width, None)
355+
width = width.value + 16
326356
tex = sdl2.SDL_CreateTexture(const.renderer.sdlrenderer,
327357
sdl2.SDL_PIXELFORMAT_RGB888,
328358
sdl2.SDL_TEXTUREACCESS_TARGET,
329359
width * 2,
330360
16)
361+
331362
def drawButtonTex(xPos, bgColor, shineColor, shadeColor, textColor): #*bgColor
332363
sdl2.SDL_SetRenderDrawColor(const.renderer.sdlrenderer, *bgColor, 255)
333364
sdl2.SDL_RenderFillRect(const.renderer.sdlrenderer, rect(xPos, 0, width, 16))
@@ -343,26 +374,18 @@ def drawButtonTex(xPos, bgColor, shineColor, shadeColor, textColor): #*bgColor
343374
sdl2.SDL_SetRenderDrawColor(const.renderer.sdlrenderer, 51, 71, 66, 255)
344375
sdl2.SDL_RenderDrawRect(const.renderer.sdlrenderer, rect(xPos, 0, width, 16))
345376

346-
textTex = generateText(text, textColor, 'bold')
347-
sdl2.SDL_RenderCopy(const.renderer.sdlrenderer, convertSurfToTex(textTex), None, rect(xPos + 8, 1, textTex.contents.w, textTex.contents.h))
377+
textSurf = generateText(text, textColor, 'bold')
378+
textTex = convertSurfToTex(textSurf)
379+
sdl2.SDL_RenderCopy(const.renderer.sdlrenderer, textTex, None, rect(xPos + 8, 1, textSurf.contents.w, textSurf.contents.h))
380+
sdl2.SDL_FreeSurface(textSurf)
381+
sdl2.SDL_DestroyTexture(textTex)
348382

349383
sdl2.SDL_SetRenderTarget(const.renderer.sdlrenderer, tex)
350384
drawButtonTex(0, (105, 130, 109), (148, 176, 131), (72, 98, 99), sdl2.SDL_Color(207, 219, 199))
351385
drawButtonTex(width, (77, 104, 82), (68, 85, 101), (105, 130, 109), sdl2.SDL_Color(51, 71, 66))
352386

353387
normalRect = rect(0, 0, width, 16)
354388
pressedRect = rect(width, 0, width, 16)
355-
# if type == 0:
356-
# col0 = (105, 130, 109)
357-
# col1 = (148, 176, 131)
358-
# col2 = (72, 98, 99)
359-
# col3 = sdl2.SDL_Color(207, 219, 199) #text
360-
# elif type == 1:
361-
# col0 = (77, 104, 82)
362-
# col1 = (68, 85, 101)
363-
# col2 = (105, 130, 109)
364-
# col3 = sdl2.SDL_Color(51, 71, 66) #text
365-
366389
return tex, normalRect, pressedRect
367390

368391
def createInputFieldTextures(self):
@@ -398,17 +421,9 @@ def drawInputField(tex, bgCol, shadeCol, shineCol, outlineCol):
398421
52,
399422
16
400423
)
401-
self.inputFieldDisabledTex = sdl2.SDL_CreateTexture(
402-
const.renderer.sdlrenderer,
403-
sdl2.SDL_PIXELFORMAT_RGB888,
404-
sdl2.SDL_TEXTUREACCESS_TARGET,
405-
52,
406-
16
407-
)
408424

409425
drawInputField(self.inputFieldNormalTex, (77, 104, 82), (68, 85, 101), (105, 130, 109), (51, 71, 66))
410426
drawInputField(self.inputFieldHighlightedTex, (105, 130, 109), (72, 98, 99), (148, 176, 131), (51, 71, 66))
411-
drawInputField(self.inputFieldDisabledTex, (67, 81, 74), (67, 81, 74), (83, 101, 93), (50, 61, 61))
412427

413428
def moveDestRect(self):
414429
""" Moves the rectangle while dragging based on mouse position. """

filebar.py

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,12 @@ def createToScreen(self):
4646
const.renderer.present()
4747

4848
def createOptionTexture(self):
49-
textNormal = generateText(self.text, sdl2.SDL_Color(74, 85, 84), 'bold')
50-
textHighlighted = generateText(self.text, sdl2.SDL_Color(77, 104, 82), 'bold')
51-
textClicked = generateText(self.text, sdl2.SDL_Color(51, 71, 66), 'bold')
49+
textNormalSurf = generateText(self.text, sdl2.SDL_Color(74, 85, 84), 'bold')
50+
textHighlightedSurf = generateText(self.text, sdl2.SDL_Color(77, 104, 82), 'bold')
51+
textClickedSurf = generateText(self.text, sdl2.SDL_Color(51, 71, 66), 'bold')
5252

53-
textWidth = textNormal.contents.w
54-
self.optionWidth = textNormal.contents.w + 20
53+
textWidth = textNormalSurf.contents.w
54+
self.optionWidth = textNormalSurf.contents.w + 20
5555
self.optionTex = sdl2.SDL_CreateTexture(
5656
const.renderer.sdlrenderer,
5757
sdl2.SDL_PIXELFORMAT_RGB888,
@@ -95,10 +95,17 @@ def createOptionTexture(self):
9595
#outline
9696
xOffset = 0
9797
sdl2.SDL_SetRenderDrawColor(const.renderer.sdlrenderer, 58, 73, 112, 255)
98-
for text in [textNormal, textHighlighted, textClicked]:
99-
sdl2.SDL_RenderCopy(const.renderer.sdlrenderer, convertSurfToTex(text), None, rect(xOffset + 3, 2, textWidth, 12))
98+
for text in [textNormalSurf, textHighlightedSurf, textClickedSurf]:
99+
tex = convertSurfToTex(text)
100+
sdl2.SDL_RenderCopy(const.renderer.sdlrenderer, tex, None, rect(xOffset + 3, 2, textWidth, 12))
100101
sdl2.SDL_RenderDrawRect(const.renderer.sdlrenderer, rect(xOffset-1, 0, self.optionWidth, 20))
102+
103+
sdl2.SDL_DestroyTexture(tex)
101104
xOffset += self.optionWidth
105+
106+
sdl2.SDL_FreeSurface(textNormalSurf)
107+
sdl2.SDL_FreeSurface(textHighlightedSurf)
108+
sdl2.SDL_FreeSurface(textClickedSurf)
102109
const.setViewport()
103110
self.normalSrcRect = rect(0, 0, self.optionWidth, 20)
104111
self.highlightedSrcRect = rect(self.optionWidth, 0, self.optionWidth, 20)

images/px.ico

832 Bytes
Binary file not shown.

miscFunctions.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,16 +35,14 @@ def undo():
3535

3636
def updateAttributesTexture():
3737
os.chdir(os.path.dirname(os.path.abspath(__file__)))
38+
sdl2.SDL_FreeSurface(surfAttr.attrSurf)
3839
if pxattr.version == 0:
3940
surfAttr.attrSurf = loadImageAsSurf(paths.attributesTextureKB)
40-
surfMpt.attributeSurf = loadImageAsSurf(paths.attributesTextureKB)
41-
4241
elif pxattr.version == 1:
4342
surfAttr.attrSurf = loadImageAsSurf(paths.attributesTexturePT)
44-
surfMpt.attributeSurf = loadImageAsSurf(paths.attributesTexturePT)
4543
elif pxattr.version == 2:
4644
surfAttr.attrSurf = loadImageAsSurf(paths.attributesTexture2012)
47-
surfMpt.attributeSurf = loadImageAsSurf(paths.attributesTexture2012)
45+
sdl2.SDL_BlitSurface(surfAttr.attrSurf, None, surfMpt.attributeSurf, None)
4846
surfAttr.updateTex()
4947

5048
def openFile():
@@ -62,6 +60,7 @@ def openFile():
6260
else:
6361
mouse.history.clear()
6462
mouse.historyIndex = -1
63+
6564
pxattr.pxOpen(path)
6665
pxattr.path = path
6766
pxattr.attributeArrayEdit = pxattr.attributeArray
@@ -154,6 +153,7 @@ def promptEditPxattr():
154153
def processReplaceImage(inputData): #[path]
155154
surfMpt.path = inputData[0]
156155
if os.path.exists(surfMpt.path) and surfMpt.path[-4:] == '.png' or surfMpt.path[-4:] == '.bmp':
156+
sdl2.SDL_FreeSurface(surfMpt.mptSurf)
157157
surfMpt.mptSurf = loadImageAsSurf(surfMpt.path)
158158
surfMpt.updateMptTex()
159159
updateRender(const.surfaceFunctions)

readme.txt

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
.pxattr are collision data files used for tilesets; it associates a tile from a tileset to a collision type. The data values vary from version, so I included info for what tiles exist in other versions.
2+
3+
Select an attribute from the right side, and then draw with it. Undo and Redo with Ctrl-Z and Ctrl-Shift-Z if needed. Save File with Ctrl-S or from the Filebar.
4+
Edit file data from Filebar.
5+
6+
Pxattr Info:
7+
Compression has existed since post 2012 (Kero Blaster), but it has been unused. It is used in Pitest, for both the level files and the pxattr files.
8+
It is RLE compression, storing a tile, and then the amount of times that tile gets repeated.
9+
10+
Version:
11+
Games like Kero Blaster and Pitest do not have the same header, by changing this it determines if the game engine will be able to read the pxattr file. If you use the wrong version in the wrong game, it will not work. Make sure to set the version to the correct Value.
12+
...Interestingly, Pre-2012 (Rockfish and early versions of Starfrog) don't have headers, this is compromised by the program reading the width and height (which are at the start of the file), and then seeing if the total size matches the file length.
13+
14+
Tile Resolution:
15+
This is a visual aspect that actually comes from pxmap files (the level format). This affects how they're rendered, pxattr files don't store this data, only pxmap files, however this is important because it sets how many pixels are per tile, if you use the wrong setting it can mess up the rendering of it in game.
16+
17+
Anyone can modify this code if they please (with credit.)

0 commit comments

Comments
 (0)