Author Topic: Hi!  (Read 1069 times)

Offline jan_klaassen

  • FBA Dev
  • ******
  • Posts: 315
  • Karma: +10/-0
« on: December 16, 2016, 09:46:25 AM »
Hi! It's me. Long time no see.

It's rather nice to see FBA is still going -- I had no idea. I started to do some work on my old source lately, and you seem to have based yours on an old release with just my neo-geo CD emulation added. So it seems I might have some code you'd like include.

What's your choice of version control system? I use Mercurial myself.

One of the things I wanted to tackle was some cleanup and modernisation. To that effect, Perl is out and Python is in (I'll convert the perl scripts). Here's a python script that removes the annoying and outdated tchar.h rubbish and replaces it with the regular wchar_t equivalents. It leaves untouched a few macros and I think a single function call, so edit the macros in title.h and a few other bits that the compiler will complain about. Name this and run it from your FBA directory. N.B. Make sure to commit any changes or make a backup of your source before running this -- it overwrites all files it modifies.

Code: [Select]
import sys
import os.path
import re

class converter(object):

    def __init__(self):
        self.re_str = re.compile(r'_T\(\s*\"(?P<string>.*?)\"\)')
        self.re_chr = re.compile(r'_T\(\'(?P<string>.*?)\'\)')
        self.re_macro = re.compile(r'_T\((?P<string>[a-zA-Z0-9_()#]*?)\)')
        self.re_tc = re.compile(r'TCHAR')
        self.re_tcs = re.compile(r'_tcs(?P<string>[^(]*)')
        self.re_fnc = re.compile(r'_[a-zA-Z]*?t[a-zA-Z]*?(printf|scanf|fopen|remove|access|asctime)')
        self.re_get = re.compile(r'_f(putt|gett)[a-zA-Z]*?')
        self.re_txt = re.compile(r'_ist(space|digit)')

    def convertfile(self, file):

        def _str(m):
            return 'L"' +'string') + '"'
        def _chr(m):
            return 'L\'' +'string') + '\''
        def _macro(m):
        def _tc(m):
            return 'wchar_t'
        def _tcs(m):
            return 'wcs' +'string')
        def _fnc(m):
            return't', 'w', 1).replace('_fw', 'fw', 1).replace('_sw', 'sw', 1)
        def _get(m):
            return'_fgett', 'fgetw', 1).replace('_fputt', 'fputw', 1)
        def _txt(m):
            return'_ist', 'isw', 1)

        with open(file + ".tmp", "wt") as nf:
            changes = 0
            with open(file, "rt") as f:
                for line in f:
                    line = line.rstrip()
                    n = 0;
                    m = self.re_str.subn(_str, line)
                    if m[1] > 0:
                        line = m[0]
                        n += 1
                    m = self.re_chr.subn(_chr, line)
                    if m[1] > 0:
                        line = m[0]
                        n += 1
                    m = self.re_macro.subn(_macro, line)
                    if m[1] > 0:
                        line = m[0]
                        n += 1
                    m = self.re_tc.subn(_tc, line)
                    if m[1] > 0:
                        line = m[0]
                        n += 1
                    m = self.re_tcs.subn(_tcs, line)
                    if m[1] > 0:
                        line = m[0]
                        n += 1
                    m = self.re_fnc.subn(_fnc, line)
                    if m[1] > 0:
                        line = m[0]
                        n += 1
                    m = self.re_get.subn(_get, line)
                    if m[1] > 0:
                        line = m[0]
                        n += 1
                    m = self.re_txt.subn(_txt, line)
                    if m[1] > 0:
                        line = m[0]
                        n += 1
                    #if n > 0:
                    #   print(line)
                    changes += n
                    print(line, file=nf)

        if changes > 0:
            os.replace(file + ".tmp", file)
            os.remove(file + ".tmp")

    def convert(self, srcdir):
        for root, dir, files in os.walk(srcdir):
            print("processing: {root}...".format(root=root))
            for file in files:
                if not (file.endswith(".c") or file.endswith(".cpp") or file.endswith(".h")):
                self.convertfile("{root}\\{file}".format(root=root, file=file))

if __name__ == '__main__':

    src = sys.argv[1] if len(sys.argv) == 2 else "src"
    c = converter()

Offline Treble Winner

  • dontbeabarry
  • *
  • Posts: 1795
  • Karma: +0/-1001
Re: Hi!
« Reply #1 on: December 16, 2016, 11:09:36 AM »
Hi jan - hope you're keeping well.  :smilie:

We're using SVN on If you want to register an account I'll send an invite through.
Account of Barry Harris; the traitor.

Offline iq_132

  • Administrator
  • *****
  • Posts: 3572
  • Karma: +380/-0
  • What's a pac?
    • NeoSource
