New Insane IDEA! (Sylverant PSO Patcher)

Sylverant is a homebrew open source server for Phantasy Star Online. Dreamcast users still play PSO online with this server even today! This is the official forum for both the online game server as well as the open source project itself. Feel free to post and get a gathering started online! We can also show you how to get connected!

Moderators: BlueCrab, Aleron Ives

Post Reply
User avatar
Whithil XBR
DCEmu Cool Newbie
DCEmu Cool Newbie
Posts: 15
Joined: Tue Jul 05, 2011 3:37 pm
Has liked: 0
Been liked: 0

New Insane IDEA! (Sylverant PSO Patcher)

Post by Whithil XBR » Sun Sep 18, 2011 11:36 am

Hi Again :grin:

So here I am, once more to bring you an Insane idea...

Well, today i was translating some pso weapons to portuguese, when Kireek sent an image of his new Forest skin.
I really liked it, and it gave me an idea...

I was reading about Sylverant PSO Patcher, and it's amazing! It can Break the HL Check, fix the Ultimate and change the connection to sylverant, so... what if we try to do more?

Please, don't misunderstand... I'm intended to change the current disc

The Idea is... well... to make another disc, Based in Sylverant PSO Patcher, but with other patches, such as Skins, Translations, and other stuff...

There are currently a lot of cool stuff available for PSOPC, and we can easily patch a psopc client

But for PSODC the only way is to make another ISO and burn a Disc with the patched pso
Well, in my the last topic Ives told me about the players with Original discs, so I Agreed him that making a patched disc would not be a good idea for these players.

But now, it seems to be different... so why not?

We could make a new disc with Skins, Traslations to other languages and Much more.

Think about it!
User avatar
Aleron Ives
DCEmu Nutter
DCEmu Nutter
Posts: 829
Joined: Wed Jan 05, 2011 2:15 pm
Location: California
Has liked: 0
Been liked: 4 times
Contact:

Re: New Insane IDEA! (Sylverant PSO Patcher)

Post by Aleron Ives » Sun Sep 18, 2011 2:22 pm

Where do you propose to put the new files?

Remember that the Dreamcast has a dinky amount of RAM, and all of it is used for various game files as you're playing a game, which means it can't be used for other things. Textures take up quite a bit of space, and there's nowhere to put them in the memory. The loader for PSO only works because the patching program is microscopic, and even finding a place in the RAM to put a program so tiny (< 1 KiB) took multiple rounds of searching and testing to find a place to use that wouldn't cause PSO to malfunction.

As for translations, altering the Dreamcast's text files is impossible, unless you want to rewrite the entire text file by hand. The Dreamcast uses a different format than PC does, so the unitxt editor doesn't work on the Dreamcast's text files. Due to the Dreamcast's use of ISO 8859-1 and Shift-JIS, it's also not even possible to make translations to most languages, because their character sets are not supported. PC can be translated to any language, because it uses Unicode.
"Fear the HUnewearl."
Image
User avatar
BlueCrab
The Crabby Overlord
The Crabby Overlord
Posts: 5441
Joined: Mon May 27, 2002 11:31 am
Location: Sailing the Skies of Arcadia
Has liked: 3 times
Been liked: 23 times
Contact:

Re: New Insane IDEA! (Sylverant PSO Patcher)

Post by BlueCrab » Sun Sep 18, 2011 6:53 pm

Aleron Ives pretty much hit the nail on the head here. Anything that involves any new files being used is pretty much completely out of the question. In addition, anything that involves non-trivial changes to the code would be very difficult, and might well also be out of the question.

Sylverant PSO Patcher is very space constrained (with the map fix patch in there, we only have about 300 extra bytes to do anything with and make sure that PSO doesn't notice the patcher). Everything has to be done in assembly (for obvious reasons), and its quite tedious to add new stuff to it that is non-trivial.
User avatar
Aleron Ives
DCEmu Nutter
DCEmu Nutter
Posts: 829
Joined: Wed Jan 05, 2011 2:15 pm
Location: California
Has liked: 0
Been liked: 4 times
Contact:

Re: New Insane IDEA! (Sylverant PSO Patcher)

Post by Aleron Ives » Sun Sep 18, 2011 9:57 pm

Since the reasons for writing the patcher in assembly might not be obvious for non-programmers, I'll add that when you write a program in a language like C and compile it into machine code, the way the compiler interprets your commands and converts them into machine code can sometimes lead to the program taking up more space than is strictly necessary to perform the task you wanted to accomplish.

Under normal circumstances, this isn't a problem, because the efficiency and space consumed by a program written in a language like C is usually tolerable.

The space constraints for the PSO patcher are so extreme that BlueCrab literally had to write every instruction by hand in Dreamcast assembly so as to not waste a single byte of space. The "overhead" that would have been generated by compiling the patcher normally would have been unacceptable, because there's simply no room available in the memory to waste any space at all. As BlueCrab noted, just the map fix alone consumes 33% of the available space, and that's only counting the patch itself, not the space needed for the program to actually apply the patch.
"Fear the HUnewearl."
Image
User avatar
BlueCrab
The Crabby Overlord
The Crabby Overlord
Posts: 5441
Joined: Mon May 27, 2002 11:31 am
Location: Sailing the Skies of Arcadia
Has liked: 3 times
Been liked: 23 times
Contact:

Re: New Insane IDEA! (Sylverant PSO Patcher)

Post by BlueCrab » Sun Sep 18, 2011 10:26 pm

Aleron Ives wrote:not the space needed for the program to actually apply the patch.
Which, thankfully, in the grand scheme of things, is only 64 bytes. :wink:

Just for fun, to show how amusing the code is for the patching routine... Here's all of it (the fun part is at the .patch_pso label):

Code: Select all

!   This file is part of Sylverant PSO Patcher
!   Copyright (C) 2011 Lawrence Sebald
!
!   This program is free software: you can redistribute it and/or modify
!   it under the terms of the GNU General Public License version 3 as
!   published by the Free Software Foundation.
!
!   This program is distributed in the hope that it will be useful,
!   but WITHOUT ANY WARRANTY; without even the implied warranty of
!   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
!   GNU General Public License for more details.
!
!   You should have received a copy of the GNU General Public License
!   along with this program.  If not, see <http://www.gnu.org/licenses/>.

!   GD-ROM syscall replacement function.
!   This is our vector for patching PSO after decryption. On the first GD-ROM
!   access after the main game binary is in RAM, this will trigger patching.
!   This gets copied to 0x8C008000. We have exactly 768 bytes there to do our
!   thing, which is plenty of space.
!
!   Before this gets copied, the various variables must be filled in.
    .globl      _gd_syscall

! List of variables that should be filled in...
    .globl      _patch_trigger_addr
    .globl      _patch_trigger_pattern
    .globl      _old_gd_vector
    .globl      _patches_count
    .globl      _patches
    .globl      _server_addr
    .globl      _patches_enabled
    .globl      _clear_and_load
    .globl      _gd_syscall_len

    .balign     4
_gd_syscall:
    ! Make sure we found something earlier
    mov.w       _patches_enabled, r0
    sts.l       pr, @-r15
    tst         #1, r0
    bt          .do_syscall
    ! Check the space that we need to look for the signature of the game binary.
    mov.l       _patch_trigger_addr, r1
    mov.l       _patch_trigger_pattern, r2
    mov.l       @r1, r1
    cmp/eq      r1, r2
    bt          .patch_pso
.do_syscall:
    ! Call on the original GD-ROM syscall to do the heavy lifting.
    mov.l       _old_gd_vector, r0
    jsr         @r0
    nop
    lds.l       @r15+, pr
    rts
    nop

    .balign     4
_patch_trigger_addr:
    .long       0
_patch_trigger_pattern:
    .long       0
_old_gd_vector:
    .long       0

.patch_pso:
    ! Copy any 32-bit patches we have...
    mov.l       _patches_count, r1
    mova        _patches, r0
    mov         #0, r2
    cmp/eq      r1, r2
    bt          .patch_server_name
.patches_loop:
    mov.l       @r0+, r3
    mov.l       @r0+, r2
    dt          r1
    mov.l       r2, @r3
    bf/s        .patches_loop
    ocbp        @r3
    ! Patch the server address
.patch_server_name:
    mova        .server_host, r0
    mov.l       _server_addr, r2
.server_copy_loop:
    mov.b       @r0+, r3
    cmp/eq      r1, r3
    mov.b       r3, @r2
    bf/s        .server_copy_loop
    add         #1, r2
    bra         .do_syscall
    nop

    .balign     4
_patches_count:
    .long       (.patches_end - _patches) >> 3
_patches:
    ! The maximum number of patches here is 9. The maximal list is shown in the
    ! comments. Not all versions will have all patches (and since EUv2 needs the
    ! map fix patch, but not the HL Check, they may not all match up with the
    ! comment either).
    .long       0, 0                    ! HL Check patch (rts; mov #0, r0)
    .long       0, 0                    ! Cave 1 map pointers (Ultimate)
    .long       0, 0                    ! Cave 1 map count (Ultimate)
    .long       0, 0                    ! Cave 3 map pointers (Ultimate)
    .long       0, 0                    ! Cave 3 map count (Ultimate)
    .long       0, 0                    ! Mine 1 map pointers (Ultimate)
    .long       0, 0                    ! Mine 1 map count (Ultimate)
    .long       0, 0                    ! Mine 2 map pointers (Ultimate)
    .long       0, 0                    ! Mine 2 map count (Ultimate)
.patches_end:
_server_addr:
    .long       0
.server_host:
    .string     "sylverant.net"
    .balign     2
_patches_enabled:
    .word       1                       ! We will reset this otherwise...
_clear_and_load:
    ! Disable interrupts
    mov.l       .no_ints_sr, r0
    ldc         r0, sr
    ! Clear out the loader
    mov.l       .loader_base, r0
    mov.l       .loader_end, r1
    mov         #0, r2
.clear_loop:
    mov.l       r2, @r0
    add         #4, r0
    cmp/eq      r0, r1
    bf          .clear_loop
    ! Clean up the various registers...
    ldc         r4, sr
    ldc         r5, vbr
    lds         r6, fpscr
    mov         r7, r15
    ! Jump to IP.BIN 
    mov.l       .bin_base, r0
    jmp         @r0
    nop
    .balign     4
.no_ints_sr:
    .long       0x500000F0
.loader_base:
    .long       0xACD00000
.loader_end:
    .long       0xAD000000
.bin_base:
    ! This is actually the first stage of the IP.BIN file.
    .long       0xAC00B800
    
_gd_syscall_len:
    .long       _gd_syscall_len - _gd_syscall
    .balign     4
User avatar
Whithil XBR
DCEmu Cool Newbie
DCEmu Cool Newbie
Posts: 15
Joined: Tue Jul 05, 2011 3:37 pm
Has liked: 0
Been liked: 0

Re: New Insane IDEA! (Sylverant PSO Patcher)

Post by Whithil XBR » Mon Sep 19, 2011 8:10 am

ImageImage

ok, ok... it seems that was not a good idea...

But I believe we'll be able to do something, maybe using the Dreamcast SD Card Loader, or whatever...Image

Anyway... Thank you guys :grin:

Image
User avatar
Whithil XBR
DCEmu Cool Newbie
DCEmu Cool Newbie
Posts: 15
Joined: Tue Jul 05, 2011 3:37 pm
Has liked: 0
Been liked: 0

Re: New Insane IDEA! (Sylverant PSO Patcher)

Post by Whithil XBR » Mon Sep 19, 2011 8:27 am

BlueCrab wrote:
Aleron Ives wrote:not the space needed for the program to actually apply the patch.
Which, thankfully, in the grand scheme of things, is only 64 bytes. :wink:

Just for fun, to show how amusing the code is for the patching routine... Here's all of it (the fun part is at the .patch_pso label):

Code: Select all

!   This file is part of Sylverant PSO Patcher
!   Copyright (C) 2011 Lawrence Sebald
!
!   This program is free software: you can redistribute it and/or modify
!   it under the terms of the GNU General Public License version 3 as
!   published by the Free Software Foundation.
!
!   This program is distributed in the hope that it will be useful,
!   but WITHOUT ANY WARRANTY; without even the implied warranty of
!   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
!   GNU General Public License for more details.
!
!   You should have received a copy of the GNU General Public License
!   along with this program.  If not, see <http://www.gnu.org/licenses/>.

!   GD-ROM syscall replacement function.
!   This is our vector for patching PSO after decryption. On the first GD-ROM
!   access after the main game binary is in RAM, this will trigger patching.
!   This gets copied to 0x8C008000. We have exactly 768 bytes there to do our
!   thing, which is plenty of space.
!
!   Before this gets copied, the various variables must be filled in.
    .globl      _gd_syscall

! List of variables that should be filled in...
    .globl      _patch_trigger_addr
    .globl      _patch_trigger_pattern
    .globl      _old_gd_vector
    .globl      _patches_count
    .globl      _patches
    .globl      _server_addr
    .globl      _patches_enabled
    .globl      _clear_and_load
    .globl      _gd_syscall_len

    .balign     4
_gd_syscall:
    ! Make sure we found something earlier
    mov.w       _patches_enabled, r0
    sts.l       pr, @-r15
    tst         #1, r0
    bt          .do_syscall
    ! Check the space that we need to look for the signature of the game binary.
    mov.l       _patch_trigger_addr, r1
    mov.l       _patch_trigger_pattern, r2
    mov.l       @r1, r1
    cmp/eq      r1, r2
    bt          .patch_pso
.do_syscall:
    ! Call on the original GD-ROM syscall to do the heavy lifting.
    mov.l       _old_gd_vector, r0
    jsr         @r0
    nop
    lds.l       @r15+, pr
    rts
    nop

    .balign     4
_patch_trigger_addr:
    .long       0
_patch_trigger_pattern:
    .long       0
_old_gd_vector:
    .long       0

.patch_pso:
    ! Copy any 32-bit patches we have...
    mov.l       _patches_count, r1
    mova        _patches, r0
    mov         #0, r2
    cmp/eq      r1, r2
    bt          .patch_server_name
.patches_loop:
    mov.l       @r0+, r3
    mov.l       @r0+, r2
    dt          r1
    mov.l       r2, @r3
    bf/s        .patches_loop
    ocbp        @r3
    ! Patch the server address
.patch_server_name:
    mova        .server_host, r0
    mov.l       _server_addr, r2
.server_copy_loop:
    mov.b       @r0+, r3
    cmp/eq      r1, r3
    mov.b       r3, @r2
    bf/s        .server_copy_loop
    add         #1, r2
    bra         .do_syscall
    nop

    .balign     4
_patches_count:
    .long       (.patches_end - _patches) >> 3
_patches:
    ! The maximum number of patches here is 9. The maximal list is shown in the
    ! comments. Not all versions will have all patches (and since EUv2 needs the
    ! map fix patch, but not the HL Check, they may not all match up with the
    ! comment either).
    .long       0, 0                    ! HL Check patch (rts; mov #0, r0)
    .long       0, 0                    ! Cave 1 map pointers (Ultimate)
    .long       0, 0                    ! Cave 1 map count (Ultimate)
    .long       0, 0                    ! Cave 3 map pointers (Ultimate)
    .long       0, 0                    ! Cave 3 map count (Ultimate)
    .long       0, 0                    ! Mine 1 map pointers (Ultimate)
    .long       0, 0                    ! Mine 1 map count (Ultimate)
    .long       0, 0                    ! Mine 2 map pointers (Ultimate)
    .long       0, 0                    ! Mine 2 map count (Ultimate)
.patches_end:
_server_addr:
    .long       0
.server_host:
    .string     "sylverant.net"
    .balign     2
_patches_enabled:
    .word       1                       ! We will reset this otherwise...
_clear_and_load:
    ! Disable interrupts
    mov.l       .no_ints_sr, r0
    ldc         r0, sr
    ! Clear out the loader
    mov.l       .loader_base, r0
    mov.l       .loader_end, r1
    mov         #0, r2
.clear_loop:
    mov.l       r2, @r0
    add         #4, r0
    cmp/eq      r0, r1
    bf          .clear_loop
    ! Clean up the various registers...
    ldc         r4, sr
    ldc         r5, vbr
    lds         r6, fpscr
    mov         r7, r15
    ! Jump to IP.BIN 
    mov.l       .bin_base, r0
    jmp         @r0
    nop
    .balign     4
.no_ints_sr:
    .long       0x500000F0
.loader_base:
    .long       0xACD00000
.loader_end:
    .long       0xAD000000
.bin_base:
    ! This is actually the first stage of the IP.BIN file.
    .long       0xAC00B800
    
_gd_syscall_len:
    .long       _gd_syscall_len - _gd_syscall
    .balign     4
mmm.. It's really interesting...Image
I don't really understand it at all.. But I think I got an idea of how it works.

Great job, guysImage
User avatar
shadowrod
DCEmu Freak
DCEmu Freak
Posts: 59
Joined: Mon Dec 06, 2010 4:09 pm
Has liked: 0
Been liked: 0

Re: New Insane IDEA! (Sylverant PSO Patcher)

Post by shadowrod » Tue Sep 20, 2011 6:57 am

Hey Aleron and about making a patcher for skins or something else uselful for pso gc, on sd or moded gamecube? I´m not defending piracy or something, it´s just a bit of curiosity...I dunno if the amount of ram in Gc memory is enough either.
Post Reply