Jump to content



Photo
- - - - -

How to use one ROM for multiple tables


  • Please log in to reply
21 replies to this topic

#1 koadic

koadic

    Pinball Fan

  • VIP
  • 1,363 posts
  • Location:Omaha, NE, USA

  • Flag: United States of America

  • Favorite Pinball: Addams Family/Fish Tales/Medieval Madness



Contributor

Posted 14 May 2012 - 07:12 AM

Ok, Destruk has updated the core.vbs file (v3.35) which includes a version of my code below... If you have the new core.vbs file, you only need to add a single line to handle different .nv files for tables that use the same rom. In the Table_init section, in between the controller.gamename and controller.run commands, add NVOffset (n) where n is 1-10 and defines which version you want to set that table to use.

(Shortened for simplicity's sake)
CODE
With Controller
    .GameName cGameName
    NVOffset (1)
    .Run
End With


Explanation of how it works:
- Upon adding NVOffset(n), it will check if a table using the same rom has been previously run with a different version, and if so, backup the .nv file for the previous version run
- It will then create/rename a placeholder .txt file that specifies the version being run (so it can be checked on future runs).
- And finally, if changing versions, it will grab the last backed up .nv file for the version being run (if it exists) and copy that to the current .nv file



Original post, kept for posterity's sake
_______________________________________________________________

The following will allow you to use a single ROM for multiple table and have it behave as if it were a completely separate ROM for each. This its handy for those odd tables that use the same ROM as a different table, or you just have different versions of the same table and want to keep separate high scores for each. In the following code, the version is set to 0, as this allows the code to be copied and pasted into any table, new or old without effecting anything by default.

Create the following at the end of the table script (or almost anywhere really) in each table that you want to use this functionality, then just set the version number to 1, 2, etc. to have them keep separate nvrams
CODE
Sub NVCheck
Dim check,v,vv,nvpath
Const version = 0 'change this in other tables to call different versions of the nvram
nvpath = controller.installdir & "\nvram\"
Set check = CreateObject("Scripting.FileSystemObject")
For v=1 to 10 'check up to 10 possible versions using same rom, it's overkill, but can be changed to a lower number
If check.FileExists(nvpath & cGameName & " v" & v & ".txt") Then vv=v : exit For : End If
vv=0
Next
If vv=version or version = 0 Then
exit Sub
ElseIf vv=0 Then
check.CreateTextFile nvpath & cGameName & " v" & version & ".txt", True
exit Sub
Else
check.moveFile nvpath & cGameName & " v" & vv & ".txt", nvpath & cGameName & " v" & version & ".txt"
If check.FileExists(nvpath & cGameName & ".nv") Then
check.copyFile nvpath & cGameName & ".nv", nvpath & cGameName & " v" & vv & ".nv", True
End If
If check.FileExists(nvpath & cGameName & " v" & version & ".nv") Then
check.copyFile nvpath & cGameName & " v" & version & ".nv", nvpath & cGameName & ".nv", True
End If
End If
End Sub


and then add 'NVCheck' to call that Sub in the table init before pinmame starts up (either before controller.run, or the .run under 'with Controller', depending on the wording).... example:
CODE
Sub TAF_Init()

NVCheck
With Controller
.GameName = cGameName
If Err Then MsgBox "Can't start Game " & cGameName & vbNewLine & Err.Description:Exit Sub


This added script assumes there is a cGameName defined stating the rom used, and you will have to adjust the version numbers in the script for each separate table. You can set 2 tables to the same version and have a 3rd table set to a different one if you want. Any table using the same rom without this script addition will use the standard nvram file, which will be the one from the last version you ran. The alternate versions of the nvram only get created/updated when a different version is run.

Edited by koadic, 17 May 2012 - 02:47 AM.


#2 destruk

destruk

    VPF Veteran

  • VPF Staff
  • 6,307 posts
  • Location:Colorado Springs, CO

  • Flag: United States of America

  • Favorite Pinball: Ultrapin!



Posted 14 May 2012 - 05:09 PM

Very cool. smile.gif Thanks Koadic.

Build a fire, vipers love the heat.


#3 Wahreez McDermot

Wahreez McDermot

    Enthusiast

  • Members
  • PipPipPip
  • 126 posts
  • Location:Sugar Land, TX

  • Flag: United States of America

  • Favorite Pinball: I can't pick just one!

Posted 14 May 2012 - 09:12 PM

Very cool! Thanks a ton for the info. Will be nice being able to play the different versions of tables w/o crushing my high score on the 'harder' version.

#4 TedB

TedB

    Pinball Fan

  • Charter Member
  • 705 posts

  • Flag: Netherlands

  • Favorite Pinball: those with non virtual steel balls

Posted 15 May 2012 - 04:31 PM

Thanks! I have asked this question before and one of the answers was indeed similar to your solution (at first glance). Great to have this script, hopefully table authors will include it in their tables if they create a table that uses a shared rom. But even if they don't I can still use this script.

Edited by TedB, 15 May 2012 - 04:32 PM.


#5 koadic

koadic

    Pinball Fan

  • VIP
  • 1,363 posts
  • Location:Omaha, NE, USA

  • Flag: United States of America

  • Favorite Pinball: Addams Family/Fish Tales/Medieval Madness



Contributor

Posted 15 May 2012 - 10:38 PM

QUOTE (TedB @ May 15 2012, 11:31 AM) <{POST_SNAPBACK}>
Thanks! I have asked this question before and one of the answers was indeed similar to your solution (at first glance). Great to have this script, hopefully table authors will include it in their tables if they create a table that uses a shared rom. But even if they don't I can still use this script.


Yeah, I remember reading it too... this takes that batch/ahk script idea and incorporates directly into the table script so all you have to do is paste it into the table then set which 'version' you want it to be, or have it do nothing if the version is set to 0. While not idiot proof, I imagine it is still quite a bit simpler than those other methods, short of having a version of pinmame that will accept renamed roms.

#6 destruk

destruk

    VPF Veteran

  • VPF Staff
  • 6,307 posts
  • Location:Colorado Springs, CO

  • Flag: United States of America

  • Favorite Pinball: Ultrapin!



Posted 16 May 2012 - 12:25 AM

With a maximum allowed rom name of 8 characters and over 2000 individual romsets, how would you suggest it automatically accept renamed roms?

I agree this is probably the best solution available short of being able to compile your own vpm.

The other method, of having it 'guess what you want to run' would neither be efficient, or practical. The only sure solution I can see of allowing it to use any rom name for any nvram file would be to have pinmame save the name the script calls for, and then the table author defining what individual unzipped) roms to load, and then having a single rom.zip master file of 4GB in size with all the roms inside that, and use the called file to save the nvram as. - sounds kind of stupid that way, but it'd work. Alternately, have the table script define the nvram file name to use for the table, but then you'd have the risk of someone else's table using the same filename and screwing it up.

Of course, if you only run or use one table per romset name, then this all is a non-issue. smile.gif

Build a fire, vipers love the heat.


#7 koadic

koadic

    Pinball Fan

  • VIP
  • 1,363 posts
  • Location:Omaha, NE, USA

  • Flag: United States of America

  • Favorite Pinball: Addams Family/Fish Tales/Medieval Madness



Contributor

Posted 16 May 2012 - 01:33 AM

QUOTE (destruk @ May 15 2012, 07:25 PM) <{POST_SNAPBACK}>
With a maximum allowed rom name of 8 characters and over 2000 individual romsets, how would you suggest it automatically accept renamed roms?

I agree this is probably the best solution available short of being able to compile your own vpm.

The other method, of having it 'guess what you want to run' would neither be efficient, or practical. The only sure solution I can see of allowing it to use any rom name for any nvram file would be to have pinmame save the name the script calls for, and then the table author defining what individual unzipped) roms to load, and then having a single rom.zip master file of 4GB in size with all the roms inside that, and use the called file to save the nvram as. - sounds kind of stupid that way, but it'd work. Alternately, have the table script define the nvram file name to use for the table, but then you'd have the risk of someone else's table using the same filename and screwing it up.

Of course, if you only run or use one table per romset name, then this all is a non-issue. smile.gif


biggrin.gif I wasn't trying to imply it would be easy or practical, just that it would be the easiest option for the end user.

Was also thinking that this could be easily modified to possibly be put in the core.vbs or something by changing it to set a variable as controller.gamename instead cGameName directly (as some tables use different wording), then if wanted, you only add a line in the table script specifying the 'version' you want it to run as and a line to call the check after the rom name is specified and before the controller.run command ... nothing added, the subroutine doesn't get called. Such as below...

Inside core.vbs or something
CODE
Sub NVCheck
Dim check,v,vv,nvpath,rom
Const version = 0 'change this in other tables to call different versions of the nvram 'remove this line as it will be added in table script
rom = controller.gamename 'add this line instead
nvpath = controller.installdir & "\nvram\"
Set check = CreateObject("Scripting.FileSystemObject")
For v=1 to 10 'check up to 10 possible versions using same rom, it's overkill, but can be changed to a lower number
If check.FileExists(nvpath & rom & " v" & v & ".txt") Then vv=v : exit For : End If
vv=0
Next
If IsEmpty(Eval("version"))=true Then Exit Sub 'this checks to see if version is defined, and if not, exit sub
If vv=version or version = 0 Then Exit Sub
ElseIf vv=0 Then
check.CreateTextFile nvpath & rom & " v" & version & ".txt", True
exit Sub
Else
check.moveFile nvpath & rom & " v" & vv & ".txt", nvpath & rom & " v" & version & ".txt"
If check.FileExists(nvpath & rom & ".nv") Then
check.copyFile nvpath & rom & ".nv", nvpath & rom & " v" & vv & ".nv", True
End If
If check.FileExists(nvpath & rom & " v" & version & ".nv") Then
check.copyFile nvpath & rom & " v" & version & ".nv", nvpath & rom & ".nv", True
End If
End If
End Sub

Then you only need to add 2 lines to enable alternate nvram versions as the bulk will already be in the core.vbs... NVCheck can be added to all new tables by default with no ill effects (placed as below), and the user can add the version later if feature is wanted/needed. Example additions in red:
CODE
Sub Table1_Init
const version=1 'specify which version of nvram this table will run, think you can place this anywhere, just placed here for compactness
vpmInit Me
With Controller
.GameName = cGameName
If Err Then MsgBox "Can't start Game" & cGameName & vbNewLine & Err.Description:Exit Sub
NVCheck 'called after .GameName is specified but before .Run, then doesn't matter what is used to specify the rom name
.Games(cGameName).Settings.Value("rol")=0
.HandleKeyboard = 0
.ShowTitle = 0
.ShowDMDOnly = 1
.ShowFrame = 0
.HandleMechanics = 1
.Hidden = 0
On Error Resume Next
.Run GetPlayerHWnd
If Err Then MsgBox Err.Description
End With

On Error Goto 0

Edited by koadic, 16 May 2012 - 10:00 PM.


#8 destruk

destruk

    VPF Veteran

  • VPF Staff
  • 6,307 posts
  • Location:Colorado Springs, CO

  • Flag: United States of America

  • Favorite Pinball: Ultrapin!



Posted 16 May 2012 - 02:42 AM

I would agree with that change. smile.gif
Excellent work btw.

Build a fire, vipers love the heat.


#9 koadic

koadic

    Pinball Fan

  • VIP
  • 1,363 posts
  • Location:Omaha, NE, USA

  • Flag: United States of America

  • Favorite Pinball: Addams Family/Fish Tales/Medieval Madness



Contributor

Posted 16 May 2012 - 04:30 PM

Hey Destruk, quick question which maybe you could answer... as I have said before, I really don't have any programming background, I'm just a guy smart enough to 'google, copy, paste' stuff together to get stuff to work the way I want it to. I was thinking about this...

