hacktools 0.36.1__tar.gz → 0.37.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. {hacktools-0.36.1/hacktools.egg-info → hacktools-0.37.1}/PKG-INFO +11 -2
  2. hacktools-0.37.1/hacktools/__init__.py +1 -0
  3. {hacktools-0.36.1 → hacktools-0.37.1}/hacktools/nitro.py +111 -94
  4. {hacktools-0.36.1 → hacktools-0.37.1/hacktools.egg-info}/PKG-INFO +11 -2
  5. {hacktools-0.36.1 → hacktools-0.37.1}/setup.py +1 -0
  6. hacktools-0.36.1/hacktools/__init__.py +0 -1
  7. {hacktools-0.36.1 → hacktools-0.37.1}/LICENSE +0 -0
  8. {hacktools-0.36.1 → hacktools-0.37.1}/MANIFEST.in +0 -0
  9. {hacktools-0.36.1 → hacktools-0.37.1}/README.md +0 -0
  10. {hacktools-0.36.1 → hacktools-0.37.1}/hacktools/arch.py +0 -0
  11. {hacktools-0.36.1 → hacktools-0.37.1}/hacktools/assets/icon.png +0 -0
  12. {hacktools-0.36.1 → hacktools-0.37.1}/hacktools/c_ext/cmp_cri.c +0 -0
  13. {hacktools-0.36.1 → hacktools-0.37.1}/hacktools/c_ext/cmp_lzss.c +0 -0
  14. {hacktools-0.36.1 → hacktools-0.37.1}/hacktools/c_ext/cmp_misc.c +0 -0
  15. {hacktools-0.36.1 → hacktools-0.37.1}/hacktools/c_ext/cmp_racjin.c +0 -0
  16. {hacktools-0.36.1 → hacktools-0.37.1}/hacktools/c_ext/inc.h +0 -0
  17. {hacktools-0.36.1 → hacktools-0.37.1}/hacktools/common.py +0 -0
  18. {hacktools-0.36.1 → hacktools-0.37.1}/hacktools/compression.py +0 -0
  19. {hacktools-0.36.1 → hacktools-0.37.1}/hacktools/cpk.py +0 -0
  20. {hacktools-0.36.1 → hacktools-0.37.1}/hacktools/gb.py +0 -0
  21. {hacktools-0.36.1 → hacktools-0.37.1}/hacktools/gui.py +0 -0
  22. {hacktools-0.36.1 → hacktools-0.37.1}/hacktools/nasm.py +0 -0
  23. {hacktools-0.36.1 → hacktools-0.37.1}/hacktools/nds.py +0 -0
  24. {hacktools-0.36.1 → hacktools-0.37.1}/hacktools/psp.py +0 -0
  25. {hacktools-0.36.1 → hacktools-0.37.1}/hacktools/psx.py +0 -0
  26. {hacktools-0.36.1 → hacktools-0.37.1}/hacktools/wii.py +0 -0
  27. {hacktools-0.36.1 → hacktools-0.37.1}/hacktools/ws.py +0 -0
  28. {hacktools-0.36.1 → hacktools-0.37.1}/hacktools.egg-info/SOURCES.txt +0 -0
  29. {hacktools-0.36.1 → hacktools-0.37.1}/hacktools.egg-info/dependency_links.txt +0 -0
  30. {hacktools-0.36.1 → hacktools-0.37.1}/hacktools.egg-info/requires.txt +0 -0
  31. {hacktools-0.36.1 → hacktools-0.37.1}/hacktools.egg-info/top_level.txt +0 -0
  32. {hacktools-0.36.1 → hacktools-0.37.1}/setup.cfg +0 -0
  33. {hacktools-0.36.1 → hacktools-0.37.1}/tests/test_cmp.py +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: hacktools
3
- Version: 0.36.1
3
+ Version: 0.37.1
4
4
  Summary: A set of utilities and tools for rom hacking and translations.
5
5
  Home-page: https://github.com/Illidanz/hacktools
6
6
  Author: Illidan
@@ -10,6 +10,7 @@ Classifier: Programming Language :: Python :: 3.9
10
10
  Classifier: Programming Language :: Python :: 3.10
11
11
  Classifier: Programming Language :: Python :: 3.11
12
12
  Classifier: Programming Language :: Python :: 3.12
13
+ Classifier: Programming Language :: Python :: 3.13
13
14
  Classifier: License :: OSI Approved :: MIT License
14
15
  Classifier: Operating System :: OS Independent
15
16
  Requires-Python: >=3.7
@@ -46,6 +47,14 @@ Requires-Dist: Pillow; extra == "all"
46
47
  Requires-Dist: click; extra == "all"
47
48
  Requires-Dist: tqdm; extra == "all"
