bensweeneyonbass's Feed

bensweeneyonbass
05-06-2021 at 07:18 AM
9 Comments
Rate this Entry

MAME v.106 INP in a hex editor

@Almighty Dreadlock @Barthax @xelnia

I have a simple question about where to look in a WolfMAME v.106 INP when confirming settings. See the adjudication thread of my submission here.

Specifically this section of @terencew 's post:

DIP Info from source:
Code:
INPUT_PORTS_START( 64street )
***snipped***
INPUT_PORTS_END
***snipped***
Sample correct TG:
DSW2: offset 0x37, repeat every 0x7C, typical value 0xB9
- DSW2: 0x01 (Flip_Screen): 0x01 (Off)
- DSW2: 0x02 (Demo_Sounds): [not relevant]
- DSW2: 0x04 (Allow_Continue): 0x04 (On)
- DSW2: 0x18 (Difficulty): 0x18 (Normal)
- DSW2: 0x60 (Lives): 0x20 (3)
- DSW2: 0x80 (unused): [not relevant]

30: 00 00 00 FF 00 00 00 B9 00 00 00 00 00 00 00 00 | ... ...¦........
B0: 00 00 00 B9 00 00 00 00 00 00 00 00 00 00 00 00 | ...¦............
120: 00 00 00 FF 00 00 00 FF 00 00 00 FF 00 00 00 B9 | ... ... ... ...¦


^Is the above bold section of three lines the lines of the INP that describe what the DIP settings are?


That's how I'm reading it, and if that's the case, then I would totally be comfortable at least checking v.106 settings (although not a lot of v.106 runs coming in these days). Thank you for your time!