QUOTE (destruk @ May 15 2012, 07:25 PM) <{POST_SNAPBACK}>
Alternately, have the table script define the nvram file name to use for the table, but then you'd have the risk of someone else's table using the same filename and screwing it up.


Is there an easy way to add the functionality of the script I have above directly into VPinMame? and thus just call it by adding a 'Controller.version 1' (or calling it .nvoffset to be more specific to what it is) in there somewhere? then it is one simple addition to the table script, nothing needed to be added by the table authors at all unless they know the table shares a single available rom with another table, and then they can set each table to separate versions from the get go. If more than one table is set to use the same nvram file, I don't see it as being a big deal as that is what is happening now, but can also be changed by the end user if desired.

I tried looking at the VPinMame code previously just to look, and I wouldn't know where to start even... hell, I couldn't even get it to compile (not that I really spent much time looking into what the issue was).

edit: slight rewording of what I was trying to say

Edited by koadic, 16 May 2012 - 05:18 PM.


#10 destruk

destruk

    VPF Veteran

  • VPF Staff
  • 6,307 posts
  • Location:Colorado Springs, CO

  • Flag: United States of America

  • Favorite Pinball: Ultrapin!



Posted 16 May 2012 - 06:14 PM

Tom Haukapt was the creator of the dll com object windows interface. Sadly, he's the only one who really knows how that works in the pinmame dev team, and he's no longer active programming for it. So I have no idea how difficult it would be to add it to the vpm object. However, adding it to core.vbs is straightforward and wouldn't be a problem to include in a future update. I'll merge it in now.

-edit- Please test this out with your table(s) and if it works ok, then we'll add it to the official release zip.

Edited by destruk, 16 May 2012 - 06:27 PM.

Build a fire, vipers love the heat.


#11 koadic

koadic

    Pinball Fan

  • VIP
  • 1,363 posts
  • Location:Omaha, NE, USA

  • Flag: United States of America

  • Favorite Pinball: Addams Family/Fish Tales/Medieval Madness



Contributor

Posted 16 May 2012 - 07:06 PM

QUOTE (destruk @ May 16 2012, 01:14 PM) <{POST_SNAPBACK}>
Tom Haukapt was the creator of the dll com object windows interface. Sadly, he's the only one who really knows how that works in the pinmame dev team, and he's no longer active programming for it. So I have no idea how difficult it would be to add it to the vpm object. However, adding it to core.vbs is straightforward and wouldn't be a problem to include in a future update. I'll merge it in now.

-edit- Please test this out with your table(s) and if it works ok, then we'll add it to the official release zip.


Seems to work fine, using 2 different copies of the same table, one with version 1 set, and other with version 2, and adding NVCheck. Upon starting the v1 first, it creates the identifier v1.txt file letting it know which was the last to run (no previous version text file, so no change to any .nv file yet, it only creates the .txt), then upon starting v2, it changes the v1.txt file to a v2.txt file (again, to identify which was the last version run, so it knows whether or not to backup the existing nvram), then creates a v1.nv for backup, and if it exists, copies the v2.nv to the main .nv. Then going back to v1, it again renames the v2.txt file to v1, and then backs up the .nv to the v2.nv, and copies the v1.nv to the main .nv, so it seems like it is working just fine. (If you can follow what I just wrote biggrin.gif)

All this with adding a Const version = 1 (can do a dim version: version = 1, but simpler to just define it as a constant unless you build it into a dip menu) and putting NVCheck in the table_init, between controller.gamename and controller.run.

IN OTHER WORDS - Everything is good to go... when using the new version of the core.vbs posted above, just add the two lines to enable it.

EDIT: Had a quick thought..., stay tuned for updates...
updates- for the official release, what do you think about this? First change name slightly incase anyone has already copy/pasted into their tables so no conflict... will use NVOffset instead
CODE
Sub NVOffset (version)
Dim check,v,vv,nvpath,rom
rom = controller.gamename
nvpath = controller.installdir & "\nvram\"
Set check = CreateObject("Scripting.FileSystemObject")
For v=1 to 10 'check up to 10 possible versions using same rom, it's overkill, but can be changed to a lower number
If check.FileExists(nvpath & rom & " v" & v & ".txt") Then vv=v : exit For : End If
vv=0
Next
If vv=version or version = 0 Then Exit Sub
ElseIf vv=0 Then
check.CreateTextFile nvpath & rom & " v" & version & ".txt", True
exit Sub
Else
check.moveFile nvpath & rom & " v" & vv & ".txt", nvpath & rom & " v" & version & ".txt"
If check.FileExists(nvpath & rom & ".nv") Then
check.copyFile nvpath & rom & ".nv", nvpath & rom & " v" & vv & ".nv", True
End If
If check.FileExists(nvpath & rom & " v" & version & ".nv") Then
check.copyFile nvpath & rom & " v" & version & ".nv", nvpath & rom & ".nv", True
End If
End If
End Sub


Then all they should have to do is add 'NVOffset(1)' (or 2, 3, etc) in the table init instead of specifying a version, what do you think? will it work like that?

ReUpdate: Seems to work fine doing it this way, so only a single line needs to be added if done as above

Edited by koadic, 16 May 2012 - 09:58 PM.


#12 destruk

destruk

    VPF Veteran

  • VPF Staff
  • 6,307 posts
  • Location:Colorado Springs, CO

  • Flag: United States of America

  • Favorite Pinball: Ultrapin!



Posted 16 May 2012 - 07:47 PM

QUOTE (koadic @ May 16 2012, 01:06 PM) <{POST_SNAPBACK}>
EDIT: Had a quick thought..., stay tuned for updates... for the official release, what do you think about this? First change name slightly incase anyone has already copy/pasted into their tables so no conflict... will use NVOffset instead
CODE
Sub [color="#FF0000"]NVOffset (version)[/color]
    Dim check,v,vv,nvpath,rom

Then all they should have to do is add 'NVOffset(1)' (or 2, 3, etc) in the table init instead of specifying a version, what do you think? will it work like that?


Sounds good. In your experience, a global variable called "version" won't have any impact on a local variable named the same thing? I try not to duplicate variable declarations myself whether they are local or global.
"When you declare a variable within a procedure, the variable can only be accessed within that procedure. When the procedure exits, the variable is destroyed. These variables are called local variables. You can have local variables with the same name in different procedures, because each is recognized only by the procedure in which it is declared.
If you declare a variable outside a procedure, all the procedures on your page can access it. The lifetime of these variables starts when they are declared, and ends when the page is closed. " -- http://www.w3schools...t_variables.asp

Maybe just to be on the safe side, rename all the variables the routine uses with an nvcheck prefix just to avoid conflicts with other used variables in the table script, or change the nvcheck routine to be run as a class with private variables.
"Version" is a fairly common thing to have in a table script - whether that is a textbox, variable, or a delayed timer name. I don't think anyone uses "V" or "VV" smile.gif

nevermind...

found this -
3. Collision - If a variable is explicitly defined in a procedure code has the same name as a variable defined in the main code, the variable of the main code become in-accessible within this procedure.

So you're fine. I'll commit the change and upload a new vbs pack.

Build a fire, vipers love the heat.


#13 destruk

destruk

    VPF Veteran

  • VPF Staff
  • 6,307 posts
  • Location:Colorado Springs, CO

  • Flag: United States of America

  • Favorite Pinball: Ultrapin!



Posted 16 May 2012 - 07:58 PM

done. smile.gif

Build a fire, vipers love the heat.


#14 koadic

koadic

    Pinball Fan

  • VIP
  • 1,363 posts
  • Location:Omaha, NE, USA

  • Flag: United States of America

  • Favorite Pinball: Addams Family/Fish Tales/Medieval Madness



Contributor

Posted 16 May 2012 - 08:26 PM