48
49
  Requires-Dist: customtkinter; extra == "all"
50
+ Dynamic: author
51
+ Dynamic: classifier
52
+ Dynamic: description
53
+ Dynamic: description-content-type
54
+ Dynamic: home-page
55
+ Dynamic: provides-extra
56
+ Dynamic: requires-python
57
+ Dynamic: summary
49
58
 
50
59
  # hacktools
51
60
  A set of utilities and tools for rom hacking and translations.
@@ -0,0 +1 @@
1
+ __version__ = "0.37.1"
@@ -1310,6 +1310,102 @@ class NSBMDPalette:
1310
1310
  self.size = 0
1311
1311
  self.data = []
1312
1312
 
1313
+ def readTEX0(nsbmd, f, zerotransp=False):
1314
+ # Read TEX0 block
1315
+ f.seek(nsbmd.blockoffset + 4)
1316
+ nsbmd.blocksize = f.readUInt()
1317
+ nsbmd.blocklimit = nsbmd.blocksize + nsbmd.blockoffset
1318
+ f.seek(4, 1)
1319
+ nsbmd.texdatasize = f.readUShort() * 8
1320
+ f.seek(6, 1)
1321
+ nsbmd.texdataoffset = f.readUInt() + nsbmd.blockoffset
1322
+ f.seek(4, 1)
1323
+ nsbmd.sptexsize = f.readUShort() * 8
1324
+ f.seek(6, 1)
1325
+ nsbmd.sptexoffset = f.readUInt() + nsbmd.blockoffset
1326
+ nsbmd.spdataoffset = f.readUInt() + nsbmd.blockoffset
1327
+ f.seek(4, 1)
1328
+ nsbmd.paldatasize = f.readUShort() * 8
1329
+ f.seek(2, 1)
1330
+ nsbmd.paldefoffset = f.readUInt() + nsbmd.blockoffset
1331
+ nsbmd.paldataoffset = f.readUInt() + nsbmd.blockoffset
1332
+ common.logDebug(vars(nsbmd))
1333
+ # Texture definition
1334
+ f.seek(1, 1)
1335
+ texnum = f.readByte()
1336
+ pos = f.tell()
1337
+ f.seek(nsbmd.paldefoffset + 1)
1338
+ palnum = f.readByte()
1339
+ f.seek(pos)
1340
+ common.logDebug("texnum:", texnum, "palnum:", palnum)
1341
+ f.seek(14 + (texnum * 4), 1)
1342
+ for i in range(texnum):
1343
+ offset = f.readUShort() * 8
1344
+ param = f.readUShort()
1345
+ f.seek(4, 1)
1346
+ tex = NSBMDTexture()
1347
+ tex.format = (param >> 10) & 7
1348
+ tex.width = 8 << ((param >> 4) & 7)
1349
+ tex.height = 8 << ((param >> 7) & 7)
1350
+ tex.size = tex.width * tex.height * NSBMDbpp[tex.format] // 8
1351
+ if tex.format == 5:
1352
+ tex.offset = offset + nsbmd.sptexoffset
1353
+ else:
1354
+ tex.offset = offset + nsbmd.texdataoffset
1355
+ nsbmd.textures.append(tex)
1356
+ # Texture name
1357
+ for tex in nsbmd.textures:
1358
+ tex.name = f.readString(16)
1359
+ common.logDebug(vars(tex))
1360
+ # Palette definition
1361
+ f.seek(nsbmd.paldefoffset + 2 + 14 + (palnum * 4))
1362
+ for i in range(palnum):
1363
+ pal = NSBMDPalette()
1364
+ pal.offset = (f.readUShort() * 8) + nsbmd.paldataoffset
1365
+ f.seek(2, 1)
1366
+ nsbmd.palettes.append(pal)
1367
+ # Palette size
1368
+ if palnum > 0:
1369
+ for i in range(palnum):
1370
+ r = i + 1
1371
+ while r < len(nsbmd.palettes) and nsbmd.palettes[r].offset == nsbmd.palettes[i].offset:
1372
+ r += 1
1373
+ if r != palnum:
1374
+ nsbmd.palettes[i].size = nsbmd.palettes[r].offset - nsbmd.palettes[i].offset
1375
+ else:
1376
+ nsbmd.palettes[i].size = nsbmd.blocklimit - nsbmd.palettes[i].offset
1377
+ nsbmd.palettes[i].size = nsbmd.blocklimit - nsbmd.palettes[i].offset
1378
+ # Palette name
1379
+ for pal in nsbmd.palettes:
1380
+ pal.name = f.readString(16)
1381
+ common.logDebug(vars(pal))
1382
+ # Traverse palettes
1383
+ for pal in nsbmd.palettes:
1384
+ f.seek(pal.offset)
1385
+ for i in range(pal.size // 2):
1386
+ palcolor = common.readPalette(f.readShort())
1387
+ if i == 0 and zerotransp:
1388
+ palcolor = (palcolor[0], palcolor[1], palcolor[2], 0)
1389
+ pal.data.append(palcolor)
1390
+ # Traverse texture
1391
+ spdataoffset = nsbmd.spdataoffset
1392
+ for texi in range(len(nsbmd.textures)):
1393
+ tex = nsbmd.textures[texi]
1394
+ if tex.format == 5:
1395
+ r = tex.size >> 1
1396
+ f.seek(spdataoffset)
1397
+ for i in range(r // 2):
1398
+ tex.spdata.append(f.readUShort())
1399
+ spdataoffset += r
1400
+ # Export texture
1401
+ f.seek(tex.offset)
1402
+ if tex.format == 5:
1403
+ for i in range(tex.size // 4):
1404
+ tex.data.append(f.readUInt())
1405
+ else:
1406
+ tex.data = f.read(tex.size)
1407
+ return nsbmd
1408
+
1313
1409
 
1314
1410
  def readNSBMD(nsbmdfile, zerotransp=False):
1315
1411
  nsbmd = NSBMD()
@@ -1328,100 +1424,18 @@ def readNSBMD(nsbmdfile, zerotransp=False):
1328
1424
  f.seek(-4, 1)
1329
1425
  texstart = f.readUShort()
1330
1426
  nsbmd.blockoffset = nsbmdstart + texstart
1331
- # Read TEX0 block
1332
- f.seek(nsbmd.blockoffset + 4)
1333
- nsbmd.blocksize = f.readUInt()
1334
- nsbmd.blocklimit = nsbmd.blocksize + nsbmd.blockoffset
1335
- f.seek(4, 1)
1336
- nsbmd.texdatasize = f.readUShort() * 8
1337
- f.seek(6, 1)
1338
- nsbmd.texdataoffset = f.readUInt() + nsbmd.blockoffset
1339
- f.seek(4, 1)
1340
- nsbmd.sptexsize = f.readUShort() * 8
1341
- f.seek(6, 1)
1342
- nsbmd.sptexoffset = f.readUInt() + nsbmd.blockoffset
1343
- nsbmd.spdataoffset = f.readUInt() + nsbmd.blockoffset
1344
- f.seek(4, 1)
1345
- nsbmd.paldatasize = f.readUShort() * 8
1346
- f.seek(2, 1)
1347
- nsbmd.paldefoffset = f.readUInt() + nsbmd.blockoffset
1348
- nsbmd.paldataoffset = f.readUInt() + nsbmd.blockoffset
1349
- common.logDebug(vars(nsbmd))
1350
- # Texture definition
1351
- f.seek(1, 1)
1352
- texnum = f.readByte()
1353
- pos = f.tell()
1354
- f.seek(nsbmd.paldefoffset + 1)
1355
- palnum = f.readByte()
1356
- f.seek(pos)
1357
- common.logDebug("texnum:", texnum, "palnum:", palnum)
1358
- f.seek(14 + (texnum * 4), 1)
1359
- for i in range(texnum):
1360
- offset = f.readUShort() * 8
1361
- param = f.readUShort()
1362
- f.seek(4, 1)
1363
- tex = NSBMDTexture()
1364
- tex.format = (param >> 10) & 7
1365
- tex.width = 8 << ((param >> 4) & 7)
1366
- tex.height = 8 << ((param >> 7) & 7)
1367
- tex.size = tex.width * tex.height * NSBMDbpp[tex.format] // 8
1368
- if tex.format == 5:
1369
- tex.offset = offset + nsbmd.sptexoffset
1370
- else:
1371
- tex.offset = offset + nsbmd.texdataoffset
1372
- nsbmd.textures.append(tex)
1373
- # Texture name
1374
- for tex in nsbmd.textures:
1375
- tex.name = f.readString(16)
1376
- common.logDebug(vars(tex))
1377
- # Palette definition
1378
- f.seek(nsbmd.paldefoffset + 2 + 14 + (palnum * 4))
1379
- for i in range(palnum):
1380
- pal = NSBMDPalette()
1381
- pal.offset = (f.readUShort() * 8) + nsbmd.paldataoffset
1382
- f.seek(2, 1)
1383
- nsbmd.palettes.append(pal)
1384
- # Palette size
1385
- if palnum > 0:
1386
- for i in range(palnum):
1387
- r = i + 1
1388
- while r < len(nsbmd.palettes) and nsbmd.palettes[r].offset == nsbmd.palettes[i].offset:
1389
- r += 1
1390
- if r != palnum:
1391
- nsbmd.palettes[i].size = nsbmd.palettes[r].offset - nsbmd.palettes[i].offset
1392
- else:
1393
- nsbmd.palettes[i].size = nsbmd.blocklimit - nsbmd.palettes[i].offset
1394
- nsbmd.palettes[i].size = nsbmd.blocklimit - nsbmd.palettes[i].offset
1395
- # Palette name
1396
- for pal in nsbmd.palettes:
1397
- pal.name = f.readString(16)
1398
- common.logDebug(vars(pal))
1399
- # Traverse palettes
1400
- for pal in nsbmd.palettes:
1401
- f.seek(pal.offset)
1402
- for i in range(pal.size // 2):
1403
- palcolor = common.readPalette(f.readShort())
1404
- if i == 0 and zerotransp:
1405
- palcolor = (palcolor[0], palcolor[1], palcolor[2], 0)
1406
- pal.data.append(palcolor)
1407
- # Traverse texture
1408
- spdataoffset = nsbmd.spdataoffset
1409
- for texi in range(len(nsbmd.textures)):
1410
- tex = nsbmd.textures[texi]
1411
- if tex.format == 5:
1412
- r = tex.size >> 1
1413
- f.seek(spdataoffset)
1414
- for i in range(r // 2):
1415
- tex.spdata.append(f.readUShort())
1416
- spdataoffset += r
1417
- # Export texture
1418
- f.seek(tex.offset)
1419
- if tex.format == 5:
1420
- for i in range(tex.size // 4):
1421
- tex.data.append(f.readUInt())
1422
- else:
1423
- tex.data = f.read(tex.size)
1424
- return nsbmd
1427
+ return readTEX0(nsbmd, f, zerotransp)
1428
+
1429
+
1430
+ def readNSBTX(nsbmdfile, zerotransp=False):
1431
+ nsbmd = NSBMD()
1432
+ with common.Stream(nsbmdfile, "rb") as f:
1433
+ nsbmdstart = 0
1434
+ # Read the TEX0 offset
1435
+ f.seek(nsbmdstart + 0x10)
1436
+ texstart = f.readUShort()
1437
+ nsbmd.blockoffset = nsbmdstart + texstart
1438
+ return readTEX0(nsbmd, f, zerotransp)
1425
1439
 
1426
1440
 
1427
1441
  def drawNSBMD(file, nsbmd, texi):
@@ -1431,6 +1445,9 @@ def drawNSBMD(file, nsbmd, texi):
1431
1445
  common.logError("PIL not found")
1432
1446
  return
1433
1447
  tex = nsbmd.textures[texi]
1448
+ if tex.format != 7 and len(nsbmd.palettes) == 0:
1449
+ common.logDebug("Skipping texture with no palettes")
1450
+ return
1434
1451
  common.logDebug("Exporting", tex.name, "...")
1435
1452
  palette = None
1436
1453
  if tex.format != 7:
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: hacktools
3
- Version: 0.36.1
3
+ Version: 0.37.1
4
4
  Summary: A set of utilities and tools for rom hacking and translations.
5
5
  Home-page: https://github.com/Illidanz/hacktools
6
6
  Author: Illidan
@@ -10,6 +10,7 @@ Classifier: Programming Language :: Python :: 3.9
10
10
  Classifier: Programming Language :: Python :: 3.10
11
11
  Classifier: Programming Language :: Python :: 3.11
12
12
  Classifier: Programming Language :: Python :: 3.12
13
+ Classifier: Programming Language :: Python :: 3.13
13
14
  Classifier: License :: OSI Approved :: MIT License
14
15
  Classifier: Operating System :: OS Independent
15
16
  Requires-Python: >=3.7
@@ -46,6 +47,14 @@ Requires-Dist: Pillow; extra == "all"
46
47
  Requires-Dist: click; extra == "all"
47
48
  Requires-Dist: tqdm; extra == "all"
48
49
  Requires-Dist: customtkinter; extra == "all"
50
+ Dynamic: author
51
+ Dynamic: classifier
52
+ Dynamic: description
53
+ Dynamic: description-content-type
54
+ Dynamic: home-page
55
+ Dynamic: provides-extra
56
+ Dynamic: requires-python
57
+ Dynamic: summary
49
58
 
50
59
  # hacktools
51
60
  A set of utilities and tools for rom hacking and translations.
@@ -50,6 +50,7 @@ setup(
50
50
  "Programming Language :: Python :: 3.10",
51
51
  "Programming Language :: Python :: 3.11",
52
52
  "Programming Language :: Python :: 3.12",
53
+ "Programming Language :: Python :: 3.13",
53
54
  "License :: OSI Approved :: MIT License",
54
55
  "Operating System :: OS Independent",
55
56
  ],
@@ -1 +0,0 @@
1
- __version__ = "0.36.1"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes