PSP-Archive / ARK-4

Custom Firmware for the PSP and PS Vita.
683 stars 42 forks source link

Satelite menu cyrillic fonts fix #198

Closed jeffangelion closed 1 year ago

jeffangelion commented 1 year ago

Issue #191 fixes:

P.S. There are two ways to edit such tile fonts:

  1. Hard way: look under every stone for RomArtist.exe freeware
  2. Easy way: write scripts for .pf <-> .png conversion
    
    #!/usr/bin/env python3
    # -*- coding: utf-8 -*-
    # SPDX-License-Identifier: GPL-3.0-or-later
    # Copyright (C) 2023 Ivan Vatlin <jenrus@riseup.net>
    import sys  # sys.argv
    import zlib # zlib.crc32(); zlib.compress()
    # Usage: pf_to_png.py <input_file> <output_file>
    # Image specs: PNG, 128x128 pixels, 1 bit grayscale, no Adam7 interlace
    def pf_to_png(pf):
    png_signature = b'\x89\x50\x4e\x47\x0d\x0a\x1a\x0a'
    ihdr = (
        b'\x00\x00\x00\x0d' # Chunk data length (13 bytes)
        b'\x49\x48\x44\x52' # IHDR chunk signature
        b'\x00\x00\x00\x80' # width: 128 pixels
        b'\x00\x00\x00\x80' # height: 128 pixels
        b'\x01'             # bit depth: 1 bit per pixel
        b'\x00'             # color type: grayscale
        b'\x00'             # compression method: default
        b'\x00'             # filter method: default
        b'\x00'             # interlace method: no interlace
        b'\xeb\x45\x5c\x66' # CRC32 checksum (zlib.crc32().to_bytes(4, 'big'))
    )
    idat = bytearray()
    idat_signature = b'\x49\x44\x41\x54' # IDAT chunk signature
    iend = (
        b'\x00\x00\x00\x00' # Chunk data length (0 bytes)
        b'\x49\x45\x4e\x44' # IEND chunk signature
        b'\xae\x42\x60\x82' # CRC32 checksum (zlib.crc32().to_bytes(4, 'big'))
    )
    for i in range(0, 2048, 128):
        for j in range(0, 8, 1):
            idat.extend(b'\x00') # add filter type (none) byte
            for k in range(0, 128, 8):
                idat.append(pf[i + j + k])
    idat = zlib.compress(idat)
    idat_length = len(idat).to_bytes(4, 'big')
    idat = idat_signature + idat
    output = png_signature + ihdr + idat_length + idat + zlib.crc32(idat).to_bytes(4, 'big') + iend
    return output

with open(sys.argv[1], mode="rb") as pf_file: pf_data = pf_file.read() png_file = open(sys.argv[2], mode="wb") png_file.write(pf_to_png(pf_data))