Alright, so I guess that means anything explicitly defined inside a Sub will take precedence over anything defined outside the Sub. Is it then safe to assume that if it is defined outside the sub, the one inside the sub won't effect it? Like I said, I am a 'Google, Copy, Paste' guy, I only assumed that's how it would behave.

Edited by koadic, 16 May 2012 - 08:27 PM.


#15 rosve

rosve

    :)

  • VIP
  • 1,179 posts
  • Location:Always travelling around the world

  • Flag: Sweden

  • Favorite Pinball: Funhouse, Faces, Starship Troopers



Posted 16 May 2012 - 08:30 PM

QUOTE (koadic @ May 16 2012, 10:26 PM) <{POST_SNAPBACK}>
Alright, so I guess that means anything explicitly defined inside a Sub will take precedence over anything defined outside the Sub. Is it then safe to assume that if it is defined outside the sub, the one inside the sub won't effect it? Like I said, I am a 'Google, Copy, Paste' guy, I only assumed that's how it would behave.


Yes, thats how Global and Local variables work in every language I been working with (including VBS smile.gif).

Edited by rosve, 16 May 2012 - 08:31 PM.


#16 koadic

koadic

    Pinball Fan

  • VIP
  • 1,363 posts
  • Location:Omaha, NE, USA

  • Flag: United States of America

  • Favorite Pinball: Addams Family/Fish Tales/Medieval Madness



Contributor

Posted 16 May 2012 - 09:16 PM

The core.vbs will need to be reupdated as I found a bug that may occur (not fatal or anything, but possibly annoying smile.gif, just need to add an additional file check)) as currently if you try to use it with multiple versions, and delete the standard .nv file in between changing versions, it will error because it will try to backup a file that isn't there.

I have also gone ahead and updated the first post with simplified instructions, so long as you are using the new core.vbs.

#17 destruk

destruk

    VPF Veteran

  • VPF Staff
  • 6,307 posts
  • Location:Colorado Springs, CO

  • Flag: United States of America

  • Favorite Pinball: Ultrapin!



Posted 16 May 2012 - 09:50 PM

updated - the reason I asked is just because it's one of those little things I try to avoid when coding - not overlapping/dupicating variable names means I never had to worry about it before.

Build a fire, vipers love the heat.


#18 gStAv

gStAv

    Pinball Lover

  • Members
  • PipPipPipPip
  • 1,331 posts

  • Flag: Sweden

  • Favorite Pinball: TOM, IJ, AFM, WC94

Posted 16 May 2012 - 10:40 PM

Cool find koadic!! Have to try this one for ATF / ARFM cool.gif

3rs054-6.png


#19 jamos

jamos

    Enthusiast

  • Members
  • PipPipPip
  • 51 posts

  • Flag: United States of America

  • Favorite Pinball: Pinball Wizard

Posted 14 December 2020 - 04:20 AM

I am still not getting this to work properly, I add NVoffset (1) .. (2).. etc. to my tables in the correct spot. But when I run the tables it keeps the last score and the credits as if I am still playing the same table. What am I doing wrong??

 

Can you not use rom Alias with this code as I do so I can properly place my virtual DMD displays in different positions and save them?


Edited by jamos, 14 December 2020 - 04:23 AM.


#20 wiesshund

wiesshund

    VPF Legend

  • Members
  • PipPipPipPipPipPipPip
  • 11,798 posts

  • Flag: United States of America

  • Favorite Pinball: How many can i have?

Posted 14 December 2020 - 06:29 AM

Here is what my VPMAlias.txt looks like

but i think there are limits as to what you can and can not accomplish with it

ratfink,startreb
missworld,kissc
penthouse,hglbtrtb
blkou_hf,blkou_l1
aarfm,afm_113b
acdcluci,ACD_170h
acdcltbr,ACD_170h
acdcbib,ACD_170h
acdcprem,ACD_170h
acdcprov,ACD_170
acdcpro,ACD_170

If you feel the need to empty your wallet in my direction, i dont have any way to receive it anyways

If you really want to get rid of money you can donate to this

Athena's Wildlife Sanctuary



Back to Visual Pinball