PackP3D and custom PRC issues

Hello there, I’ve been having some issues getting my custom PRC files to work after building a .p3d file. The only parameter that seems to work correctly is “window-title”.

The offending PRC file is called ‘custom.prc’ and is in the root directory along with my ‘main.py’ file. I’ve tried putting the other parameters (mainly “win-size” is what I’m trying to work on) in different places in the PRC file but nothing except the window title gets loaded. It’s always a sizeable window at 640x480 resolution.

For the record, I’ve also tried using the WindowProperties object to fix this even though I’d much rather be able to simply load the PRC file however when I use

myProps = base.win.getProperties()
myProps.setFixedSize(True)
myProps.setSize(x,y)
base.win.requestProperties(myProps)

I get a python error saying that setFixedSize cannot be called on a constant object.

Can anyone help me out with this? I just want to be able to change the size of my windows, prevent them from being resized and if I’m lucky be able to use a custom icon (but the latter is purely in the interest of aesthetics)

Instead of using an actual PRC file, you can load the same PRC options in your Python script.
For example:

from pandac.PandaModules import loadPrcFileData
loadPrcFileData('', 'window-title Space Balls: The Game')
loadPrcFileData('', 'icon-filename darkhelmet.ico')
loadPrcFileData('', 'fullscreen 1')
loadPrcFileData('', 'win-size 1024 768')

Put it before importing any other Panda modules.

Hmm, the p3d runtime system will automatically replace many of the prc window-size settings with its own settings. The reason for this is that the p3d runtime system was primarily designed for supporting panda-in-a-browser, where the window size information comes from the browser, and cannot be specified in a prc file.

But this is obviously a bad decision for cases when you just want to run the p3d file from the desktop. In this case it should allow the prc settings to apply. I’ll make a fix to this for future releases of the runtime.

In the meantime, though, teedee’s advice is good: you can override the prc settings manually via Python code, and that should stick. Just be sure to do this before you have imported DirectStart (or otherwise created a ShowBase instance).

David

Thanks for the help. Using teedee’s proposed solution I’ve got it working as a python script, but yet again when I build the p3d file it errors out.

def LoadSettings():
    f = open('./config','r')
    for line in f:
        loadPrcFileData('',line)

Although this works perfectly as a python script, it generates an IOError when run as a p3d. Is there another function I should be using to parse file data when using Panda3D? I apologize; I’m very new to Python (I only started learning it to be able to properly use Panda3D) so any help would be greatly appreciated.

Edit
Also, is there a PRC setting for a fixed-size window? I noticed that you can set it using the WindowProperties object but I couldn’t find a corresponding PRC variable.

To read a file from disk in a p3d file, you have to prefix AppRunner.multifileRoot:

def LoadSettings():
    from direct.showbase.AppRunnerGlobal import appRunner
    if appRunner:
        filename = appRunner.multifileRoot + '/config.prc'
    else:
        filename = './config.prc'
    f = open(filename, 'r')
    for line in f:
        loadPrcFileData('',line) 

Or, you can just encode the lines in your Python file (presumably there aren’t many of them), and this may be simpler than reading a data file like this.

Note that a file without an extension is not included in a p3d file by default. Make sure you are including your config file into your p3d file.

The prc setting for a fixed-size window is win-fixed-size.

David

Thanks, but the file I’m intending to parse is located outside the p3d, unless of course I can also write to it as needed when it’s inside the p3d.

Also, I tried adding “win-fixed-size 1” to the config file and the resulting window was still sizeable. I’m running Windows Vista Home Premium with Panda3D runtime version 1.0.0 if that helps anything.

If it’s outside the p3d, then you need to specify the full path to it on disk. When you run a p3d file by clicking on it from the desktop, you do not have a “current directory” in the usual sense, so “./config” doesn’t reference a file in your current directory.

If you intend for your user to run the p3d file from the command line, then you may specify -c keep_user_env=1 when you generate the p3d file; this will tell the p3d runtime to preserve your current directory, and “./config” will then reference the file you think it does.

Oops, as it happens, win-fixed-size was broken in version 1.7.0, which is the version you currently get when you run from a p3d file. It is already fixed on the cvs trunk, and this will be released in a future update, hopefully coming soon.

David

Thank you very much. I look forward to the next release.

Sorry to double-post but I’ve been playing with this for awhile now and I still can’t get it to work

def LoadSettings():
    from direct.showbase.AppRunnerGlobal import appRunner
    if appRunner:
        path = appRunner.multifileRoot + '/config.cfg'
    else:
        path = './config.cfg'
    f = open(path, 'r')
    for line in f:
        loadPrcFileData('',line)

still causes the following error to occur (I’ve tried getting more detailed information but this is all I can get, regardless of what I set the notify-level at):

File "C:\Users\--------\Desktop\Panda3D\DirectGUI\main.py", line 13, in LoadSettings
  f = open(path, 'r')