Re: Hi!
« Reply #2 on: December 16, 2016, 04:02:03 PM »
Holy cow. Jan_Klaassen is still alive! Welcome back (hopefully). :)

Offline JacKc

  • FBA Dev
  • ******
  • Posts: 1562
  • Karma: +51/-0
  • Sarah Connor !?
Re: Hi!
« Reply #3 on: December 17, 2016, 03:28:05 AM »
Hi Jan :)

Welcome back to the team !

Offline vbt

  • FBA Contributor
  • *****
  • Posts: 194
  • Karma: +9005/-0
Re: Hi!
« Reply #4 on: December 17, 2016, 08:06:47 PM »
we count on you Jan :)

Offline jan_klaassen

  • FBA Dev
  • ******
  • Posts: 315
  • Karma: +10/-0
Re: Hi!
« Reply #5 on: December 19, 2016, 09:43:38 AM »
Thanks for teh nice welcome everyone.
we count on you Jan
Please don't.  :biggrin:

So, to get down to business. I will install TortoiseSVN then, I guess. (Will PM account.) I'll have to see what's the easiest way of getting my sourcecode to you guys. Maybe bitbucket...

Most of the new stuff in my version is in the GUI. Some will be easy to port, some will be more inevolved. Here's a rough list:

  • There is preliminary support for using a hash to verify the integrity of romsets. For now it creates a RIPEMD160 hash for each loaded file. I intend to automate adding them to the data structures for each game eventually (with a python script) so it can verify them. I'll probably replace RIPEMD160 with BLAKE2 or SHA2/3.
  • You can set the part of the emulated screen that is visible for each game. There is a dialog box, and the settings are saved. This is useful for Neo Geo and a bunch of other games that don't aways use the full display.
  • There's an audio dsp module that can host VST 2 plugins. Useful for e.g. equalisers, harmonic exciters, etc. or, if you're working on sound code, various visualisations.
  • The progress dialog can display screenshots and it has a marquee mode for when you can't (or don't wish to bother) update the progress.
  • The image loading supports jpeg (via libjpeg) as well as png.
  • There is some image processing; a special algorithm for shrinking the screenshots displayed in the game selection dialog (because using the sampling theorem won't work well for that) and a (slow) cubic interpolator for enlarging.
  • There is a dialog that extracts info from history.dat and formats it nicely for display, along with a flyer image.
  • The game selection dialog has been updated. It has a right-click context menu for the games. I thought ther were too many checkboxes, so the filters have been changed to include hybrid edit/dropdown controls. These perform regular expression searches on various driver text fields (different combinations per control). The dropdowns contain named preset regular expressions, which are loaded from a text filem along with a default text file included as a resource to make them easy to change/add to. It uses the boost library for the regex searches.
  • The GUI runs in a separate thread. That enables a truly modeless menu, so the emulation can continue to run no matter what the GUI is doing, which is nice for e.g. kaillera and anything that can take avantage of parallel processing. Some of the BurnGet* functions have been updated since their use wasn't thread-safe (still needs some work to be completely thread-safe, but nothing that causes any problems for now).
  • The standard menu is part of a toolbar. MVS emulation gets an addional toolbar to display its LED coin counters and the marquee lights that show the active cartridge.
  • There is proper muti-monitor support, both in windowed and fullscreen modes. Vertical and horizontal games can go to different screens, which is nice if one of your screens is in portait mode. In windowed mode, windows/dialogs are centered and/or resized according to on the screen they appear on, and the blitters avoid using textures that are overly large.
  • You can set the DirectSound output device, and there are separate settings for fullscreen mode, so e.g. if you want to use a projector or big TV, the sound can follow the picture.

I'm working on a dialog box for the fullscreen settings.

That's a fair amount of stuff, so you'll have to see which parts to incorporate. Given how much our versions have diverged, I'm not sure a 3-way diff will be enough to port much of this, but who knows (I don't have a repository with nost of my changes, though I created a mercurial repository now). I'd  suggest that the person most familiar with yout GUI source code does the porting, with my help.

Other than Neo Geo CD, I didn't do much work on drivers. Neo Geo CD is very much a WIP, and I'll port my changes after I've finished with the things I'm working on (e.g. there's a CD interface for the new cd images).

Here's a screenshot of some of it in action:
« Last Edit: December 19, 2016, 09:51:47 AM by jan_klaassen »

Offline Ashura-X

  • Member
  • ***
  • Posts: 134
  • Karma: +0/-0
Re: Hi!
« Reply #6 on: December 20, 2016, 11:10:55 AM »
Ohhh!!!! The CPS2 Raster Effects master is back!!!!!

Nice to see you again Jan :)