Thanksdatagod, JJT_Defender thanked this post
Likeswwdkong, JJT_Defender liked this post
Comments
  1. bensweeneyonbass's Avatar

    I would only be checking INPs of games that have already been adjudicated here during TGSAP as a v.106 submission. That would allow me to compare existing checks to current INPs in a hex editor.

    Likesdatagod liked this post
  2. bensweeneyonbass's Avatar

    Oh also it would allow someone to guess-and-check at the settings of a submitted INP by recording INPs of their own at various settings and comparing these lines of code. I know that's clumsy and the check.bat is tidier but if it's accessible for even a few more people that'll be a benefit.

  3. Barthax's Avatar

    Brief background: Computers work in binary (base 2) and humans work with binary really badly so the next-nearest options are Octal (base 8) and Hexadecimal (base 16). Octal is typically written with a leading zero: 010 is the number 8 in Decimal (there is no visual numbers 8 or 9 in Octal). This leading zero scenario is pretty misleading for humans so it's best to stick with Hexadecimal. Hexadecimal (base 16) values are typically written with a 0x prefix: 0x37 - 0x10 is 16 in Decimal (numbers are 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F - yes, they are numbers in Hexadecimal). Modern computers store data in bytes-based boundaries which hold Decimal numbers 0 through 255 (-128 to +127 if signed) - these are 0x00 to 0xFF in Hexadecimal.

    OK, so the example for the dip switch set MAME refers to as DSW2 is first seen at the file offset of 0x37. The file starts at zero - 0x00 - so the second byte in the file is offset 1 (0x01). The example shows the line offset first and as this is a stereotypical hexadecimal dump (16 bytes per line of ASCII, 1 byte each pair of numbers) there are no 0x prefixes anywhere but all values are hexadecimal. The first example line begins 30: so this is offset 0x30 in the file and the rest of the line are the 16 bytes which begin at that offset. DSW2 is offset 0x37 - positional count across & we get the value 0xB9.

    The rest of the DSW2 description are masks and then values of the dips. We're best with binary to figure out the visual of masks (I know, humans don't work well with binary but you'll soon see it's actualy 8, 4, 2 & 1 - not 0s and 1s). Convert the 0xB9 to binary (best shown in "nibbles": 4 bits each):

    1011 1001

    The first dip switch has a mask ("- DSW2: 0x01") of 0x01. A mask is a positional indicator of what is relevant. In binary this 0x01 is:

    0000 0001

    Position the mask against the value (using M instead of 1 for the Mask):

    1011 1001

    000 000M

    So for this dip switch only the right-most bit is relevant - which has a value of 1. We then consult the end of the dip switch to find out what value is expected: 0x01 (Off). Compare the two & that confirms the Flip Screen is off at that point in the example INP.


    - DSW2: 0x02 (Demo_Sounds): [not relevant]

    0x02 is the bit to the left of the right-most:

    0000 0010

    ... which is not set in the 0xB9 value:

    1011 1001

    000 00M0

    Therefore there's a value of 0 for that dip switch but it's not relevant as it's whether there are demo sounds.


    - DSW2: 0x04 (Allow_Continue): 0x04 (On)

    0x04 is the next one to the left:

    0000 0100

    From B9:

    1011 1001

    0000 0M00

    The value from the B9 for this bit is zero so we know the Continues were Off, not On in the example INP.


    - DSW2: 0x18 (Difficulty): 0x18 (Normal)

    0x18 might look complicated when you first learn this stuff but it's the left-most bit of the second coupled with the right-most bit of the first:

    0001 1000

    Notice you didn't actually need to learn the position of 1 because you'd learned it above... Four values to remember in nibble-based binary:

    8421

    .. .repeat for two nibbles or one byte:

    8421 8421

    ... back to the B9 value & both of these positions are 1, so combine them in binary for:

    1011 1001

    000M M000

    0001 1000

    = 0x18. :D


    - DSW2: 0x60 (Lives): 0x20 (3)

    Might have to engage the brain a little to realise that 0x60 is made up of 4+2... the same as masking both 0x40 and 0x20.

    1011 1001

    0MM0 0000

    0010 0000

    = 0x20.

    Quick & dirty primer. Now do the same with the actual INP. HTH

    Updated 05-06-2021 at 10:00 AM by Barthax
  4. bensweeneyonbass's Avatar

    This is excellent thanks a lot Pete.


    So - there are two things going on.


    1) Determining where in the INP the Normal Value is and looking to see what it is as it repeats itself throughout the INP (as long as the settings aren't changed mid-inp which is why the beginning, middle, and end are usually posted in the check).


    2) Computing a DIP switch value from the Normal Value for each DIP switch based on its mask. The computed value corresponds to a logical setting like On/Off or Easy/Medium/Hard.


    What I'm getting is this - If I didn't know what this information was (the offset and the repetition interval, and what values corresponded to what DIP switches/settings) I would be unable to inspect the INP and pull the Normal Value, and even if I could guess at what the normal value is based on a good guess I still would be unable to interpret that because I wouldn't know what masks and values exist for the switches/settings.


    Fortunately you host a massive body of this information here and I cannot tell you how meaningful this info is. Thanks to every single person who has contributed to this data set as well.


    Thanks very much for giving us the quick & dirty.

    LikesBarthax, redelf liked this post
  5. Barthax's Avatar

    Quote Originally Posted by bensweeneyonbass

    This is excellent thanks a lot Pete.


    So - there are two things going on.


    1) Determining where in the INP the Normal Value is and looking to see what it is as it repeats itself throughout the INP (as long as the settings aren't changed mid-inp which is why the beginning, middle, and end are usually posted in the check).


    Yes, exactly. What some people do is change the configuration very shortly after recording. This works fine for any game with NVRAM and software settings - they'll have to show the changes as part of the visual element of the recording. However, for inputs (name of the INP, after all!) and hardware DIPs (and, I think from memory, there's a rare logical setting represented as a "dip") they are stored in the INP. For these hardware DIPs, changing them mid-recording might not actually change the behaviour. So, as far as the human is concerned and the INP, there's proof the DIP was changed but for the code of the game, those DIPs were read once at boot up and then ignored...

    Logically, therefore, if you can find a change in DIP settings in the INP part-way through the file, you still have further investigation into the game to know whether or not that actually had any effect on the game play.

    [/quote]


    Quote Originally Posted by bensweeneyonbass

    2) Computing a DIP switch value from the Normal Value for each DIP switch based on its mask. The computed value corresponds to a logical setting like On/Off or Easy/Medium/Hard.


    What I'm getting is this - If I didn't know what this information was (the offset and the repetition interval, and what values corresponded to what DIP switches/settings) I would be unable to inspect the INP and pull the Normal Value, and even if I could guess at what the normal value is based on a good guess I still would be unable to interpret that because I wouldn't know what masks and values exist for the switches/settings.


    Fortunately you host a massive body of this information here and I cannot tell you how meaningful this info is. Thanks to every single person who has contributed to this data set as well.


    Thanks very much for giving us the quick & dirty.

    So obviously the code for each individual game is likely to be different and also the version of MAME may have changed code from a prior version. So be certain of the version of MAME & go back to the original MAME source to be absolutely certain. Thankfully, each game has, buried in the source code, a definition like the following:

    INPUT_PORTS_START( 1942 )

    Taken from: https://github.com/Barthax/TGDips/blob/master/dips/106/1942.c (URL for this quick & simple example).

    This begins the set of DIPs which get stored in the INP (and other information!). That set of information gets ended with:

    INPUT_PORTS_END

    Everything in between is likely to represent something in the INP. 1942 makes this easy as each piece of information (typically covering 4 bytes in the INP) is described:

    PORT_START_TAG("IN0")
    PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_START1 )
    PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_START2 )
    PORT_BIT( 0x0c, IP_ACTIVE_LOW, IPT_UNUSED )
    PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_SERVICE1 )
    PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED )
    PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_COIN2 )
    PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_COIN1 )

    PORT_START_TAG("IN1")
    PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY
    PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY
    PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY
    PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY
    PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 )
    PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 )
    PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED )

    PORT_START_TAG("IN2")
    PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_COCKTAIL
    PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_COCKTAIL
    PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_COCKTAIL
    PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_COCKTAIL
    PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_COCKTAIL
    PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_COCKTAIL
    PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED )

    PORT_START_TAG("DSWA")
    PORT_DIPNAME( 0x07, 0x07, DEF_STR( Coin_A ) )
    PORT_DIPSETTING( 0x01, DEF_STR( 4C_1C ) )
    PORT_DIPSETTING( 0x02, DEF_STR( 3C_1C ) )
    PORT_DIPSETTING( 0x04, DEF_STR( 2C_1C ) )
    PORT_DIPSETTING( 0x07, DEF_STR( 1C_1C ) )
    PORT_DIPSETTING( 0x03, DEF_STR( 2C_3C ) )
    PORT_DIPSETTING( 0x06, DEF_STR( 1C_2C ) )
    PORT_DIPSETTING( 0x05, DEF_STR( 1C_4C ) )
    PORT_DIPSETTING( 0x00, DEF_STR( Free_Play ) )
    PORT_DIPNAME( 0x08, 0x00, DEF_STR( Cabinet ) )
    PORT_DIPSETTING( 0x00, DEF_STR( Upright ) )
    PORT_DIPSETTING( 0x08, DEF_STR( Cocktail ) )
    PORT_DIPNAME( 0x30, 0x30, DEF_STR( Bonus_Life ) )
    PORT_DIPSETTING( 0x30, "20K 80K 80K+" )
    PORT_DIPSETTING( 0x20, "20K 100K 100K+" )
    PORT_DIPSETTING( 0x10, "30K 80K 80K+" )
    PORT_DIPSETTING( 0x00, "30K 100K 100K+" )
    PORT_DIPNAME( 0xc0, 0x40, DEF_STR( Lives ) )
    PORT_DIPSETTING( 0x80, "1" )
    PORT_DIPSETTING( 0x40, "2" )
    PORT_DIPSETTING( 0xc0, "3" )
    PORT_DIPSETTING( 0x00, "5" )

    PORT_START_TAG("DSWB")
    PORT_DIPNAME( 0x07, 0x07, DEF_STR( Coin_B ) )
    PORT_DIPSETTING( 0x01, DEF_STR( 4C_1C ) )
    PORT_DIPSETTING( 0x02, DEF_STR( 3C_1C ) )
    PORT_DIPSETTING( 0x04, DEF_STR( 2C_1C ) )
    PORT_DIPSETTING( 0x07, DEF_STR( 1C_1C ) )
    PORT_DIPSETTING( 0x03, DEF_STR( 2C_3C ) )
    PORT_DIPSETTING( 0x06, DEF_STR( 1C_2C ) )
    PORT_DIPSETTING( 0x05, DEF_STR( 1C_4C ) )
    PORT_DIPSETTING( 0x00, DEF_STR( Free_Play ) )
    PORT_SERVICE( 0x08, IP_ACTIVE_LOW )
    PORT_DIPNAME( 0x10, 0x10, DEF_STR( Flip_Screen ) )
    PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
    PORT_DIPSETTING( 0x00, DEF_STR( On ) )
    PORT_DIPNAME( 0x60, 0x60, DEF_STR( Difficulty ) )
    PORT_DIPSETTING( 0x40, DEF_STR( Easy ) )
    PORT_DIPSETTING( 0x60, DEF_STR( Normal ) )
    PORT_DIPSETTING( 0x20, "Difficult" )
    PORT_DIPSETTING( 0x00, "Very Difficult" )
    PORT_DIPNAME( 0x80, 0x80, "Freeze" )
    PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
    PORT_DIPSETTING( 0x00, DEF_STR( On ) )

    Five sets of information = 24 bytes that should always be together in the INP. As these sets are individually only one byte each (0x & two digits), they will be recorded in the first of the four bytes - a single set is B9 00 00 00 from the example INP further up. Those three pairs of 00 will be consistent throughout the INP in the pattern.

    You should also see from the above the "dumbing down" we made into the other files on a per-rules basis.

    From https://github.com/Barthax/TGDips/blob/master/dips/106/1942.txt :

    DSWA: offset 0x2F, repeat every 0x7C, typical value 0xF7
    - DSWA: 0x07 (Coin_A): [not relevant]
    - DSWA: 0x08 (Cabinet): [not relevant]
    - DSWA: 0x30 (Bonus_Life): 0x30 (20K 80K 80K+)
    - DSWA: 0xc0 (Lives): 0xc0 (3)

    DSWB: offset 0x33, repeat every 0x7C, typical value 0xFF
    - DSWB: 0x07 (Coin_B): [not relevant]
    - DSWB: 0x08 (service): [not relevant]
    - DSWB: 0x10 (Flip_Screen): 0x10 (Off)
    - DSWB: 0x60 (Difficulty): 0x60 (Normal)
    - DSWB: 0x80 (Freeze): 0x80 (Off)


    In practice, set the DIPs to something you know how to find & you should soon see the pattern with some practice in a test INP.

    Thanksredelf, bensweeneyonbass thanked this post
    Updated 05-06-2021 at 12:57 PM by Barthax
  6. bensweeneyonbass's Avatar

    Am I correct in assuming that 0x7C is the length of one frame?

    LikesBarthax liked this post
  7. Barthax's Avatar

    Quote Originally Posted by bensweeneyonbass

    Am I correct in assuming that 0x7C is the length of one frame?

    In this case, yes. :) Different games will have a different frame length.

    Thanksbensweeneyonbass thanked this post
  8. bensweeneyonbass's Avatar

    That's what I wanted to know. Thank you. Also here's another thing - in the interest of computing what acceptable values (per track rules) exist for DSW2 in the 64street example first posed, I have a table here that I believe may illustrate a question I have. Are all the following DSW2 values "acceptable" if found? I understand some may not make the game playable (as would be the case with the service switch or flip screen) but, barring that, I am inclined to think that B9 is what we expect to see but any of the following would be ok as long as the game play does not break the rules (as would be the case with Allow Continues=YES but no continues were used):



    EDIT: I didn't consider Flip Screen to be OFF or ON but I meant to.


    FURTHER EDIT: This is bordering on a TGSAP discussion and not an INP analysis discussion so we can skip what would be defined as "acceptable." I guess I'm just hashing out an example in the case I didn't know what the Typical Value of DSW2 was for the TG track rules, and I wanted to whittle down what the possible values were that I'm looking for to be repeating.

    LikesBarthax liked this post
    Updated 05-07-2021 at 05:59 AM by bensweeneyonbass
  9. Barthax's Avatar

    Quote Originally Posted by bensweeneyonbass

    That's what I wanted to know. Thank you. Also here's another thing - in the interest of computing what acceptable values (per track rules) exist for DSW2 in the 64street example first posed, I have a table here that I believe may illustrate a question I have. Are all the following DSW2 values "acceptable" if found? I understand some may not make the game playable (as would be the case with the service switch or flip screen) but, barring that, I am inclined to think that B9 is what we expect to see but any of the following would be ok as long as the game play does not break the rules (as would be the case with Allow Continues=YES but no continues were used):



    EDIT: I didn't consider Flip Screen to be OFF or ON but I meant to.


    FURTHER EDIT: This is bordering on a TGSAP discussion and not an INP analysis discussion so we can skip what would be defined as "acceptable." I guess I'm just hashing out an example in the case I didn't know what the Typical Value of DSW2 was for the TG track rules, and I wanted to whittle down what the possible values were that I'm looking for to be repeating.


    Essentially you're correct on all counts:

    - Those are all valid for meeting the 3 Lives, Normal difficulty requirement.

    - Service mode might not give you any gameplay & others may simply not be easy to play due tothe slip screen (but also MAME could rectify the flip from the command line also!).

    - There's the TGSAP human perception of continues: is "Allow Continue off" the same as not using continues with "Allow Continue on"?! :P

    Likesbensweeneyonbass liked this post
Join us