```python
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# SPDX-License-Identifier: GPL-3.0-or-later
# Copyright (C) 2023 Ivan Vatlin <jenrus@riseup.net>
import sys # sys.argv
import zlib # zlib.decompress()
# Usage: png_to_pf.py <input_file> <output_file>
def png_to_pf(png):
    if png[0:8] == b'\x89\x50\x4e\x47\x0d\x0a\x1a\x0a': # Check PNG signature
        idat_length = int.from_bytes(png[33:37], "big") # Skip IHDR chunk & reading IDAT chunk data length
        idat_zlib = png[41:41+idat_length]              # Read compressed IDAT chunk data
        idat_data = zlib.decompress(idat_zlib)          # Decompress IDAT chunk data
        pf = bytearray()
        for i in range(0, 2176, 136):
            for k in range(0, 16, 1):
                for j in range(1, 136, 17): # Skip filter type byte
                    pf.append(idat_data[i + j + k])
        return pf
    else:
        print('not a PNG file')

with open(sys.argv[1], mode="rb") as png_file:
    png_data = png_file.read()
    pf_file = open(sys.argv[2], mode="wb")
    pf_file.write(png_to_pf(png_data))
jeffangelion commented 1 year ago

Font comparison: CP866.pf Before/After: CP866_old CP866 CYRILL1.pf Before/After: CYRILL1_old CYRILL1 CYRILL2.pf Before/After: CYRILL2_old CYRILL2 CYRILL3.pf Before/After: CYRILL3_old CYRILL3 RUSSIAN.pf Before/After: RUSSIAN_old RUSSIAN Bonus: CYRIL_B.pf (to demonstrate its problems): CYRIL_B

krazynez commented 1 year ago

Issue #191 fixes:

* RUSSIAN.pf is IBM CP866 complaint

* CP866.pf now has correct `М` character

* CYRILL*.pf now has `Ёё` characters

* CYRIL_B.pf removed because of uselessness

P.S. There are two ways to edit such tile fonts:

1. Hard way: look under every stone for RomArtist.exe freeware

2. Easy way: write scripts for .pf <-> .png conversion
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# SPDX-License-Identifier: GPL-3.0-or-later
# Copyright (C) 2023 Ivan Vatlin <jenrus@riseup.net>
import sys  # sys.argv
import zlib # zlib.crc32(); zlib.compress()
# Usage: pf_to_png.py <input_file> <output_file>
# Image specs: PNG, 128x128 pixels, 1 bit grayscale, no Adam7 interlace
def pf_to_png(pf):
    png_signature = b'\x89\x50\x4e\x47\x0d\x0a\x1a\x0a'
    ihdr = (
        b'\x00\x00\x00\x0d' # Chunk data length (13 bytes)
        b'\x49\x48\x44\x52' # IHDR chunk signature
        b'\x00\x00\x00\x80' # width: 128 pixels
        b'\x00\x00\x00\x80' # height: 128 pixels
        b'\x01'             # bit depth: 1 bit per pixel
        b'\x00'             # color type: grayscale
        b'\x00'             # compression method: default
        b'\x00'             # filter method: default
        b'\x00'             # interlace method: no interlace
        b'\xeb\x45\x5c\x66' # CRC32 checksum (zlib.crc32().to_bytes(4, 'big'))
    )
    idat = bytearray()
    idat_signature = b'\x49\x44\x41\x54' # IDAT chunk signature
    iend = (
        b'\x00\x00\x00\x00' # Chunk data length (0 bytes)
        b'\x49\x45\x4e\x44' # IEND chunk signature
        b'\xae\x42\x60\x82' # CRC32 checksum (zlib.crc32().to_bytes(4, 'big'))
    )
    for i in range(0, 2048, 128):
        for j in range(0, 8, 1):
            idat.extend(b'\x00') # add filter type (none) byte
            for k in range(0, 128, 8):
                idat.append(pf[i + j + k])
    idat = zlib.compress(idat)
    idat_length = len(idat).to_bytes(4, 'big')
    idat = idat_signature + idat
    output = png_signature + ihdr + idat_length + idat + zlib.crc32(idat).to_bytes(4, 'big') + iend
    return output

with open(sys.argv[1], mode="rb") as pf_file:
    pf_data = pf_file.read()
    png_file = open(sys.argv[2], mode="wb")
    png_file.write(pf_to_png(pf_data))
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# SPDX-License-Identifier: GPL-3.0-or-later
# Copyright (C) 2023 Ivan Vatlin <jenrus@riseup.net>
import sys # sys.argv
import zlib # zlib.decompress()
# Usage: png_to_pf.py <input_file> <output_file>
def png_to_pf(png):
    if png[0:8] == b'\x89\x50\x4e\x47\x0d\x0a\x1a\x0a': # Check PNG signature
        idat_length = int.from_bytes(png[33:37], "big") # Skip IHDR chunk & reading IDAT chunk data length
        idat_zlib = png[41:41+idat_length]              # Read compressed IDAT chunk data
        idat_data = zlib.decompress(idat_zlib)          # Decompress IDAT chunk data
        pf = bytearray()
        for i in range(0, 2176, 136):
            for k in range(0, 16, 1):
                for j in range(1, 136, 17): # Skip filter type byte
                    pf.append(idat_data[i + j + k])
        return pf
    else:
        print('not a PNG file')

with open(sys.argv[1], mode="rb") as png_file:
    png_data = png_file.read()
    pf_file = open(sys.argv[2], mode="wb")
    pf_file.write(png_to_pf(png_data))

if you wish you can add that to the contrib/PC folder in ARK :+1:

krazynez commented 1 year ago

Ignore the GH actions its just because its from outside source so your tokens are not the proper ones that we use. More concerned if it properly compiled or not.

JoseAaronLopezGarcia commented 1 year ago

We might have to revise this code: https://github.com/PSP-Archive/ARK-4/blob/45b5e3ba69b0661b27a222378d3cacd94e99827f/extras/menus/advancedvsh/fonts.c#L100

As it is now, it only lets you use "Russian.pf" for the Russian language.

jeffangelion commented 1 year ago

You don't have to, RUSSIAN.pf is more than enough + user can select other fonts via ADVANCED VSH MENU (however user need to scroll through options BACKWARDS) (no, you can just select them)

JoseAaronLopezGarcia commented 1 year ago

You don't have to, RUSSIAN.pf is more than enough + user can select other fonts via ADVANCED VSH MENU (however user need to scroll through options BACKWARDS)

Users can't select other fonts, it's limited to only "Russian.pf", it can't be changed unless we update that part of the code.

jeffangelion commented 1 year ago

@JoseAaronLopezGarcia sorry in advance for photos but here is the proof of all fonts being selectable

CP866.pf ![CP866.pf](https://github.com/PSP-Archive/ARK-4/assets/16368461/b1e51c66-fb95-4e39-b69b-08bc173ecf99)
RUSSIAN.pf ![RUSSIAN.pf](https://github.com/PSP-Archive/ARK-4/assets/16368461/bd2a4ef1-592f-48e9-819d-9ebdab9cc685)
CYRILL1.pf ![CYRILL1.pf](https://github.com/PSP-Archive/ARK-4/assets/16368461/6018a03c-2804-4aae-b676-c5972ea26e57)
CYRILL2.pf ![CYRILL2.pf](https://github.com/PSP-Archive/ARK-4/assets/16368461/4affdbe0-ea53-49c4-a232-5e38be5a8a86)
CYRILL3.pf ![CYRILL3.pf](https://github.com/PSP-Archive/ARK-4/assets/16368461/504065f4-99f5-408a-98da-13cef5b13c11)
CYRIL_B.pf ![CYRIL_B.pf](https://github.com/PSP-Archive/ARK-4/assets/16368461/959a87d6-de2c-45b8-b117-98e248afd03f)
JoseAaronLopezGarcia commented 1 year ago

All good, thanks for your help!

JoseAaronLopezGarcia commented 1 year ago

if you wish you can add that to the contrib/PC folder in ARK 👍

Did we do this in the end? I wouldn't want this very useful code to get lost.

jeffangelion commented 1 year ago

Did we do this in the end?

Yeah, it was added by commit 0649823

I wouldn't want this very useful code to get lost.

The code can and should be improved, it's a hacky mess with bytes