File "C:\panda3d-1.7.0\built_cmu\direct\stdpy\file.py", line 132, in __init__
IOError
Failure on startup.

Did you pack config.cfg into your p3d file? Note that .cfg is not packed by default either, but you can include it with “-e cfg” on the packp3d command line.

You can also inspect the contents of your p3d file with the command “multify -tvf my.p3d”

David

D’OH I feel like a moron. I just assumed that things with extensions got included seeing as I didn’t have to add anything to include my jpeg and png files.

Unfortunately, even though I’m reading in the data it’s not changing the window in the p3d file. I’ve also tried changing ‘LoadSettings’ to the following:

def LoadSettings():
    loadPrcFileData('','window-title My Game')
    loadPrcFileData('','win-size 800 600')

And although it works when I run the script, it doesn’t seem to affect anything in the P3D (not even the window title)

Are you sure you’re calling LoadSettings before you import DirectStart or otherwise instantiate a ShowBase instance? How are you invoking the p3d file?

David

def LoadSettings():
    loadPrcFileData('','window-title DirectGUI Test')
    loadPrcFileData('','win-size 800 600')

class GuiTest(ShowBase):
    def __init__(self):
        LoadSettings()
        ShowBase.__init__(self)
        #extra code here

That’s how I currently have it set up. I’m running the P3D usually by double-clicking it, sometimes executing via “panda3d myp3d.p3d” in the command line if I need to see the output.

Sorry, as I’ve said before I’m very new to python. Does “importing” a package do anything other than defining the names/methods and allowing you to use them in your script? Most of my imports are at the very beginning of the script as I was under the impression it was similar to to the C “#include <header.h>”.

That should be OK, assuming you don’t have an import to DirectStart. Unlike in C++, Python import statements can actually invoke code–they will invoke whatever code is at the toplevel of the module file you are importing, and DirectStart.py has some commands to create an instance of a ShowBase class. But since you are creating your own ShowBase instead of importing DirectStart, this probably isn’t happening.

I’ve just investigated the Panda code in question. My apologies, I was giving you bad advice: the prc file settings are completely reset by the plugin runtime. However, you can still replace the default window properties structure like this:

wp = WindowProperties.getDefault()
wp.setTitle('DirectGUI Test')
wp.setSize(800, 600)
WindowProperties.setDefault(wp)

Put this code in place of your calls to loadPrcFileData(), and you should be good.

David

Perfect. That fixed everything, thank you so much for putting up with me through all this.

Edit
For the record, using the WindowProperties object also fixes the ‘win-fixed-size’ issue as well.

Hi guys.

Reading these posts I could set all window properties I wanted except the window icon.
The problem occurs only when running a p3d file. Running “python main.py” works fine.

Here is my code:

from pandac.PandaModules import WindowProperties
from direct.showbase.AppRunnerGlobal import appRunner

wp = WindowProperties.getDefault() 
wp.setTitle("My Game Title")
wp.setFixedSize(True)
 
icoFileName = "models/icons/shuriken_32.ico"

if appRunner:
    icoFileName = appRunner.multifileRoot + "/" + icoFileName

wp.setIconFilename(icoFileName)

WindowProperties.setDefault(wp)
        
from Application import Application

myApp = Application()

run()

I used “-e ico” option when packed my p3d file. Checked if it was there with “multify -tvf my.p3d”, that’s ok.

Even so, I got this message when executing “panda3d myGame.p3d”:

:display:windisplay(warning): Could not find icon filename /c/Users/gilberto/AppData/Local/Panda3D/start/models/icons/shuriken_32.ico
:display: Unable to set window properties: !undecorated fixed_size icon:/c/Users/gilberto/AppData/Local/Panda3D/start/models/icons/shuriken_32.ico

What is happening? Why panda3d could not find the icon file? Any suggestions David?

Thanks

Ah, the problem is that Windows requires the .ico file to actually reside on disk; it can’t load the icon from within the p3d file. So we’ll need to tell Panda to extract the ico file explicitly.

It really should do this automatically, but I didn’t think of this before. So I’ve just added the code to packp3d to automatically add .ico files as auto-extract files (along with .dll and the like). But for now, you’ll have to do this explicitly, which means you’ll need to package your p3d file with a pdef file. This file might look something like this:

class myGame(p3d):
    config(display_name = "My Game")
    require('panda3d')
    dir('.')
    file('shuriken_32.ico', extract = True)
    mainModule('main')

And then you can build the p3d file with a command that looks something like this:

ppackage myGame.pdef

David

Wow thank you David I’m pretty sure this will work.

But as I’m planning to distribute my game with a NSIS installer, I think that what I should do is to change the icon of the executable file. This would change both the window icon and the start menu shortcut icon, right?

I started this thread to get some help on it:


panda3d.org/forums/viewtopic … 7526#77526

I’m finishing my game and I would like to create a nice intaller for it. Custom icons would be very cool.

By the way, I would like to thank you David, your posts in this forum were very useful to me over the last 7 months I’ve been developing my game.

Thank you.