git-svn-id: svn://svn.icculus.org/gtkradiant/GtkRadiant/branches/ZeroRadiant@190 8a3a26a2-13c4-0310-b231-cf6edde360e5
This commit is contained in:
TTimo 2007-11-04 04:09:22 +00:00
parent 33efc90892
commit 64fe6940f0
57 changed files with 3349 additions and 3349 deletions

View file

@ -1,7 +1,7 @@
Compilation instructions
------------------------
See latest information for compiling and installation
on the developer pages:
http://www.qeradiant.com/wikifaq/index.php?GtkRadiant%20Hacker
Compilation instructions
------------------------
See latest information for compiling and installation
on the developer pages:
http://www.qeradiant.com/wikifaq/index.php?GtkRadiant%20Hacker

View file

@ -1,8 +1,8 @@
; bkgrnd2d.def : Declares the module parameters for the DLL.
LIBRARY "BKGRND2D"
DESCRIPTION 'BKGRND2D Windows Dynamic Link Library'
EXPORTS
; Explicit exports can go here
Synapse_EnumerateInterfaces @1
; bkgrnd2d.def : Declares the module parameters for the DLL.
LIBRARY "BKGRND2D"
DESCRIPTION 'BKGRND2D Windows Dynamic Link Library'
EXPORTS
; Explicit exports can go here
Synapse_EnumerateInterfaces @1

View file

@ -1,131 +1,131 @@
November 25 2003
bkgrnd2d v 0.25 beta for radiant 1.3.13
by SCDS_reyalP (email hellsownpuppy@yahoo.com)
WARNING:
This is an beta release. It is provided with absolutely NO WARRANTY.
If it turns your data to mush and melts your CPU, don't blame me.
Overview:
This little plugin allows you to display an image in the the gtkradiant 2d
windows. This is useful for layout sketches, maps made from
existing plans, building geometry based on photgraphs, viewing terrain
alphamaps in relation to your terrain, and so on.
Installation:
extract the .dll and bitmaps into your gtkradiant/plugins directory, and
restart radiant. Be sure to use directory names, to ensure the bitmaps go
in your plugins/bitmaps directory.
Uninstallation:
Close radiant, delete the bkgrnd2d.dll from the plugins directory, and
delete the bkgrnd2*.bmp files from the plugins/bitmaps directory.
User Interface:
- The plugin adds 4 buttons to the radiant plugin toolbar. The first 3
toggle the display of a background image in the specified view. The fourth
brings up a configuration dialog. The configuration dialog can also be
opened from the plugins menu.
- If an image has not been loaded, or it's display size and location have
not been set, pushing one of the toggle buttons will bring up the dialog
with the corresponding page selected.
- The configuration dialog is non-modal, meaning that you can leave it open
while you work in radiant. If it gets lost behind another window, clicking
on the configuration button will bring it to the forground.
Usage:
- bring up the configuration dialog.
- Choose the "Browse..." button. This will prompt you for an image file.
The file *MUST* be inside your basegame directory (baseq3, main, etmain or
whatever your chosen game uses). The image must be in a format supported by
the game in use. For q3 based games this is truecolor .jpg, .tga and
sometimes .png. For q2 this is .wal
- Use one of the following methods to set the size (in game units) that the
file is displayed.
1) select 1 or more brushes or entities and choose "from selection"
This will use the total dimensions off all selected brushes and entities
to size the image.
2) For the X/Y view only, choose 'Size to min/max keys' This will look in
the worldspawn entity for the keys mapcoordsmins and mapcoordsmaxs (also
used for ET tracemap generation and command map sizing) and use those
dimensions to size the image.
- Use the toggle buttons to show or hide the loaded images. The buttons will
press or unpress whenever you click them, but an image will only be
displayed once you have successfully loaded a file and set its size/postion.
- Set the opacity of the image using the slider in the configuration dialog.
- If any of these commands do not produce the expected results, there may be
an information in the radiant console. Please include this when reporting
bugs.
Notes and limitations:
- This plugin is compiled for GtkRadiant 1.3.13. It may or may not work with
later versions. It will *NOT* work with version 1.3.12 and below. If you
build from source (see below) you can build it for other versions.
- As mentioned above, the image *MUST* be inside your basegame directory, or
another directory in which radiant looks for game files.
- To prevent the image from being distorted, you should size it to the
original images aspect ratio. mapcoordsmaxs/mapcoordsmins and command maps
should always be square.
- If you want a specific pixel to world unit relationship, you must arrange
that yourself.
- On load, the image is converted to a texture whose dimensions are powers
of 2. If the original image dimensions are not powers of 2, some detail will
be lost due to resampling. If it is too large to fit on a single texture,
resolution is reduced.
- radiants gamma and mipmap options are applied to the image.
- If the image has an alpha channel, it will be included in the blending
process. 0 is transparent, 255 is opaque. .tga images are recommended if
you want to have an alpha channel.
- since the plugin will only use true color files, you cannot use a terrain
indexmap (aka alphamap) or heightmap directly. You can of course, save a
copy of your indexmap in a 32 bit format.
- There is no unload command.
- You put the plugin in a game specific plugin directory, rather than the
radiant plugin directory.
- You cannot set the image size with sub-unit precision.
- Only win32 binaries are included. The source is available from:
http://www.cyberonic.net/~gdevault/rfm/mapstuff/bkgrnd2d-b0.25-src.zip
If you want to use it on another platform you will need a buildable gtkradiant
source tree to build it. For any non-windows platform you will also have to
figure out the compile options. I suggest ripping those off from some other
plugin.
TODO:
- make file selection paterns match supported filetypes
- large images without downsampling
- bitmap and pcx support for indexmaps
- automatic size from indexmapped entities
- render under the grid instead of blending
- mac/*nix support
- remember/save/restore settings
- texture options independant of radiant prefs
- clean up icky code
Changes from 0.1
- all 2d views supported
- new ui
- file selection patterns, default directory improved
Changes from 0.2
- tooltips in dialog
- various code cleanup
November 25 2003
bkgrnd2d v 0.25 beta for radiant 1.3.13
by SCDS_reyalP (email hellsownpuppy@yahoo.com)
WARNING:
This is an beta release. It is provided with absolutely NO WARRANTY.
If it turns your data to mush and melts your CPU, don't blame me.
Overview:
This little plugin allows you to display an image in the the gtkradiant 2d
windows. This is useful for layout sketches, maps made from
existing plans, building geometry based on photgraphs, viewing terrain
alphamaps in relation to your terrain, and so on.
Installation:
extract the .dll and bitmaps into your gtkradiant/plugins directory, and
restart radiant. Be sure to use directory names, to ensure the bitmaps go
in your plugins/bitmaps directory.
Uninstallation:
Close radiant, delete the bkgrnd2d.dll from the plugins directory, and
delete the bkgrnd2*.bmp files from the plugins/bitmaps directory.
User Interface:
- The plugin adds 4 buttons to the radiant plugin toolbar. The first 3
toggle the display of a background image in the specified view. The fourth
brings up a configuration dialog. The configuration dialog can also be
opened from the plugins menu.
- If an image has not been loaded, or it's display size and location have
not been set, pushing one of the toggle buttons will bring up the dialog
with the corresponding page selected.
- The configuration dialog is non-modal, meaning that you can leave it open
while you work in radiant. If it gets lost behind another window, clicking
on the configuration button will bring it to the forground.
Usage:
- bring up the configuration dialog.
- Choose the "Browse..." button. This will prompt you for an image file.
The file *MUST* be inside your basegame directory (baseq3, main, etmain or
whatever your chosen game uses). The image must be in a format supported by
the game in use. For q3 based games this is truecolor .jpg, .tga and
sometimes .png. For q2 this is .wal
- Use one of the following methods to set the size (in game units) that the
file is displayed.
1) select 1 or more brushes or entities and choose "from selection"
This will use the total dimensions off all selected brushes and entities
to size the image.
2) For the X/Y view only, choose 'Size to min/max keys' This will look in
the worldspawn entity for the keys mapcoordsmins and mapcoordsmaxs (also
used for ET tracemap generation and command map sizing) and use those
dimensions to size the image.
- Use the toggle buttons to show or hide the loaded images. The buttons will
press or unpress whenever you click them, but an image will only be
displayed once you have successfully loaded a file and set its size/postion.
- Set the opacity of the image using the slider in the configuration dialog.
- If any of these commands do not produce the expected results, there may be
an information in the radiant console. Please include this when reporting
bugs.
Notes and limitations:
- This plugin is compiled for GtkRadiant 1.3.13. It may or may not work with
later versions. It will *NOT* work with version 1.3.12 and below. If you
build from source (see below) you can build it for other versions.
- As mentioned above, the image *MUST* be inside your basegame directory, or
another directory in which radiant looks for game files.
- To prevent the image from being distorted, you should size it to the
original images aspect ratio. mapcoordsmaxs/mapcoordsmins and command maps
should always be square.
- If you want a specific pixel to world unit relationship, you must arrange
that yourself.
- On load, the image is converted to a texture whose dimensions are powers
of 2. If the original image dimensions are not powers of 2, some detail will
be lost due to resampling. If it is too large to fit on a single texture,
resolution is reduced.
- radiants gamma and mipmap options are applied to the image.
- If the image has an alpha channel, it will be included in the blending
process. 0 is transparent, 255 is opaque. .tga images are recommended if
you want to have an alpha channel.
- since the plugin will only use true color files, you cannot use a terrain
indexmap (aka alphamap) or heightmap directly. You can of course, save a
copy of your indexmap in a 32 bit format.
- There is no unload command.
- You put the plugin in a game specific plugin directory, rather than the
radiant plugin directory.
- You cannot set the image size with sub-unit precision.
- Only win32 binaries are included. The source is available from:
http://www.cyberonic.net/~gdevault/rfm/mapstuff/bkgrnd2d-b0.25-src.zip
If you want to use it on another platform you will need a buildable gtkradiant
source tree to build it. For any non-windows platform you will also have to
figure out the compile options. I suggest ripping those off from some other
plugin.
TODO:
- make file selection paterns match supported filetypes
- large images without downsampling
- bitmap and pcx support for indexmaps
- automatic size from indexmapped entities
- render under the grid instead of blending
- mac/*nix support
- remember/save/restore settings
- texture options independant of radiant prefs
- clean up icky code
Changes from 0.1
- all 2d views supported
- new ui
- file selection patterns, default directory improved
Changes from 0.2
- tooltips in dialog
- various code cleanup

View file

@ -1,8 +1,8 @@
; plugin.def : Declares the module parameters for the DLL.
LIBRARY "bobToolz"
; DESCRIPTION 'bobToolz Windows Dynamic Link Library'
EXPORTS
; Explicit exports can go here
Synapse_EnumerateInterfaces @1
; plugin.def : Declares the module parameters for the DLL.
LIBRARY "bobToolz"
; DESCRIPTION 'bobToolz Windows Dynamic Link Library'
EXPORTS
; Explicit exports can go here
Synapse_EnumerateInterfaces @1

View file

@ -1,17 +1,17 @@
common/areaportal
common/clip
common/clusterportal
common/cushion
common/donotenter
common/full_clip
common/hint
common/missileclip
common/nodraw
common/nodrawnonsolid
common/nodrop
common/noimpact
common/origin
common/trigger
common/weapclip
liquid
common/areaportal
common/clip
common/clusterportal
common/cushion
common/donotenter
common/full_clip
common/hint
common/missileclip
common/nodraw
common/nodrawnonsolid
common/nodrop
common/noimpact
common/origin
common/trigger
common/weapclip
liquid
fog

View file

@ -1,61 +1,61 @@
base_light/light1blue_2000
base_light/light1blue_5000
ctf/blue_telep
ctf/ctf_blueflag
ctf/ctf_tower_bluefin_shiny
gothic_door/door02_eblue2_shiny
gothic_light/ironcrossltblue_10000
gothic_light/ironcrossltblue_2000
gothic_light/ironcrossltblue_20000
gothic_light/ironcrossltblue_3000
gothic_light/ironcrossltblue_30000
gothic_light/ironcrossltblue_4000
gothic_light/ironcrossltblue_5000
sfx/beam_blue
sfx/flameanim_blue
sfx/flameanim_blue_nolight
sfx/flameanim_blue_pj
sfx/mkc_fog_ctfblue
sfx/xbluefog
base_wall2/blue_metal
base_wall2/jumppad_blue_kc
base_wall2/blue_line
base_wall2/double_line_blue
base_wall2/blue_arrow_small
base_wall2/blue_circle
base_wall2/bluearrows
base_wall2/blue_solid
ctf2/blueteam01
ctf2/blueteam02
ctf2/xblueteam01
ctf2/blue_banner02
proto2/blueflag
proto2/blueob
proto2/marbledoor_blue
proto2/concrete_bluenfx
proto2/bluelight_on
proto2/bsbluelight_on
proto2/rsbluelight_off
proto2/bsbluelight_off
proto2/rsbluelight_on
proto2/bluetrim01
proto2/blue_zot
proto2/blue_zot2
proto2/bluea_dcl
proto2/concrete_blue
proto2/teamwerkz_blue1
proto2/blueflare2
proto2/blueflare
sfx2/flameanim_blue_lowlite
sfx2/blue_jumpad05
sfx2/blue_launchpad
sfx2/blue_jumpad
sfx2/blue_jumpad2
sfx2/blue_jumpad3
sfx2/bluegoal2
tim/blue_flagbase
team_icon/the fallen_blue
team_icon/intruders_blue
team_icon/crusaders_blue
team_icon/pagans_blue
base_light/light1blue_2000
base_light/light1blue_5000
ctf/blue_telep
ctf/ctf_blueflag
ctf/ctf_tower_bluefin_shiny
gothic_door/door02_eblue2_shiny
gothic_light/ironcrossltblue_10000
gothic_light/ironcrossltblue_2000
gothic_light/ironcrossltblue_20000
gothic_light/ironcrossltblue_3000
gothic_light/ironcrossltblue_30000
gothic_light/ironcrossltblue_4000
gothic_light/ironcrossltblue_5000
sfx/beam_blue
sfx/flameanim_blue
sfx/flameanim_blue_nolight
sfx/flameanim_blue_pj
sfx/mkc_fog_ctfblue
sfx/xbluefog
base_wall2/blue_metal
base_wall2/jumppad_blue_kc
base_wall2/blue_line
base_wall2/double_line_blue
base_wall2/blue_arrow_small
base_wall2/blue_circle
base_wall2/bluearrows
base_wall2/blue_solid
ctf2/blueteam01
ctf2/blueteam02
ctf2/xblueteam01
ctf2/blue_banner02
proto2/blueflag
proto2/blueob
proto2/marbledoor_blue
proto2/concrete_bluenfx
proto2/bluelight_on
proto2/bsbluelight_on
proto2/rsbluelight_off
proto2/bsbluelight_off
proto2/rsbluelight_on
proto2/bluetrim01
proto2/blue_zot
proto2/blue_zot2
proto2/bluea_dcl
proto2/concrete_blue
proto2/teamwerkz_blue1
proto2/blueflare2
proto2/blueflare
sfx2/flameanim_blue_lowlite
sfx2/blue_jumpad05
sfx2/blue_launchpad
sfx2/blue_jumpad
sfx2/blue_jumpad2
sfx2/blue_jumpad3
sfx2/bluegoal2
tim/blue_flagbase
team_icon/the fallen_blue
team_icon/intruders_blue
team_icon/crusaders_blue
team_icon/pagans_blue
team_icon/stroggs_blue

View file

@ -1,61 +1,61 @@
base_light/light1red_2000
base_light/light1red_5000
ctf/red_telep
ctf/ctf_redflag
ctf/ctf_tower_redfin_shiny
gothic_door/door02_bred2_shiny
gothic_light/ironcrossltred_10000
gothic_light/ironcrossltred_2000
gothic_light/ironcrossltred_20000
gothic_light/ironcrossltred_3000
gothic_light/ironcrossltred_30000
gothic_light/ironcrossltred_4000
gothic_light/ironcrossltred_5000
sfx/beam_red
sfx/flameanim_red
sfx/flameanim_red_nolight
sfx/flameanim_red_pj
sfx/mkc_fog_ctfred
sfx/xredfog
base_wall2/red_metal
base_wall2/jumppad_red_kc
base_wall2/red_line
base_wall2/double_line_red
base_wall2/red_arrow_small
base_wall2/red_circle
base_wall2/redarrows
base_wall2/red_solid
ctf2/redteam01
ctf2/redteam02
ctf2/xredteam01x
ctf2/red_banner02
proto2/redflag
proto2/redob
proto2/marbledoor_red
proto2/concrete_rednfx
proto2/redlight_on
proto2/bsredlight_on
proto2/rsredlight_off
proto2/bsredlight_off
proto2/rsredlight_on
proto2/redtrim01
proto2/red_zot
proto2/red_zot2
proto2/reda_dcl
proto2/concrete_red
proto2/teamwerkz_red1
proto2/redflare2
proto2/redflare
sfx2/flameanim_red_lowlite
sfx2/red_jumpad05
sfx2/red_launchpad
sfx2/red_jumpad
sfx2/red_jumpad2
sfx2/red_jumpad3
sfx2/redgoal2
tim/red_flagbase
team_icon/the fallen_red
team_icon/intruders_red
team_icon/crusaders_red
team_icon/pagans_red
base_light/light1red_2000
base_light/light1red_5000
ctf/red_telep
ctf/ctf_redflag
ctf/ctf_tower_redfin_shiny
gothic_door/door02_bred2_shiny
gothic_light/ironcrossltred_10000
gothic_light/ironcrossltred_2000
gothic_light/ironcrossltred_20000
gothic_light/ironcrossltred_3000
gothic_light/ironcrossltred_30000
gothic_light/ironcrossltred_4000
gothic_light/ironcrossltred_5000
sfx/beam_red
sfx/flameanim_red
sfx/flameanim_red_nolight
sfx/flameanim_red_pj
sfx/mkc_fog_ctfred
sfx/xredfog
base_wall2/red_metal
base_wall2/jumppad_red_kc
base_wall2/red_line
base_wall2/double_line_red
base_wall2/red_arrow_small
base_wall2/red_circle
base_wall2/redarrows
base_wall2/red_solid
ctf2/redteam01
ctf2/redteam02
ctf2/xredteam01x
ctf2/red_banner02
proto2/redflag
proto2/redob
proto2/marbledoor_red
proto2/concrete_rednfx
proto2/redlight_on
proto2/bsredlight_on
proto2/rsredlight_off
proto2/bsredlight_off
proto2/rsredlight_on
proto2/redtrim01
proto2/red_zot
proto2/red_zot2
proto2/reda_dcl
proto2/concrete_red
proto2/teamwerkz_red1
proto2/redflare2
proto2/redflare
sfx2/flameanim_red_lowlite
sfx2/red_jumpad05
sfx2/red_launchpad
sfx2/red_jumpad
sfx2/red_jumpad2
sfx2/red_jumpad3
sfx2/redgoal2
tim/red_flagbase
team_icon/the fallen_red
team_icon/intruders_red
team_icon/crusaders_red
team_icon/pagans_red
team_icon/stroggs_red

View file

@ -1,5 +1,5 @@
base_support/support1rust
base_support/support1shiny
base_support/support2rust
base_support/wplat1_1
base_support/support1rust
base_support/support1shiny
base_support/support2rust
base_support/wplat1_1
base_support/plate2_5

View file

@ -1,10 +1,10 @@
base_door/shinymetaldoor
base_door/shinymetaldoor_outside
gothic_door/door02_bred
gothic_door/door02_bred2_shiny
gothic_door/door02_eblue2_shiny
gothic_door/door02_i_ornate5_fin
gothic_door/door02_j
gothic_door/door02_j3
gothic_door/door02_j4
base_door/shinymetaldoor
base_door/shinymetaldoor_outside
gothic_door/door02_bred
gothic_door/door02_bred2_shiny
gothic_door/door02_eblue2_shiny
gothic_door/door02_i_ornate5_fin
gothic_door/door02_j
gothic_door/door02_j3
gothic_door/door02_j4
gothic_door/door02_k2b

View file

@ -1,14 +1,14 @@
{
"entity" "misc_model"
"offset" "-16"
"model" "models/mapobjects/trees_sd/tree_a.md3"
"model" "models/mapobjects/trees_sd/tree_b.md3"
"model" "models/mapobjects/trees_sd/tree_c.md3"
"model" "models/mapobjects/trees_sd/tree_d.md3"
"pitch" "-5" "5"
"yaw" "0" "360"
"scale" "1" "1.3"
{
"entity" "misc_model"
"offset" "-16"
"model" "models/mapobjects/trees_sd/tree_a.md3"
"model" "models/mapobjects/trees_sd/tree_b.md3"
"model" "models/mapobjects/trees_sd/tree_c.md3"
"model" "models/mapobjects/trees_sd/tree_d.md3"
"pitch" "-5" "5"
"yaw" "0" "360"
"scale" "1" "1.3"
}

View file

@ -1,12 +1,12 @@
; plugin.def : Declares the module parameters for the DLL.
LIBRARY "ctfToolz"
DESCRIPTION 'ctfToolz Windows Dynamic Link Library'
EXPORTS
; Explicit exports can go here
QERPlug_Init @1
QERPlug_GetName @2
QERPlug_GetCommandList @3
QERPlug_Dispatch @4
QERPlug_GetFuncTable @5
; plugin.def : Declares the module parameters for the DLL.
LIBRARY "ctfToolz"
DESCRIPTION 'ctfToolz Windows Dynamic Link Library'
EXPORTS
; Explicit exports can go here
QERPlug_Init @1
QERPlug_GetName @2
QERPlug_GetCommandList @3
QERPlug_Dispatch @4
QERPlug_GetFuncTable @5

View file

@ -1,96 +1,96 @@
BobToolz Changelog:
[=================]
Changes in v1110 (GTK):
[=====================]
djbob
Added:
(16.05.01)
Impemented a little feature that highligths the q3map bug that is causing problems for autocaulk, (see readme)
(01.04.01)
Added DPatch class to implement patches, however radiant does not (currently) support adding patches to an entity via a plugin, so, its actually redundant atm, i was adding this to fix the patches being removed from entities probelm with dealing with entities outside of the worldspawn.
Changes:
(02.04.01)
EPair keys and values can now be 128 characters long, not 64, happy now hydra?
Texture reseter works on patches now too.
Removed:
(29.03.01)
Removed CTF colour changer, it is now in the ctftoolz.
Fixed:
(02.04.01)
Worldspawn brushes are rebuilt per brush, rather than per entity in texture reseter.
(03.04.01)
Worldspawn brushes are rebuilt per brush, rather than per entity in brush cleanup.
Changes in v1100 (GTK):
[=====================]
djbob
Added:
(24.03.01)
Added CTF colour changer for worldspawn+func_group.
Changes:
(25.03.01)
Brought some functions over to using DMap class, allowing them to run on multiple entities, patches are still a no-no atm.
This includes:
a) brush cleanup, will now fix problems on brushes that are not in the worldspawn, and rebuild the entitiy afterwards.
b) texture reseter will change textures on all brushes now, not just those in the worldspawn.
c) CTF colour changer will also work on brushes outside of the worldspawn entity.
This introduces one prolem, patches in entities will no longer be part of the new entity, sorry for any trouble this causes, i will fix it soon hopefully.
Fixes:
(25.03.01)
Fixed bug in DMap class that prevented it destroying brushes... thus enabling the class to work!!!!
Changes in v1090 (GTK):
[=====================]
djbob
Added:
(22.03.01)
Added PitOMatic Function.
Changes in v1080b (GTK):
[======================]
djbob
Fixes:
Removed some previously unnoticed porting introduced bugs.
Added:
Polygon stuff now passes through my internal validation routines, no more phantom brushes will be made, or squiffy planes.
Changes in v1080 (GTK):
[=====================]
djbob
Fixes:
(05.03.01)
Fixed line removed by rr2 in autocaulk.
Fixed Autocaulk not working with maps larger than the old grid.
Added:
(04.03.01)
Added Changelog.
Added ability to align polygons so that top edge will be flat. (Request By Casey)
(05.03.01)
Added ability to change main texture for stairs.
rr2do2
Changes:
(??.??.01)
Removed all traces of MFC from GTK version, the evil that it is ;]
BobToolz Changelog:
[=================]
Changes in v1110 (GTK):
[=====================]
djbob
Added:
(16.05.01)
Impemented a little feature that highligths the q3map bug that is causing problems for autocaulk, (see readme)
(01.04.01)
Added DPatch class to implement patches, however radiant does not (currently) support adding patches to an entity via a plugin, so, its actually redundant atm, i was adding this to fix the patches being removed from entities probelm with dealing with entities outside of the worldspawn.
Changes:
(02.04.01)
EPair keys and values can now be 128 characters long, not 64, happy now hydra?
Texture reseter works on patches now too.
Removed:
(29.03.01)
Removed CTF colour changer, it is now in the ctftoolz.
Fixed:
(02.04.01)
Worldspawn brushes are rebuilt per brush, rather than per entity in texture reseter.
(03.04.01)
Worldspawn brushes are rebuilt per brush, rather than per entity in brush cleanup.
Changes in v1100 (GTK):
[=====================]
djbob
Added:
(24.03.01)
Added CTF colour changer for worldspawn+func_group.
Changes:
(25.03.01)
Brought some functions over to using DMap class, allowing them to run on multiple entities, patches are still a no-no atm.
This includes:
a) brush cleanup, will now fix problems on brushes that are not in the worldspawn, and rebuild the entitiy afterwards.
b) texture reseter will change textures on all brushes now, not just those in the worldspawn.
c) CTF colour changer will also work on brushes outside of the worldspawn entity.
This introduces one prolem, patches in entities will no longer be part of the new entity, sorry for any trouble this causes, i will fix it soon hopefully.
Fixes:
(25.03.01)
Fixed bug in DMap class that prevented it destroying brushes... thus enabling the class to work!!!!
Changes in v1090 (GTK):
[=====================]
djbob
Added:
(22.03.01)
Added PitOMatic Function.
Changes in v1080b (GTK):
[======================]
djbob
Fixes:
Removed some previously unnoticed porting introduced bugs.
Added:
Polygon stuff now passes through my internal validation routines, no more phantom brushes will be made, or squiffy planes.
Changes in v1080 (GTK):
[=====================]
djbob
Fixes:
(05.03.01)
Fixed line removed by rr2 in autocaulk.
Fixed Autocaulk not working with maps larger than the old grid.
Added:
(04.03.01)
Added Changelog.
Added ability to align polygons so that top edge will be flat. (Request By Casey)
(05.03.01)
Added ability to change main texture for stairs.
rr2do2
Changes:
(??.??.01)
Removed all traces of MFC from GTK version, the evil that it is ;]

View file

@ -1,77 +1,77 @@
BobToolz GTK: v1100
[=================]
Date:
[===]
16.05.01
The multipurpose Quake3 Mappers Tool
[==================================]
Author: djbob
Other work: q3terra, ctftoolz, EECA mod
eMail: gbiggans@uglab.eee.strath.ac.uk (NO SPAM thank u very much :P)
www: www.planetquake.com/toolz
www.planetquake.com/eeca
IRC: #freepq irc.fdf.net
#qeradiant irc.telefragged.com
Files Contained In This Package:
[==============================]
Readme.txt --- This file.
Changelog.txt --- Version information.
bobToolz.dll --- The plugin itsself.
bt/*.txt --- A few text files required by the plugin.
What's a boy to do?
[=================]
Put The plugin in your GTKRadiant plugins folder:
e.g. mine: c:\gamez\quake3\GTKRadiant\plugins
Run Radiant, and select the toolz from the dropdown plugin menu.
Help is available in the form of a manual on my site.
For the new q3map bug highlighting feature, run autocaulk-build mini prt, then run autocaulk.
identify an area which has been caulked incorrectly, then reopen the map, select the q3map bug highlight option, and wait.
once the selected brushes appear, u have 2 choices,
a) press i and remove all the original brushes, or
b) keep going with both sets (slower, but more useful)
navigate to the problem region, you should find that the set of inverse brushes that has been built is missing a brush
at the problem area, i suppose the next problem is finding out why :]
this function is mainly provided for other coders to show the problem, and is probably of little use to anyone else,
but u never know.
Coming Soon:
[==========]
Region area saving. perhaps, if i get the time to finish it.
Testing, Feedback & Ideas:
[========================]
Akuma, Casey, Cartman2K, maverik, rayden, nephilim_goth and god knows who else.
Thx to you all.
Thanx:
[====]
ttimo, da man :]
spog, for his often baffling advice.... and questions....
Thx to rr2do2, for his linux conversion, and removing the "evil" (his words :]) MFC code.
Thx to RKone, for improving my q3w sig.
Azr for giving me ops in #qeradiant, k3wl :]
Everyone at the Quake3World Forums, I think of you all as my little worshippers :P
BobToolz GTK: v1100
[=================]
Date:
[===]
16.05.01
The multipurpose Quake3 Mappers Tool
[==================================]
Author: djbob
Other work: q3terra, ctftoolz, EECA mod
eMail: gbiggans@uglab.eee.strath.ac.uk (NO SPAM thank u very much :P)
www: www.planetquake.com/toolz
www.planetquake.com/eeca
IRC: #freepq irc.fdf.net
#qeradiant irc.telefragged.com
Files Contained In This Package:
[==============================]
Readme.txt --- This file.
Changelog.txt --- Version information.
bobToolz.dll --- The plugin itsself.
bt/*.txt --- A few text files required by the plugin.
What's a boy to do?
[=================]
Put The plugin in your GTKRadiant plugins folder:
e.g. mine: c:\gamez\quake3\GTKRadiant\plugins
Run Radiant, and select the toolz from the dropdown plugin menu.
Help is available in the form of a manual on my site.
For the new q3map bug highlighting feature, run autocaulk-build mini prt, then run autocaulk.
identify an area which has been caulked incorrectly, then reopen the map, select the q3map bug highlight option, and wait.
once the selected brushes appear, u have 2 choices,
a) press i and remove all the original brushes, or
b) keep going with both sets (slower, but more useful)
navigate to the problem region, you should find that the set of inverse brushes that has been built is missing a brush
at the problem area, i suppose the next problem is finding out why :]
this function is mainly provided for other coders to show the problem, and is probably of little use to anyone else,
but u never know.
Coming Soon:
[==========]
Region area saving. perhaps, if i get the time to finish it.
Testing, Feedback & Ideas:
[========================]
Akuma, Casey, Cartman2K, maverik, rayden, nephilim_goth and god knows who else.
Thx to you all.
Thanx:
[====]
ttimo, da man :]
spog, for his often baffling advice.... and questions....
Thx to rr2do2, for his linux conversion, and removing the "evil" (his words :]) MFC code.
Thx to RKone, for improving my q3w sig.
Azr for giving me ops in #qeradiant, k3wl :]
Everyone at the Quake3World Forums, I think of you all as my little worshippers :P
id Software, of course.

View file

@ -1,8 +1,8 @@
; camera.def : Declares the module parameters for the DLL.
LIBRARY "CAMERA"
DESCRIPTION 'CAMERA Windows Dynamic Link Library'
EXPORTS
; Explicit exports can go here
Synapse_EnumerateInterfaces @1
; camera.def : Declares the module parameters for the DLL.
LIBRARY "CAMERA"
DESCRIPTION 'CAMERA Windows Dynamic Link Library'
EXPORTS
; Explicit exports can go here
Synapse_EnumerateInterfaces @1

View file

@ -1,8 +1,8 @@
; gensurf.def : Declares the module parameters for the DLL.
LIBRARY "gensurf"
DESCRIPTION 'gensurf Windows Dynamic Link Library'
EXPORTS
; Explicit exports can go here
Synapse_EnumerateInterfaces @1
; gensurf.def : Declares the module parameters for the DLL.
LIBRARY "gensurf"
DESCRIPTION 'gensurf Windows Dynamic Link Library'
EXPORTS
; Explicit exports can go here
Synapse_EnumerateInterfaces @1

View file

@ -1,8 +1,8 @@
; fgd.def : Declares the module parameters for the DLL.
LIBRARY "HydraToolz"
DESCRIPTION 'HydraToolz Windows Dynamic Link Library'
EXPORTS
; Explicit exports can go here
Synapse_EnumerateInterfaces @1
; fgd.def : Declares the module parameters for the DLL.
LIBRARY "HydraToolz"
DESCRIPTION 'HydraToolz Windows Dynamic Link Library'
EXPORTS
; Explicit exports can go here
Synapse_EnumerateInterfaces @1

View file

@ -1,8 +1,8 @@
; PrtView.def : Declares the module parameters for the DLL.
LIBRARY "PrtView"
; DESCRIPTION 'PrtView Windows Dynamic Link Library'
EXPORTS
; Explicit exports can go here
Synapse_EnumerateInterfaces @1
; PrtView.def : Declares the module parameters for the DLL.
LIBRARY "PrtView"
; DESCRIPTION 'PrtView Windows Dynamic Link Library'
EXPORTS
; Explicit exports can go here
Synapse_EnumerateInterfaces @1

View file

@ -1,12 +1,12 @@
Put PrtView.dll in the Q3Radiant plugins directory.
This program is pretty self explanitary, but point needs to
be mentioned. In the configuration menu for 3D view options,
the lines and polygons flags are tri-state. In the third state,
the lines or polygons will only be drawn if the have the
hint flag set. Older version of q3map will not set this flag
and the hint shader may have to be modified to set it. As of
this writing, I do not know all the details.
Geoffrey DeWan
Put PrtView.dll in the Q3Radiant plugins directory.
This program is pretty self explanitary, but point needs to
be mentioned. In the configuration menu for 3D view options,
the lines and polygons flags are tri-state. In the third state,
the lines or polygons will only be drawn if the have the
hint flag set. Older version of q3map will not set this flag
and the hint shader may have to be modified to set it. As of
this writing, I do not know all the details.
Geoffrey DeWan
gdewan@prairienet.org

View file

@ -1,266 +1,266 @@
OK. Again I would have liked to get a design document before it being done. Main functionalities we
need in the inspector:
- Unifiy the inspector under a single dialog box, called with 'S'
- Depending on what is currently selected, display several frames in the inspector:
only brushes -> surface inspector
only patches -> patch inspector
brushes & patches -> both
and later when brush primitives are mixed with regular brushes + plugin entities, raise whatever
additional inspector stuff we need
- The camera view must update realtime when we change some parameters.
- Get rid of the Apply button, use the Undo code to store settings when surface inspector is
raised. If user hits Cancel, call the undo stuff.
- Use the message broadcasting stuff to keep the inspectors up to date when the user changes the
current selection. Be careful to keep the undo stuff in sync with the select / deselect operations.
- Use a 3-state scheme to display the params in the widgets. If two faces are selected that don't
have the same shift increment, just grey out the shift box.
Messaging:
- a good chunk of the work is moving the selection/creation stuff to the messaging API
we no longer use UpdateSurfaceDialog, we post messages instead ..
the surface inspector has hooked one of it's listeners into the corresponding message
we may need to reorganize the messages, maybe introduce a hierarchy?
or pass a void * param with messages?
- we don't post messages like "update surface inspector", we post messages that say "this and that
have changed", then the surface inspector reacts if it needs to.
Do we need marshalling in the messages? Very likely .. maybe using Gtk signal stuff would be interesting?
-> the messaging stuff is a big chunk of work and our surface inspector changes are not totally
dependent on it. Better leave that for l8r
the inspector works by states and transitions? Or we post messages to it?
Use case:
the user raises the inspector .. if we are up we'll ignore, if we are hidden we'll
go through the whole process (initialise, look at what is selected, display)
then we enter an active state (listening for select / deselects and applying stuff)
all in all it seems to be too big a change for next release. will see later probably.
Trying a few more days with it, see what happens. after all the interface is fairly restricted
so there's a good chance our changes are fairly stable in the end. But rebuilding the whole interface
part might be too much ...
We need something state based? AND a set of messages ..
but first, need to write the initialisation loop
build the dialog, get the current surface information and display
Undoing the changes on the selected stuff:
at any point in time, one can get a snapshot of selected stuff and use it to store the surface
properties settings for later on. But what happens if the user modifies the selected brush, pushing
it in the undo stack? Then we would cancel the changes? (and just backup to the state right after
the modif)
We could has the 'Apply' button used for that .. grey it out when the current state is the one in
the backup. This happens whenever we hit 'Apply' or change something in the selection.
The selection has several items: entities, brushes and selected faces (possibly later generic plugin entities)
Current undo stuff is aimed at entities and brushes.
NOTE: you can't have selected faces and brushes/entities at the same time, that's a good point to
keep that seperated to deal with undo and storage
On what side should the implemetation be ? undo.cpp select.cpp or surfacedialog.cpp ?
We are going to do it with the messaging API anyway..
And hook in the undo stuff, to reset the snapshot each time something gets pushed in the undo?
We have advanced stuff on the Inspector branch, doing basics on Alpha branch.
Start writing the watch code in surfacedialog.cpp, see if we need some merging with Undo stuff l8r
We need to track for the patch inspector as well..
basic code for CSurfaceUndo written. need to add hooks for the snapshot stuff and undo stuff. and a
debug flag to monitor the life cycle of the object.
some use cases:
- select a brush
- bring up surface inspector
- check we had the debug messages from CSurfaceUndo (initialise, activate, snapshot)
- edit the surface settings
- check the views are updating correctly
- hit Ok
- check we had a deactivate message
OK
- select a brush
- bring up surface inspector
- check we had the debug messages from CSurfaceUndo (initialise, activate, snapshot)
- edit the surface settings
- check the views are updating correctly
- hit cancel / escape
- check we have a undo and deactivate from CSurfaceUndo
OK
- select a brush
- bring up the surface inspector
- edit the surface settings
- hit apply
- edit them again
- hit cancel / escape
- check you get back to the apply state
OK
- make two brushes
- select a brush
- bring up surface inspector
- change settings
- select an additional brush
- check the surface inspector, new snapshot
- hit cancel
- check brushes remained in the same state
- use standard Undo
- check the first brush got back to it's initial settings
OK
- select a brush
- bring up surface inspector
- change settings
- select an additional brush
- check the surface inspector, new snapshot
- change more settings
- hit cancel
- check the first brush returned to intermediate state, and second to initial state (i.e. last snapshot)
OK
g_surfaceUndo acts as a layer on top of the core Undo code when the surface inspector is activated.
We need it because the surface inspector can edit faces which are not handled by the undo?
(or does the current code push the whole brush when editing a face?)
not sure of the utility of the g_surfaceDialog hooks here ..
default undo usage in the sruface inspector sends way too many undo messages.
with the new scheme we store in undo only when select/deselect or user hits apply
that way the 'Cancel' and later Ctrl+Z calls make sense
but is it worth implementing a new class to achieve that?? .. yes because we intend a later cleanup
of this part. (ahem is this reason good enough..)
this part is actually much closer from the undo code than I had expected..
'Cancel' call being an Undo call..
going to Inspector3:
don't create a new class, simply use the Undo more intelligently?
i.e. don't create undo stuff when editing the brush
-> we add a flag to turn off the default undo behaviour and force Undo storage when we want
we could also store the undo Id we are interested in and call undo several times to get it back
NOTE: what happens if the user hits undo when the surface inspector is up?
-> we'll have to take his request into account?
err .. performing which undo? The texture positioning or something else?
seems the snapshot approach would still make sense then?
more use cases, see with Undo calls and select/deselect events
NOTE: this whole thing is probably a single call to select_settexture that needs to be turned on/off
instead of working at the undo level. but we would like to move to messaging so maybe it still makes sense
the undo call is in Select_SetTexture (which does not have that many callers, I was expecting more)
the question about having the undo code keep working when surface inspector is around is still raised.
but it makes it a lot harder, gotta have a real inspector mode in the undo?
dunno, think about it again later
two operations are mixed in a single one and should not be:
reading the map to get the current data we'll manipulate
feed it in the dialog box widgets
WARNING: when putting stuff in the widgets, it raises a shitload of update messages and therefor completely
fucks up our OnOK OnApply OnCancel scheme (specially OnApply!)
NOTE: we want to switch between Surface inspector for brushes only and Patch inspector for patches only
there's some crappy code in the surface inspector that we need to get rid of
but need to check about that before with Spog or others
Forcing the way into using the surface inspector is SCREWED?
Doesn't seem to work the way we want to. Always get parasite Undo messages and stuff.
We could use a seperate stack for Undo with the surface inspector?
Just store the surface properties in a seperate stack?
When user hits cancel you go back and apply whatever you had?
Doesn't seem like a clean way either.
Now dealing with both regular surface inspector and patch inspector:
we have some stuff that needs to be on/off with the two inspectors
what about catching the messages and issuing new snapshots?
the main surface inspector is doing it?
no!
so what, we have several states?
FUCKED UP
INSPECTOR 5 ----------------------------------------------------------------
restarted from scratch, made much more simple changes.
trying another trick for undo (!)
just let the undo work as usual, but call undo ourselves in SetTexMods if we have create the last do
requires proper initialization/deinitialisation.. in SetTexMods and GetTexMods..
getting rid of patch manipulation code in the regular surface inspector. The buttons will
still work, but manip will require the patch inspector. (seems the patch inspector doesn't have that
much success anyway)
TODO:
OK get rid of patch stuff
OK get rid of the texture toolbar? (it's broken right now)
(and doesn't have anything usefull..)
OK (Partial) OnCancel? we need to cancel the texdef as well
store an undo texdef each time we grab new texdef stuff
this works in reverse than the Undo code? When we do the initial
problem is, in some cases the settings that show up are not in sync with what's in the inspector??
(we can't avoid that because if a brush is selected there's no single setting)
prolly get it out as is and let Spog or others send feedback about what it's supposed to do..
for now: store stuff in the cancel texdef when we initialize an undo loop
revert to that if OnCancel is used
OK message when spinning over a patch?
DUPLICATE (.. see below ..) check the increments we store in the SI are used when shift + arrows etc.
no it doesn't work .. the shifting on keyboard shortcuts is done with m_nTextureTweak
seems m_nTextureTweak is nowhere available in the prefs (and it's not in MFC builds either)
some cleanup to be done around that it seems
OK (.. merged with below, maybe some special cases left ..) texture widget (catch the Enter key to force-call an OnApply)
OK (.. see above ..) catch Enter key at dialog level to call OnDone
NO (.. it's clean, but thats too many lines of code ..) move the code that blokes updates to use gtk_signal_handler_block_by_func and gtk_signal_handler_block_by_func
OK shift + arrow must match the SI settings,
OK (FIXME .. not using the right scale (using the scale step instead! + add a button in SI to 'Match grid')
POSTPONED (.. m_nTextureTweak is used in the nudge commands ..
.. and nudge shortcuts are broken right now ..) get rid of m_nTextureTweak
+ SI and PI always on top!
+ known issues: "Match Grid" is broken in BP mode
now on the patch inspector (nightmare!):
OK (.. put it as readonly .. don't bother ..) texture name widget is screwed?
OK the spinners scheme doesn't work, the stuff in the dialog is the inc step and we just need arrows
OK get rid of the 'Type' dialog box
POSTPONED (.. can't do undo on PI without proper Undo module ..) add proper Done Apply Cancel with Undo
NO (.. too much work for something that sucks ..) make the changes reflect in the views when manipulating the entries
OK (.. using %g ..) cut down on the number of digits!
OK increment steps to be stored in the registry
putting the Cancel stuff in the surface inspector: only based on the Undo code, no cancel settings to store
because we don't have actual storage of a current texdef (we only send alterations) BTW we should do that for
brushes as well
the patch inspector works by increments, Patch_SetTextureInfo to incrementally modify the patch.
we can still do some undo by having a texdef storing the changes and working together with the undo
if the undo is recognized, it means our current texdef increment is valid
no, we can't represent the combination of several increments scale and rotate in a single texdef..
get rid of the undo code for now .. only Apply and Done left
it seems it's still vastly broken when you select something. or is it on linux only?
need a LOT of testing and figuring it out!!
selecting a brush breaks totally.. (the texture screws up it seems)
does it attempt to change the texture of the selected object??
also: it seems you can multiple select a same brush??
the UNDO code of the SURFACE INSPECTOR IS STILL BROKEN ????
(ok I'm really screwed, time to sleep)
-> can't reproduce now?? maybe it's linux specific problem, I can't tell
FOUND A WAY TO REPRODUCE THE CRASH:
+ select brush
+ hit "Fit"
+ hit the shift spinners two times
OR:
+ select single face on brush
+ manually edit scale values
-> maybe we have a problem with current texture? (NO)
it's some kind of infinite loop? we call UpdateSurfaceInspector from Select_Brush and bang!
no, it's a texdef from a face that got deleted
prolly that hooking the undo code in there screws up the selected faces stuff
if you undo a selected face operation, you end up with the whole brush selected.
but that does not necessarily explain why you remove the face at Undo_Start
ho well .. removed the undo buffering when selected faces and everything's better
would need to re-establish the right face selection after undo, might solve the problem
(actually you'd still need to have the settings point to the right object)
From PJ about the 'Match Grid' stuff: textures are moved in pixels, not units.
We must rely on the current texture scale AND gridsize to compute the shift increment
OK. Again I would have liked to get a design document before it being done. Main functionalities we
need in the inspector:
- Unifiy the inspector under a single dialog box, called with 'S'
- Depending on what is currently selected, display several frames in the inspector:
only brushes -> surface inspector
only patches -> patch inspector
brushes & patches -> both
and later when brush primitives are mixed with regular brushes + plugin entities, raise whatever
additional inspector stuff we need
- The camera view must update realtime when we change some parameters.
- Get rid of the Apply button, use the Undo code to store settings when surface inspector is
raised. If user hits Cancel, call the undo stuff.
- Use the message broadcasting stuff to keep the inspectors up to date when the user changes the
current selection. Be careful to keep the undo stuff in sync with the select / deselect operations.
- Use a 3-state scheme to display the params in the widgets. If two faces are selected that don't
have the same shift increment, just grey out the shift box.
Messaging:
- a good chunk of the work is moving the selection/creation stuff to the messaging API
we no longer use UpdateSurfaceDialog, we post messages instead ..
the surface inspector has hooked one of it's listeners into the corresponding message
we may need to reorganize the messages, maybe introduce a hierarchy?
or pass a void * param with messages?
- we don't post messages like "update surface inspector", we post messages that say "this and that
have changed", then the surface inspector reacts if it needs to.
Do we need marshalling in the messages? Very likely .. maybe using Gtk signal stuff would be interesting?
-> the messaging stuff is a big chunk of work and our surface inspector changes are not totally
dependent on it. Better leave that for l8r
the inspector works by states and transitions? Or we post messages to it?
Use case:
the user raises the inspector .. if we are up we'll ignore, if we are hidden we'll
go through the whole process (initialise, look at what is selected, display)
then we enter an active state (listening for select / deselects and applying stuff)
all in all it seems to be too big a change for next release. will see later probably.
Trying a few more days with it, see what happens. after all the interface is fairly restricted
so there's a good chance our changes are fairly stable in the end. But rebuilding the whole interface
part might be too much ...
We need something state based? AND a set of messages ..
but first, need to write the initialisation loop
build the dialog, get the current surface information and display
Undoing the changes on the selected stuff:
at any point in time, one can get a snapshot of selected stuff and use it to store the surface
properties settings for later on. But what happens if the user modifies the selected brush, pushing
it in the undo stack? Then we would cancel the changes? (and just backup to the state right after
the modif)
We could has the 'Apply' button used for that .. grey it out when the current state is the one in
the backup. This happens whenever we hit 'Apply' or change something in the selection.
The selection has several items: entities, brushes and selected faces (possibly later generic plugin entities)
Current undo stuff is aimed at entities and brushes.
NOTE: you can't have selected faces and brushes/entities at the same time, that's a good point to
keep that seperated to deal with undo and storage
On what side should the implemetation be ? undo.cpp select.cpp or surfacedialog.cpp ?
We are going to do it with the messaging API anyway..
And hook in the undo stuff, to reset the snapshot each time something gets pushed in the undo?
We have advanced stuff on the Inspector branch, doing basics on Alpha branch.
Start writing the watch code in surfacedialog.cpp, see if we need some merging with Undo stuff l8r
We need to track for the patch inspector as well..
basic code for CSurfaceUndo written. need to add hooks for the snapshot stuff and undo stuff. and a
debug flag to monitor the life cycle of the object.
some use cases:
- select a brush
- bring up surface inspector
- check we had the debug messages from CSurfaceUndo (initialise, activate, snapshot)
- edit the surface settings
- check the views are updating correctly
- hit Ok
- check we had a deactivate message
OK
- select a brush
- bring up surface inspector
- check we had the debug messages from CSurfaceUndo (initialise, activate, snapshot)
- edit the surface settings
- check the views are updating correctly
- hit cancel / escape
- check we have a undo and deactivate from CSurfaceUndo
OK
- select a brush
- bring up the surface inspector
- edit the surface settings
- hit apply
- edit them again
- hit cancel / escape
- check you get back to the apply state
OK
- make two brushes
- select a brush
- bring up surface inspector
- change settings
- select an additional brush
- check the surface inspector, new snapshot
- hit cancel
- check brushes remained in the same state
- use standard Undo
- check the first brush got back to it's initial settings
OK
- select a brush
- bring up surface inspector
- change settings
- select an additional brush
- check the surface inspector, new snapshot
- change more settings
- hit cancel
- check the first brush returned to intermediate state, and second to initial state (i.e. last snapshot)
OK
g_surfaceUndo acts as a layer on top of the core Undo code when the surface inspector is activated.
We need it because the surface inspector can edit faces which are not handled by the undo?
(or does the current code push the whole brush when editing a face?)
not sure of the utility of the g_surfaceDialog hooks here ..
default undo usage in the sruface inspector sends way too many undo messages.
with the new scheme we store in undo only when select/deselect or user hits apply
that way the 'Cancel' and later Ctrl+Z calls make sense
but is it worth implementing a new class to achieve that?? .. yes because we intend a later cleanup
of this part. (ahem is this reason good enough..)
this part is actually much closer from the undo code than I had expected..
'Cancel' call being an Undo call..
going to Inspector3:
don't create a new class, simply use the Undo more intelligently?
i.e. don't create undo stuff when editing the brush
-> we add a flag to turn off the default undo behaviour and force Undo storage when we want
we could also store the undo Id we are interested in and call undo several times to get it back
NOTE: what happens if the user hits undo when the surface inspector is up?
-> we'll have to take his request into account?
err .. performing which undo? The texture positioning or something else?
seems the snapshot approach would still make sense then?
more use cases, see with Undo calls and select/deselect events
NOTE: this whole thing is probably a single call to select_settexture that needs to be turned on/off
instead of working at the undo level. but we would like to move to messaging so maybe it still makes sense
the undo call is in Select_SetTexture (which does not have that many callers, I was expecting more)
the question about having the undo code keep working when surface inspector is around is still raised.
but it makes it a lot harder, gotta have a real inspector mode in the undo?
dunno, think about it again later
two operations are mixed in a single one and should not be:
reading the map to get the current data we'll manipulate
feed it in the dialog box widgets
WARNING: when putting stuff in the widgets, it raises a shitload of update messages and therefor completely
fucks up our OnOK OnApply OnCancel scheme (specially OnApply!)
NOTE: we want to switch between Surface inspector for brushes only and Patch inspector for patches only
there's some crappy code in the surface inspector that we need to get rid of
but need to check about that before with Spog or others
Forcing the way into using the surface inspector is SCREWED?
Doesn't seem to work the way we want to. Always get parasite Undo messages and stuff.
We could use a seperate stack for Undo with the surface inspector?
Just store the surface properties in a seperate stack?
When user hits cancel you go back and apply whatever you had?
Doesn't seem like a clean way either.
Now dealing with both regular surface inspector and patch inspector:
we have some stuff that needs to be on/off with the two inspectors
what about catching the messages and issuing new snapshots?
the main surface inspector is doing it?
no!
so what, we have several states?
FUCKED UP
INSPECTOR 5 ----------------------------------------------------------------
restarted from scratch, made much more simple changes.
trying another trick for undo (!)
just let the undo work as usual, but call undo ourselves in SetTexMods if we have create the last do
requires proper initialization/deinitialisation.. in SetTexMods and GetTexMods..
getting rid of patch manipulation code in the regular surface inspector. The buttons will
still work, but manip will require the patch inspector. (seems the patch inspector doesn't have that
much success anyway)
TODO:
OK get rid of patch stuff
OK get rid of the texture toolbar? (it's broken right now)
(and doesn't have anything usefull..)
OK (Partial) OnCancel? we need to cancel the texdef as well
store an undo texdef each time we grab new texdef stuff
this works in reverse than the Undo code? When we do the initial
problem is, in some cases the settings that show up are not in sync with what's in the inspector??
(we can't avoid that because if a brush is selected there's no single setting)
prolly get it out as is and let Spog or others send feedback about what it's supposed to do..
for now: store stuff in the cancel texdef when we initialize an undo loop
revert to that if OnCancel is used
OK message when spinning over a patch?
DUPLICATE (.. see below ..) check the increments we store in the SI are used when shift + arrows etc.
no it doesn't work .. the shifting on keyboard shortcuts is done with m_nTextureTweak
seems m_nTextureTweak is nowhere available in the prefs (and it's not in MFC builds either)
some cleanup to be done around that it seems
OK (.. merged with below, maybe some special cases left ..) texture widget (catch the Enter key to force-call an OnApply)
OK (.. see above ..) catch Enter key at dialog level to call OnDone
NO (.. it's clean, but thats too many lines of code ..) move the code that blokes updates to use gtk_signal_handler_block_by_func and gtk_signal_handler_block_by_func
OK shift + arrow must match the SI settings,
OK (FIXME .. not using the right scale (using the scale step instead! + add a button in SI to 'Match grid')
POSTPONED (.. m_nTextureTweak is used in the nudge commands ..
.. and nudge shortcuts are broken right now ..) get rid of m_nTextureTweak
+ SI and PI always on top!
+ known issues: "Match Grid" is broken in BP mode
now on the patch inspector (nightmare!):
OK (.. put it as readonly .. don't bother ..) texture name widget is screwed?
OK the spinners scheme doesn't work, the stuff in the dialog is the inc step and we just need arrows
OK get rid of the 'Type' dialog box
POSTPONED (.. can't do undo on PI without proper Undo module ..) add proper Done Apply Cancel with Undo
NO (.. too much work for something that sucks ..) make the changes reflect in the views when manipulating the entries
OK (.. using %g ..) cut down on the number of digits!
OK increment steps to be stored in the registry
putting the Cancel stuff in the surface inspector: only based on the Undo code, no cancel settings to store
because we don't have actual storage of a current texdef (we only send alterations) BTW we should do that for
brushes as well
the patch inspector works by increments, Patch_SetTextureInfo to incrementally modify the patch.
we can still do some undo by having a texdef storing the changes and working together with the undo
if the undo is recognized, it means our current texdef increment is valid
no, we can't represent the combination of several increments scale and rotate in a single texdef..
get rid of the undo code for now .. only Apply and Done left
it seems it's still vastly broken when you select something. or is it on linux only?
need a LOT of testing and figuring it out!!
selecting a brush breaks totally.. (the texture screws up it seems)
does it attempt to change the texture of the selected object??
also: it seems you can multiple select a same brush??
the UNDO code of the SURFACE INSPECTOR IS STILL BROKEN ????
(ok I'm really screwed, time to sleep)
-> can't reproduce now?? maybe it's linux specific problem, I can't tell
FOUND A WAY TO REPRODUCE THE CRASH:
+ select brush
+ hit "Fit"
+ hit the shift spinners two times
OR:
+ select single face on brush
+ manually edit scale values
-> maybe we have a problem with current texture? (NO)
it's some kind of infinite loop? we call UpdateSurfaceInspector from Select_Brush and bang!
no, it's a texdef from a face that got deleted
prolly that hooking the undo code in there screws up the selected faces stuff
if you undo a selected face operation, you end up with the whole brush selected.
but that does not necessarily explain why you remove the face at Undo_Start
ho well .. removed the undo buffering when selected faces and everything's better
would need to re-establish the right face selection after undo, might solve the problem
(actually you'd still need to have the settings point to the right object)
From PJ about the 'Match Grid' stuff: textures are moved in pixels, not units.
We must rely on the current texture scale AND gridsize to compute the shift increment

View file

@ -1,17 +1,17 @@
#!perl
rename("$ARGV[0]", "$ARGV[0].old");
open(FILE, "$ARGV[0].old");
open(OFILE, ">$ARGV[0]");
while(<FILE>)
{
if($. != $ARGV[1])
{
print OFILE;
next;
}
s/Sys_Printf \(/Sys_FPrintf \(SYS_VRB,/;
s/Sys_Printf\(/Sys_FPrintf \(SYS_VRB,/;
print OFILE;
}
close(OFILE);
#!perl
rename("$ARGV[0]", "$ARGV[0].old");
open(FILE, "$ARGV[0].old");
open(OFILE, ">$ARGV[0]");
while(<FILE>)
{
if($. != $ARGV[1])
{
print OFILE;
next;
}
s/Sys_Printf \(/Sys_FPrintf \(SYS_VRB,/;
s/Sys_Printf\(/Sys_FPrintf \(SYS_VRB,/;
print OFILE;
}
close(OFILE);
close(FILE);

View file

@ -1,17 +1,17 @@
#!perl
rename("brush.c", "brush.c.old");
open(FILE, "brush.c.old");
open(OFILE, ">brush.c");
while(<FILE>)
{
if($. != 150)
{
print OFILE;
next;
}
s/Sys_Printf \(/Sys_FPrintf \(SYS_VRB,/;
s/Sys_Printf\(/Sys_FPrintf \(SYS_VRB,/;
print OFILE;
}
close(OFILE);
#!perl
rename("brush.c", "brush.c.old");
open(FILE, "brush.c.old");
open(OFILE, ">brush.c");
while(<FILE>)
{
if($. != 150)
{
print OFILE;
next;
}
s/Sys_Printf \(/Sys_FPrintf \(SYS_VRB,/;
s/Sys_Printf\(/Sys_FPrintf \(SYS_VRB,/;
print OFILE;
}
close(OFILE);
close(FILE);

View file

@ -1,27 +1,27 @@
printf mess in q3map
(and in the libs)
q3map: several breeds .. qprintf _printf printf
should all resolve to use a single Sys_Printf thing
and put #define printf ..
for the static libs? need to use function pointers..
q3map uses common/cmdlib.c
Radiant links against cmdlib.lib based on libs/cmdlib/cmdlib.cpp
but eventually we'll want to use the same Sys_Printf scheme in q3map AND Radiant?
qprintf and _printf are defined in common/cmdlib.c
BUT: modifying cmdlib would probably break bspc and other stuff that relies on it?
moving q3map to use a custom version of cmdlib.c in q3map/cmdlib.c
removing the qprintf and _printf stuff, moving to a seperate printout.c file
compiling libxml on win32: need to turn off a bunch of stuff.
problem: we got two xmlversion.h files??
we can't get rid of using libxml/xmlversion.h, so the solution is to get rid of xmlversion.h
(add ../libxml to the paths)
fuck!
we also compile some .c files from common/ !
-> create a common2/ dir ..
printf mess in q3map
(and in the libs)
q3map: several breeds .. qprintf _printf printf
should all resolve to use a single Sys_Printf thing
and put #define printf ..
for the static libs? need to use function pointers..
q3map uses common/cmdlib.c
Radiant links against cmdlib.lib based on libs/cmdlib/cmdlib.cpp
but eventually we'll want to use the same Sys_Printf scheme in q3map AND Radiant?
qprintf and _printf are defined in common/cmdlib.c
BUT: modifying cmdlib would probably break bspc and other stuff that relies on it?
moving q3map to use a custom version of cmdlib.c in q3map/cmdlib.c
removing the qprintf and _printf stuff, moving to a seperate printout.c file
compiling libxml on win32: need to turn off a bunch of stuff.
problem: we got two xmlversion.h files??
we can't get rid of using libxml/xmlversion.h, so the solution is to get rid of xmlversion.h
(add ../libxml to the paths)
fuck!
we also compile some .c files from common/ !
-> create a common2/ dir ..

View file

@ -1,34 +1,34 @@
========================================================================
CONSOLE APPLICATION : XMLPush
========================================================================
AppWizard has created this XMLPush application for you.
This file contains a summary of what you will find in each of the files that
make up your XMLPush application.
XMLPush.dsp
This file (the project file) contains information at the project level and
is used to build a single project or subproject. Other users can share the
project (.dsp) file, but they should export the makefiles locally.
XMLPush.cpp
This is the main application source file.
/////////////////////////////////////////////////////////////////////////////
Other standard files:
StdAfx.h, StdAfx.cpp
These files are used to build a precompiled header (PCH) file
named XMLPush.pch and a precompiled types file named StdAfx.obj.
/////////////////////////////////////////////////////////////////////////////
Other notes:
AppWizard uses "TODO:" to indicate parts of the source code you
should add to or customize.
/////////////////////////////////////////////////////////////////////////////
========================================================================
CONSOLE APPLICATION : XMLPush
========================================================================
AppWizard has created this XMLPush application for you.
This file contains a summary of what you will find in each of the files that
make up your XMLPush application.
XMLPush.dsp
This file (the project file) contains information at the project level and
is used to build a single project or subproject. Other users can share the
project (.dsp) file, but they should export the makefiles locally.
XMLPush.cpp
This is the main application source file.
/////////////////////////////////////////////////////////////////////////////
Other standard files:
StdAfx.h, StdAfx.cpp
These files are used to build a precompiled header (PCH) file
named XMLPush.pch and a precompiled types file named StdAfx.obj.
/////////////////////////////////////////////////////////////////////////////
Other notes:
AppWizard uses "TODO:" to indicate parts of the source code you
should add to or customize.
/////////////////////////////////////////////////////////////////////////////

View file

@ -1,27 +1,27 @@
XMLmap branch:
need to move the map loading / saving code out in a module
what are the main dependencies?
main functions to move out:
Map_LoadFile
Map_SaveFile
(and all their direct dependencies/call graph)
ex Entity_Parse Brush_Parse Entity_Write Brush_Write
but? even changing to XML format we would need those functions too?
is it worth having the .map and .xmlmap through a same interface?
what dependencies?
-> active_brushes
-> GetToken etc.
-> LoadFile (load into a buffer) .. that's VFS right?
first step: move some code out in map module and try to compile it..
Map_LoadFile for example
or the whole map.cpp?
first problem: entity_t is declared in entity.h, currently not available to
the plugin API. Clean way would be to create a wrapper, but speed says we
should move entity_t to qertypes.h..
XMLmap branch:
need to move the map loading / saving code out in a module
what are the main dependencies?
main functions to move out:
Map_LoadFile
Map_SaveFile
(and all their direct dependencies/call graph)
ex Entity_Parse Brush_Parse Entity_Write Brush_Write
but? even changing to XML format we would need those functions too?
is it worth having the .map and .xmlmap through a same interface?
what dependencies?
-> active_brushes
-> GetToken etc.
-> LoadFile (load into a buffer) .. that's VFS right?
first step: move some code out in map module and try to compile it..
Map_LoadFile for example
or the whole map.cpp?
first problem: entity_t is declared in entity.h, currently not available to
the plugin API. Clean way would be to create a wrapper, but speed says we
should move entity_t to qertypes.h..

View file

@ -1,76 +1,76 @@
Listing of required modules and interfaces as an XML file
=========================================================
Purpose:
--------
Make the editor more data driven. Be able to specify during
startup the full running configuration of the editor:
- what modules to load
- general execution paths (i.e. what's in the project settings)
- configuration for the loaded modules
- user preferences
Feature Requirements:
---------------------
This is primarily intended for multiple games support. A restart
of the editor may be required when going from one game to the
other, but otherwise it should read the XML file and initialize
the right modules and APIs from there.
Don't have a clear view of what multiple games support is gonna
be like. Can list a few things:
- some interfaces are required for startup in a given game mode.
That's primarily what the XML config file is there for.
For instance in Q3 you will require Q3 map format module
and Q1 will require Q1 map format module
- some modules are to be ignored? that's primary intended to
avoid loading unneeded modules.
- some plugins are loaded for all games?
- some plugins are only relevant for some games?
(those two suggest various installation paths for modules
and directory-based scan?)
- a plugin might require some other APIs to complete it's loading
process (i.e. sending it's own XML description of required
interfaces).
Constaints:
-----------
We have a nasty collision between preferences / project settings
and XML requirements. All three things need to be unified in some way.
The long term target being to have a central installation location
for the editor, and independant packages for each game.
What kind of difference is there between project settings and prefs?
Prefs would be user settings that survive throughout all games,
whereas project settings are per-game / per-mod configuration. Turns
out it's all a matter of loading the right configuration chunks at the
right time.
Proposed implementation:
------------------------
Use key/values (== property bags) based on XML format for everything.
Use them on project settings, and user prefs. The only difference
between what would be project settings and what would be user pref
is in which game configuration they are loaded, and how they are used.
Project templates: We have a particular syntax to build settings from
a 'template' version. Instead of loading a project template, we should
be selecting a template from a list.
Default startup: If we are configured to load last project on startup,
load it .. otherwise display a list of games and templates?
Module library:
---------------
The dynamic loading / interfaces sharing / pure virtual classes needs
to be implemented in a generic module. It should be the basis of the
editor startup process.
Listing of required modules and interfaces as an XML file
=========================================================
Purpose:
--------
Make the editor more data driven. Be able to specify during
startup the full running configuration of the editor:
- what modules to load
- general execution paths (i.e. what's in the project settings)
- configuration for the loaded modules
- user preferences
Feature Requirements:
---------------------
This is primarily intended for multiple games support. A restart
of the editor may be required when going from one game to the
other, but otherwise it should read the XML file and initialize
the right modules and APIs from there.
Don't have a clear view of what multiple games support is gonna
be like. Can list a few things:
- some interfaces are required for startup in a given game mode.
That's primarily what the XML config file is there for.
For instance in Q3 you will require Q3 map format module
and Q1 will require Q1 map format module
- some modules are to be ignored? that's primary intended to
avoid loading unneeded modules.
- some plugins are loaded for all games?
- some plugins are only relevant for some games?
(those two suggest various installation paths for modules
and directory-based scan?)
- a plugin might require some other APIs to complete it's loading
process (i.e. sending it's own XML description of required
interfaces).
Constaints:
-----------
We have a nasty collision between preferences / project settings
and XML requirements. All three things need to be unified in some way.
The long term target being to have a central installation location
for the editor, and independant packages for each game.
What kind of difference is there between project settings and prefs?
Prefs would be user settings that survive throughout all games,
whereas project settings are per-game / per-mod configuration. Turns
out it's all a matter of loading the right configuration chunks at the
right time.
Proposed implementation:
------------------------
Use key/values (== property bags) based on XML format for everything.
Use them on project settings, and user prefs. The only difference
between what would be project settings and what would be user pref
is in which game configuration they are loaded, and how they are used.
Project templates: We have a particular syntax to build settings from
a 'template' version. Instead of loading a project template, we should
be selecting a template from a list.
Default startup: If we are configured to load last project on startup,
load it .. otherwise display a list of games and templates?
Module library:
---------------
The dynamic loading / interfaces sharing / pure virtual classes needs
to be implemented in a generic module. It should be the basis of the
editor startup process.

View file

@ -1,33 +1,33 @@
** currently supported debug messages:
* map leaked / pointfile information
+ tested
* duplicate plane
+ tested
* degenerate plane, mirrored plane
+ testing may not be necessary, exact same code as duplicate plane
* mixed CONTENTS_DETAIL and CONTENTS_STRUCTURAL
- not tested!
* fog brush has multiple visible sides
+ tested
* WindingFromDrawSurf failed: MAX_POINTS_ON_WINDING exceeded
+ tested, only outputs a single point, would need much improvement
(TstMaps/western.map)
* MAX_BUILD_SIDES
uses xml_Select as other warnings, switched xml_Select to error or warn
+ tested
** to-be-added list (and associated test map file if any)
* Node without a volume
* leaf with too many portals
-> both in Desktop_p_leaf.map, contributed by y_lavanant@vistech.ie
Mesh lightmap miscount
** currently supported debug messages:
* map leaked / pointfile information
+ tested
* duplicate plane
+ tested
* degenerate plane, mirrored plane
+ testing may not be necessary, exact same code as duplicate plane
* mixed CONTENTS_DETAIL and CONTENTS_STRUCTURAL
- not tested!
* fog brush has multiple visible sides
+ tested
* WindingFromDrawSurf failed: MAX_POINTS_ON_WINDING exceeded
+ tested, only outputs a single point, would need much improvement
(TstMaps/western.map)
* MAX_BUILD_SIDES
uses xml_Select as other warnings, switched xml_Select to error or warn
+ tested
** to-be-added list (and associated test map file if any)
* Node without a volume
* leaf with too many portals
-> both in Desktop_p_leaf.map, contributed by y_lavanant@vistech.ie
Mesh lightmap miscount
(no test map)

File diff suppressed because it is too large Load diff

View file

@ -1,75 +1,75 @@
search orders with different settings
=====================
NON-TEAMPLAY
=====================
-------------------------------------------------
headmodel = *callisto/lily
models/players/heads/callisto/lily/head_default.skin
models/players/heads/callisto/head_lily.skin
-------------------------------------------------
headmodel = callisto/lily
models/players/callisto/lily/head_default.skin
models/players/callisto/head_lily.skin
models/players/heads/callisto/lily/head_default.skin
models/players/heads/callisto/head_lily.skin
=====================
Q3 TEAMPLAY
=====================
-------------------------------------------------
team_headmodel = *callisto/lily
team = red
models/players/heads/callisto/lily/head_red.skin
models/players/heads/callisto/head_red.skin
-------------------------------------------------
team_headmodel = callisto/lily
team = red
models/players/callisto/lily/head_red.skin
models/players/callisto/head_red.skin
models/players/heads/callisto/lily/head_red.skin
models/players/heads/callisto/head_red.skin
=====================
TA TEAMPLAY
=====================
-------------------------------------------------
team_headmodel = *callisto/lily
team = red
teamName = Stroggs
models/players/heads/callisto/lily/Stroggs/head_red.skin
models/players/heads/callisto/Stroggs/head_red.skin
models/players/heads/callisto/lily/head_red.skin
models/players/heads/callisto/head_red.skin
-------------------------------------------------
team_headmodel = callisto/lily
team = red
teamName = Stroggs
models/players/callisto/lily/Stroggs/head_red.skin
models/players/callisto/Stroggs/head_red.skin
models/players/callisto/lily/head_red.skin
models/players/callisto/head_red.skin
models/players/heads/callisto/lily/Stroggs/head_red.skin
models/players/heads/callisto/Stroggs/head_red.skin
models/players/heads/callisto/lily/head_red.skin
models/players/heads/callisto/head_red.skin
search orders with different settings
=====================
NON-TEAMPLAY
=====================
-------------------------------------------------
headmodel = *callisto/lily
models/players/heads/callisto/lily/head_default.skin
models/players/heads/callisto/head_lily.skin
-------------------------------------------------
headmodel = callisto/lily
models/players/callisto/lily/head_default.skin
models/players/callisto/head_lily.skin
models/players/heads/callisto/lily/head_default.skin
models/players/heads/callisto/head_lily.skin
=====================
Q3 TEAMPLAY
=====================
-------------------------------------------------
team_headmodel = *callisto/lily
team = red
models/players/heads/callisto/lily/head_red.skin
models/players/heads/callisto/head_red.skin
-------------------------------------------------
team_headmodel = callisto/lily
team = red
models/players/callisto/lily/head_red.skin
models/players/callisto/head_red.skin
models/players/heads/callisto/lily/head_red.skin
models/players/heads/callisto/head_red.skin
=====================
TA TEAMPLAY
=====================
-------------------------------------------------
team_headmodel = *callisto/lily
team = red
teamName = Stroggs
models/players/heads/callisto/lily/Stroggs/head_red.skin
models/players/heads/callisto/Stroggs/head_red.skin
models/players/heads/callisto/lily/head_red.skin
models/players/heads/callisto/head_red.skin
-------------------------------------------------
team_headmodel = callisto/lily
team = red
teamName = Stroggs
models/players/callisto/lily/Stroggs/head_red.skin
models/players/callisto/Stroggs/head_red.skin
models/players/callisto/lily/head_red.skin
models/players/callisto/head_red.skin
models/players/heads/callisto/lily/Stroggs/head_red.skin
models/players/heads/callisto/Stroggs/head_red.skin
models/players/heads/callisto/lily/head_red.skin
models/players/heads/callisto/head_red.skin

View file

@ -1,73 +1,73 @@
search orders with different settings
=====================
NON-TEAMPLAY
=====================
-------------------------------------------------
model = hunter/harpy
legs:
models/players/hunter/lower_harpy_default.skin
models/players/hunter/lower_harpy.skin
models/players/characters/james/lower_harpy_default.skin
models/players/characters/james/lower_harpy.skin
torso:
models/players/hunter/upper_harpy_default.skin
models/players/hunter/upper_harpy.skin
models/players/characters/hunter/upper_harpy_default.skin
models/players/characters/hunter/upper_harpy.skin
=====================
Q3 TEAMPLAY
=====================
-------------------------------------------------
team_model = hunter/harpy
team = red
legs:
models/players/hunter/lower_harpy_red.skin
models/players/hunter/lower_red.skin
models/players/characters/hunter/lower_harpy_red.skin
models/players/characters/hunter/lower_red.skin
torso:
models/players/hunter/upper_harpy_red.skin
models/players/hunter/upper_red.skin
models/players/characters/hunter/upper_harpy_red.skin
models/players/characters/hunter/upper_red.skin
=====================
TA TEAMPLAY
=====================
-------------------------------------------------
team_model = james/badass
team = red
teamName = Stroggs
legs:
models/players/james/Stroggs/lower_badass_red.skin
models/players/james/Stroggs/lower_red.skin
models/players/james/lower_badass_red.skin
models/players/james/lower_red.skin
models/players/characters/james/Stroggs/lower_badass_red.skin
models/players/characters/james/Stroggs/lower_red.skin
models/players/characters/james/lower_badass_red.skin
models/players/characters/james/lower_red.skin
torso:
models/players/james/Stroggs/upper_badass_red.skin
models/players/james/Stroggs/upper_red.skin
models/players/james/upper_badass_red.skin
models/players/james/upper_red.skin
models/players/characters/james/Stroggs/upper_badass_red.skin
models/players/characters/james/Stroggs/upper_red.skin
models/players/characters/james/upper_badass_red.skin
models/players/characters/james/upper_red.skin
search orders with different settings
=====================
NON-TEAMPLAY
=====================
-------------------------------------------------
model = hunter/harpy
legs:
models/players/hunter/lower_harpy_default.skin
models/players/hunter/lower_harpy.skin
models/players/characters/james/lower_harpy_default.skin
models/players/characters/james/lower_harpy.skin
torso:
models/players/hunter/upper_harpy_default.skin
models/players/hunter/upper_harpy.skin
models/players/characters/hunter/upper_harpy_default.skin
models/players/characters/hunter/upper_harpy.skin
=====================
Q3 TEAMPLAY
=====================
-------------------------------------------------
team_model = hunter/harpy
team = red
legs:
models/players/hunter/lower_harpy_red.skin
models/players/hunter/lower_red.skin
models/players/characters/hunter/lower_harpy_red.skin
models/players/characters/hunter/lower_red.skin
torso:
models/players/hunter/upper_harpy_red.skin
models/players/hunter/upper_red.skin
models/players/characters/hunter/upper_harpy_red.skin
models/players/characters/hunter/upper_red.skin
=====================
TA TEAMPLAY
=====================
-------------------------------------------------
team_model = james/badass
team = red
teamName = Stroggs
legs:
models/players/james/Stroggs/lower_badass_red.skin
models/players/james/Stroggs/lower_red.skin
models/players/james/lower_badass_red.skin
models/players/james/lower_red.skin
models/players/characters/james/Stroggs/lower_badass_red.skin
models/players/characters/james/Stroggs/lower_red.skin
models/players/characters/james/lower_badass_red.skin
models/players/characters/james/lower_red.skin
torso:
models/players/james/Stroggs/upper_badass_red.skin
models/players/james/Stroggs/upper_red.skin
models/players/james/upper_badass_red.skin
models/players/james/upper_red.skin
models/players/characters/james/Stroggs/upper_badass_red.skin
models/players/characters/james/Stroggs/upper_red.skin
models/players/characters/james/upper_badass_red.skin
models/players/characters/james/upper_red.skin

View file

@ -1,48 +1,48 @@
#!/usr/bin/env python
import os.path, sys, shutil
def install_file( path, src_path, f ):
src = os.path.join( src_path, f )
dst = os.path.join( path, f )
print '%s -> %s' % ( src, dst )
shutil.copyfile( src, dst )
def install( path, src_path ):
for f in [ 'radiant.exe', 'radiant.pdb' ]:
install_file( path, src_path, f )
modules_path = os.path.join( path, 'modules' )
try:
os.makedirs( modules_path )
except:
pass
assert( os.path.exists( modules_path ) )
modules_src = os.path.join( src_path, 'modules' )
assert( os.path.exists( modules_src ) )
for e in os.listdir( modules_src ):
if ( e[-4:] == '.dll' or e[-4:] == '.pdb' ):
install_file( modules_path, modules_src, e )
plugins_path = os.path.join( path, 'plugins' )
try:
os.makedirs( plugins_path )
except:
pass
assert( os.path.exists( plugins_path ) )
plugins_src = os.path.join( src_path, 'plugins' )
assert( os.path.exists( plugins_src ) )
for e in os.listdir( plugins_src ):
if ( e[-4:] == '.dll' or e[-4:] == '.pdb' ):
install_file( plugins_path, plugins_src, e )
if __name__ == '__main__':
if ( len( sys.argv ) <= 2 or not os.path.exists( sys.argv[1] ) or not os.path.exists( sys.argv[2] ) ):
print 'usage: install [target directory] [source directory]'
sys.exit(1)
print 'Install %s into %s' % ( sys.argv[2], sys.argv[1] )
install( sys.argv[1], sys.argv[2] )
#!/usr/bin/env python
import os.path, sys, shutil
def install_file( path, src_path, f ):
src = os.path.join( src_path, f )
dst = os.path.join( path, f )
print '%s -> %s' % ( src, dst )
shutil.copyfile( src, dst )
def install( path, src_path ):
for f in [ 'radiant.exe', 'radiant.pdb' ]:
install_file( path, src_path, f )
modules_path = os.path.join( path, 'modules' )
try:
os.makedirs( modules_path )
except:
pass
assert( os.path.exists( modules_path ) )
modules_src = os.path.join( src_path, 'modules' )
assert( os.path.exists( modules_src ) )
for e in os.listdir( modules_src ):
if ( e[-4:] == '.dll' or e[-4:] == '.pdb' ):
install_file( modules_path, modules_src, e )
plugins_path = os.path.join( path, 'plugins' )
try:
os.makedirs( plugins_path )
except:
pass
assert( os.path.exists( plugins_path ) )
plugins_src = os.path.join( src_path, 'plugins' )
assert( os.path.exists( plugins_src ) )
for e in os.listdir( plugins_src ):
if ( e[-4:] == '.dll' or e[-4:] == '.pdb' ):
install_file( plugins_path, plugins_src, e )
if __name__ == '__main__':
if ( len( sys.argv ) <= 2 or not os.path.exists( sys.argv[1] ) or not os.path.exists( sys.argv[2] ) ):
print 'usage: install [target directory] [source directory]'
sys.exit(1)
print 'Install %s into %s' % ( sys.argv[2], sys.argv[1] )
install( sys.argv[1], sys.argv[2] )

View file

@ -1,190 +1,190 @@
synapse code design documentation
=================================
Objective:
----------
Provide a simple cross platform layer to use dynamically loaded code
inside a core application. Portability intended to win32 / linux / MacOS (?)
Main features are:
- designed for single process only, no remote clients, no asynchronous processes
- a client/server architecture, based on configuration files: a main binary,
loading a set of shared objects
Constraints:
------------
- large existing plugin code in Radiant!
must be compatible with minimal changes, specially for plugins (i.e. clients)
- make things as much transparent as possible
(ideally, no real difference between a static linkage and dynamic linkage,
cf usage of #define macros to wrap a function call onto a code pointer)
Features:
---------
Gather as much generic code as possible in a static .lib with minimal dependencies
(only dependency should be configuration files parser)
NOTE: current effective dependency is STL / glib / xml
Main executable implemented as a server, all others as clients. What has to
be done for a server / what has to be done for a client needs to be documented.
Provide as much scripts and tools and guidelines as needed (scripted generation of
some .h files?)
Proposed implementation:
------------------------
- have linux/ and win32/ subdirectories with OS-specific implementations
(such as dynamically loading shared objects, and doing the initial query?)
- reduce the API of a client to the minimum: one exported function?
provide a squeleton to make new clients easily?
Server use case:
1) build information about location of the modules (from code and config files)
2) load all modules and query information about their APIs
NOTE: could read the APIs from some XML description files instead of
querying it from the modules?
3) build information about the required function tables
i.e.: setup a list with the function tables to be filled in, and what they
need to be filled in with.
4) resolve the function table
NOTE: is this iterative? will some plugins request more APIs as they get filled
up?
NOTE: do we have optional tables?
5) unload unreferences modules
NOTE: we don't expect to be unloading a LOT of modules, otherwise we would
setup a solution that allows exploring of the APIs a given module provides
from a file description. Or you could 'cache' that (md5-checksum the file, and
maintain an XML list).
Client use case:
1) dynamically loaded
2) prompted for the interfaces it provides
2) prompted for the interfaces it requires
3) either unloaded, or told what interfaces have been filled in
The client module exports an Synapse_EnumerateInterfaces entry point
This returns an ISynapseClient, which lists what the plugin provides, and what it requires
The APIs:
An interface is a function table, GUID / major string / minor string
GUID is a shortcut to reference a major string (i.e. the human readable thing)
the GUID / major string is unique for a given interface
minor string is used to reference a particular version of an API
(for instance when talking about image loading functionality, tga and jpg etc.)
The GUID scheme is handy because it provides easy tests. They are not strictly
necessary but we will probably want to keep them. Should we extend to GUIDs
for minor too?
Roadmap:
--------
Need to convert the core (as server) and the required modules. Will have
clearer view of what's to be done along the way.
Implementation design:
----------------------
There is a client and server side to synapse. Typically server is in Radiant or q3map,
client is in any module. For implementation, we have one server class and one client class.
It would be possible to have two seperate libraries, synapse-client and synapse-server. But
that only brings down the statically linked stuff to make things more complicated build-sysem
wise.
Initial implementation has been using isynapse.h and synapse.h, to provide a pure virtual
base class for server and client. But that doesn't bring any major functionality, it's easier
if both sides see the full API of the client and server classes.
A side problem is the diagnostic printing functionality. For easy debugging we require that
the synapse code can have access to a Sys_Printf or similar function at all times (that is for
client and server implementation). On client we will pipe through the main API to the server
as soon as we can in most cases. Using Sys_Printf would bring us to a dead end situation, since
when synapse is used as the server, the main code implements it's own Sys_Printf stuff.
Instead we introduce a local Syn_Printf implementation, which can be overriden in the server
to point to the appropriate print functions.
Runtime config:
---------------
Something that has not been looked upon a lot yet, runtime configuration. What interfaces
are loaded etc. Ideally, from an XML config file. A client explicitely requests the
server to load all the interfaces it requires (in this case, the client is radiant or
q3map).
Plugins are somewhat out of the 'required interfaces' frame, since they are loaded
whenever they are found. It is possible however that some plugins would not want to be
loaded in if the game doesn't match etc. in case they would need to access the global
config?
In most cases a given API is only required once for editor functionality. (VFS for
instance), so our #define strategy for easy mapping of the functions should still work.
Version checks, reference counting:
------------------------------------
Need version checking at several levels. A version string (major/minor) on the main API
entry point (straight in the exported function to save as much as possible for
compatibility). For individual APIs, we have been feeding the struct size into the first
int of the struct so far, and it has worked very well.
Reference counting: we introduced class based APIs to solve the ref counting issues,
which are not easy to solve on C function tables. That problem would arise in plugin
situations where we might want to 'reload' or 'unload' some plugins. The server could
keep track of the ref count.
Caching?
--------
We are going to load every shared object we find and query it for it's interfaces. Then
we will unload the stuff we don't want. This is going to slow down the startup process.
We could extract the API information in a cache to avoid the loading step.
Interfaces with multiple minors against I* objects?
---------------------------------------------------
Looking at the iimage.h API, why not having instead something that enumerates C++ objects
directly? Mainly because we want to be able to spread several minors accross multiple modules
and still use them together. And straight laid out function tables in C structs are only
one indirection when the table is static.
This raises a broader topic, instead of requesting APIs, we could request objects directly.
Would that be of any use?
Loading interfaces / resolving interdependencies strategy
---------------------------------------------------------
Some notes about how we load the modules and resolve interdependencies:
We want to avoid requesting a module for an API it provides before all the APIs it requires
have been filled in (mostly stability concerns, a module may be doing whatever internally
when we request something from it). The exception being the module we are trying to resolve
for (since we need a start point for resolution). But in all likelyness we resolve for radiant
or q3map for instance.
With this approach, it is possible that some situations could not be resolved, for instance:
Radiant
requires A
provides B
module 1
requires C
provides A
module 2
requires A
provides C
if we start by resolving Radiant, we will get stuck
if we are ready to ask module to provide the API even though the required is not meant, it would work
but that kind of situation is very unlikely, so sticking to safer strategy
Configuration
-------------
the config info needs to go down to the clients too
synapse code design documentation
=================================
Objective:
----------
Provide a simple cross platform layer to use dynamically loaded code
inside a core application. Portability intended to win32 / linux / MacOS (?)
Main features are:
- designed for single process only, no remote clients, no asynchronous processes
- a client/server architecture, based on configuration files: a main binary,
loading a set of shared objects
Constraints:
------------
- large existing plugin code in Radiant!
must be compatible with minimal changes, specially for plugins (i.e. clients)
- make things as much transparent as possible
(ideally, no real difference between a static linkage and dynamic linkage,
cf usage of #define macros to wrap a function call onto a code pointer)
Features:
---------
Gather as much generic code as possible in a static .lib with minimal dependencies
(only dependency should be configuration files parser)
NOTE: current effective dependency is STL / glib / xml
Main executable implemented as a server, all others as clients. What has to
be done for a server / what has to be done for a client needs to be documented.
Provide as much scripts and tools and guidelines as needed (scripted generation of
some .h files?)
Proposed implementation:
------------------------
- have linux/ and win32/ subdirectories with OS-specific implementations
(such as dynamically loading shared objects, and doing the initial query?)
- reduce the API of a client to the minimum: one exported function?
provide a squeleton to make new clients easily?
Server use case:
1) build information about location of the modules (from code and config files)
2) load all modules and query information about their APIs
NOTE: could read the APIs from some XML description files instead of
querying it from the modules?
3) build information about the required function tables
i.e.: setup a list with the function tables to be filled in, and what they
need to be filled in with.
4) resolve the function table
NOTE: is this iterative? will some plugins request more APIs as they get filled
up?
NOTE: do we have optional tables?
5) unload unreferences modules
NOTE: we don't expect to be unloading a LOT of modules, otherwise we would
setup a solution that allows exploring of the APIs a given module provides
from a file description. Or you could 'cache' that (md5-checksum the file, and
maintain an XML list).
Client use case:
1) dynamically loaded
2) prompted for the interfaces it provides
2) prompted for the interfaces it requires
3) either unloaded, or told what interfaces have been filled in
The client module exports an Synapse_EnumerateInterfaces entry point
This returns an ISynapseClient, which lists what the plugin provides, and what it requires
The APIs:
An interface is a function table, GUID / major string / minor string
GUID is a shortcut to reference a major string (i.e. the human readable thing)
the GUID / major string is unique for a given interface
minor string is used to reference a particular version of an API
(for instance when talking about image loading functionality, tga and jpg etc.)
The GUID scheme is handy because it provides easy tests. They are not strictly
necessary but we will probably want to keep them. Should we extend to GUIDs
for minor too?
Roadmap:
--------
Need to convert the core (as server) and the required modules. Will have
clearer view of what's to be done along the way.
Implementation design:
----------------------
There is a client and server side to synapse. Typically server is in Radiant or q3map,
client is in any module. For implementation, we have one server class and one client class.
It would be possible to have two seperate libraries, synapse-client and synapse-server. But
that only brings down the statically linked stuff to make things more complicated build-sysem
wise.
Initial implementation has been using isynapse.h and synapse.h, to provide a pure virtual
base class for server and client. But that doesn't bring any major functionality, it's easier
if both sides see the full API of the client and server classes.
A side problem is the diagnostic printing functionality. For easy debugging we require that
the synapse code can have access to a Sys_Printf or similar function at all times (that is for
client and server implementation). On client we will pipe through the main API to the server
as soon as we can in most cases. Using Sys_Printf would bring us to a dead end situation, since
when synapse is used as the server, the main code implements it's own Sys_Printf stuff.
Instead we introduce a local Syn_Printf implementation, which can be overriden in the server
to point to the appropriate print functions.
Runtime config:
---------------
Something that has not been looked upon a lot yet, runtime configuration. What interfaces
are loaded etc. Ideally, from an XML config file. A client explicitely requests the
server to load all the interfaces it requires (in this case, the client is radiant or
q3map).
Plugins are somewhat out of the 'required interfaces' frame, since they are loaded
whenever they are found. It is possible however that some plugins would not want to be
loaded in if the game doesn't match etc. in case they would need to access the global
config?
In most cases a given API is only required once for editor functionality. (VFS for
instance), so our #define strategy for easy mapping of the functions should still work.
Version checks, reference counting:
------------------------------------
Need version checking at several levels. A version string (major/minor) on the main API
entry point (straight in the exported function to save as much as possible for
compatibility). For individual APIs, we have been feeding the struct size into the first
int of the struct so far, and it has worked very well.
Reference counting: we introduced class based APIs to solve the ref counting issues,
which are not easy to solve on C function tables. That problem would arise in plugin
situations where we might want to 'reload' or 'unload' some plugins. The server could
keep track of the ref count.
Caching?
--------
We are going to load every shared object we find and query it for it's interfaces. Then
we will unload the stuff we don't want. This is going to slow down the startup process.
We could extract the API information in a cache to avoid the loading step.
Interfaces with multiple minors against I* objects?
---------------------------------------------------
Looking at the iimage.h API, why not having instead something that enumerates C++ objects
directly? Mainly because we want to be able to spread several minors accross multiple modules
and still use them together. And straight laid out function tables in C structs are only
one indirection when the table is static.
This raises a broader topic, instead of requesting APIs, we could request objects directly.
Would that be of any use?
Loading interfaces / resolving interdependencies strategy
---------------------------------------------------------
Some notes about how we load the modules and resolve interdependencies:
We want to avoid requesting a module for an API it provides before all the APIs it requires
have been filled in (mostly stability concerns, a module may be doing whatever internally
when we request something from it). The exception being the module we are trying to resolve
for (since we need a start point for resolution). But in all likelyness we resolve for radiant
or q3map for instance.
With this approach, it is possible that some situations could not be resolved, for instance:
Radiant
requires A
provides B
module 1
requires C
provides A
module 2
requires A
provides C
if we start by resolving Radiant, we will get stuck
if we are ready to ask module to provide the API even though the required is not meant, it would work
but that kind of situation is very unlikely, so sticking to safer strategy
Configuration
-------------
the config info needs to go down to the clients too
for instance, mapxml loaded for q3map or radiant, doesn't rely on the same major?

View file

@ -1,59 +1,59 @@
XML config files for customized synapse initialization at runtime
-----------------------------------------------------------------
Objective:
----------
We have to assign the minors of the APIs to function tables
(and possibly to the API managers) at runtime from some config files.
For instance in Q3 or RTCW mode, we will want to fill in
g_FileSystemTable and g_ShadersTable with the "quake3" minor. Whereas
those tables will be filled in with a different minor for HL mode.
This affects SYN_REQUIRE for all the clients of the system, so that
config will need to be global and passed around to the clients.
Implementation:
---------------
an XML hierarchy to describe the APIs:
<client name="CORE">
<api name="vfs">
quake3
</api>
<api name="shaders">
quake3
</api>
..
</client>
<client name="SHADERS">
</client>
Each client will have to be identified by a specific name, if a name in the
config is not found in the client list, the init should fail. A client can
still be hardcoded and not appear in this list though.
(a GetName() function to synapse client)
SYN_REQUIRE_ANY support will work for strict API lists. Just the same way
we do the simple SYN_REQUIRE
Discussion:
-----------
We only deal with SYN_REQUIRE. It is possible that at some point we will want
to customize the SYN_PROVIDE too. For instance depending on the game mode, a
same module could provide two different minors. Couldn't provide the two minors
at the same time though, only one.
Implementation:
---------------
Default config file will be synapse.config in the gametools path. We can override
this later with a custom line in the .game file. Should Synapse be able to operate
without this config file though, as it is looked up by the main program and handed
over to synapse before init? Possibly .. we'll just pass a NULL config node ptr
Add the config file path to CSynpaseServer::Initialize, pass the loaded XML file to
XML config files for customized synapse initialization at runtime
-----------------------------------------------------------------
Objective:
----------
We have to assign the minors of the APIs to function tables
(and possibly to the API managers) at runtime from some config files.
For instance in Q3 or RTCW mode, we will want to fill in
g_FileSystemTable and g_ShadersTable with the "quake3" minor. Whereas
those tables will be filled in with a different minor for HL mode.
This affects SYN_REQUIRE for all the clients of the system, so that
config will need to be global and passed around to the clients.
Implementation:
---------------
an XML hierarchy to describe the APIs:
<client name="CORE">
<api name="vfs">
quake3
</api>
<api name="shaders">
quake3
</api>
..
</client>
<client name="SHADERS">
</client>
Each client will have to be identified by a specific name, if a name in the
config is not found in the client list, the init should fail. A client can
still be hardcoded and not appear in this list though.
(a GetName() function to synapse client)
SYN_REQUIRE_ANY support will work for strict API lists. Just the same way
we do the simple SYN_REQUIRE
Discussion:
-----------
We only deal with SYN_REQUIRE. It is possible that at some point we will want
to customize the SYN_PROVIDE too. For instance depending on the game mode, a
same module could provide two different minors. Couldn't provide the two minors
at the same time though, only one.
Implementation:
---------------
Default config file will be synapse.config in the gametools path. We can override
this later with a custom line in the .game file. Should Synapse be able to operate
without this config file though, as it is looked up by the main program and handed
over to synapse before init? Possibly .. we'll just pass a NULL config node ptr
Add the config file path to CSynpaseServer::Initialize, pass the loaded XML file to
the clients. Do we need to wrap in an object with some convenience functions?

View file

@ -1,85 +1,85 @@
Release / Reload of modules
---------------------------
The 'not active' modules are unloaded after startup
Plugins should be allowed to be unloaded and reloaded on the fly
Modules too, when possible?
Don't want to 'force' all plugins to have unload capabilities
Just has to be something specified at compile time wether or not they can unload 'cleanly'
Dependency implications. When you release a module, you need to remove a number of interfaces.
If those interfaces are being used, can you explicitely ask for them to be unloaded?
Also, problem with plugins breaking the startup process:
http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=441
The most important is to provide a clean shutdown method
What's the != between unload and shutdown?
Means that the server proceeds to the shutdown, and nothing else is supposed to be making
calls through APIs post shutdown.
Should be done in 3 steps:
#1 prepare shutdown, all APIs are active, just release and save all the stuff you want
#2 tell the modules to shutdown, i.e. release the APIs they point to? (at this point they can't call through anymore)
#3 force all things to be unloaded, warn about reference count problems
What is different when we unload a module, and we want to keep the editor up?
All the interfaces obtained from this plugin need to be released
If some pure virtual classes have been obtained from this plugin, we need a mecanism to have them removed
Do we need a first path to check if the unload procedure is going to be allowed?
For instance, a plugin that provides custom entities rendering etc.
Need to unload first, then need to reload (scan the map again, rebuild)
Summing up, when doing a reload we need to keep track of the modules and let them know after the
module has been reloaded, so that the links can be rebuilt. When doing unload we need to do a
'check' pass prior to anything to know if the release is possible. Because it does not depend
on the module we unload, it depends on the other clients that use it.
Objectives:
-----------
- 'release check' of a module
walk through the interfaces this module has provided, and make sure the release will be possible
- 'release' of a module
actually drop all the interfaces. this should be done only after a 'release check'
if something fails here, we are in an unstable state and need to abort
- 'client shutdown' unused modules after initial startup
actual DLL unload / complete shutdown of the client interface
this comes after 'release check' and 'release'
- 'refresh' modules
'release check', 'release', 'shutdown' and then, reload and build the links again
- 'core shutdown'
'release' and force 'shutdown' of all clients
even if we encounter some interfaces that we are not able to release cleanly
force things and shutdown all clients
then the core process is ready to exit..
Constraints:
------------
- refresh and shutdown are sharing some code
- the 'release' part of a module refresh may not be always possible (that's what 'release check' is there for)
- 'core shutdown' has to be forced to happen, in the safest way possible obviously
Implementation:
---------------
- 'client shutdown' comes first
this is used after initial startup, since we don't have to do a prior 'release' on those
this will be used in the 'core shutdown' and 'refresh' too
- then 'core shutdown' procedure?
that's the most urgent thing we need
but 'release check' and 'release' have to be written in and used during 'core shutdown'
- 'refresh' takes an essential part of the design, but that's not something we need to have written right now?
(it mostly relies on 'release check' 'release' 'client shutdown', and then reload and rebuild the links)
'client shutdown':
this is server side code though, you tell the server 'shutdown this client'
we don't have to exchange anything with the client while we do that
(written initially for unload of unused modules after startup)
'core shutdown':
is a shutdown of all clients
Release / Reload of modules
---------------------------
The 'not active' modules are unloaded after startup
Plugins should be allowed to be unloaded and reloaded on the fly
Modules too, when possible?
Don't want to 'force' all plugins to have unload capabilities
Just has to be something specified at compile time wether or not they can unload 'cleanly'
Dependency implications. When you release a module, you need to remove a number of interfaces.
If those interfaces are being used, can you explicitely ask for them to be unloaded?
Also, problem with plugins breaking the startup process:
http://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=441
The most important is to provide a clean shutdown method
What's the != between unload and shutdown?
Means that the server proceeds to the shutdown, and nothing else is supposed to be making
calls through APIs post shutdown.
Should be done in 3 steps:
#1 prepare shutdown, all APIs are active, just release and save all the stuff you want
#2 tell the modules to shutdown, i.e. release the APIs they point to? (at this point they can't call through anymore)
#3 force all things to be unloaded, warn about reference count problems
What is different when we unload a module, and we want to keep the editor up?
All the interfaces obtained from this plugin need to be released
If some pure virtual classes have been obtained from this plugin, we need a mecanism to have them removed
Do we need a first path to check if the unload procedure is going to be allowed?
For instance, a plugin that provides custom entities rendering etc.
Need to unload first, then need to reload (scan the map again, rebuild)
Summing up, when doing a reload we need to keep track of the modules and let them know after the
module has been reloaded, so that the links can be rebuilt. When doing unload we need to do a
'check' pass prior to anything to know if the release is possible. Because it does not depend
on the module we unload, it depends on the other clients that use it.
Objectives:
-----------
- 'release check' of a module
walk through the interfaces this module has provided, and make sure the release will be possible
- 'release' of a module
actually drop all the interfaces. this should be done only after a 'release check'
if something fails here, we are in an unstable state and need to abort
- 'client shutdown' unused modules after initial startup
actual DLL unload / complete shutdown of the client interface
this comes after 'release check' and 'release'
- 'refresh' modules
'release check', 'release', 'shutdown' and then, reload and build the links again
- 'core shutdown'
'release' and force 'shutdown' of all clients
even if we encounter some interfaces that we are not able to release cleanly
force things and shutdown all clients
then the core process is ready to exit..
Constraints:
------------
- refresh and shutdown are sharing some code
- the 'release' part of a module refresh may not be always possible (that's what 'release check' is there for)
- 'core shutdown' has to be forced to happen, in the safest way possible obviously
Implementation:
---------------
- 'client shutdown' comes first
this is used after initial startup, since we don't have to do a prior 'release' on those
this will be used in the 'core shutdown' and 'refresh' too
- then 'core shutdown' procedure?
that's the most urgent thing we need
but 'release check' and 'release' have to be written in and used during 'core shutdown'
- 'refresh' takes an essential part of the design, but that's not something we need to have written right now?
(it mostly relies on 'release check' 'release' 'client shutdown', and then reload and rebuild the links)
'client shutdown':
this is server side code though, you tell the server 'shutdown this client'
we don't have to exchange anything with the client while we do that
(written initially for unload of unused modules after startup)
'core shutdown':
is a shutdown of all clients

View file

@ -1,72 +1,72 @@
# version and about message management
# NOTE: this module is meant to be used on all platforms, it is not SCons centric
# version:
# input:
# include/version.default
# output:
# include/version.h include/RADIANT_MAJOR include/RADIANT_MINOR
# the header is used by C/C++ code, the straight text file by setup
# about message
# for non-official builds, we have a default message
# otherwise, use environment variable $RADIANT_ABOUTMSG
# input:
# include/aboutmsg.default
# or file pointed to by $RADIANT_ABOUTMSG if exists
# ouput:
# include/aboutmsg.h
import sys, re, string, os
def get_version():
# version
f = open('include/version.default', 'r')
buffer = f.read()
line = string.split(buffer, '\n')[0]
f.close()
sys.stdout.write("version: %s\n" % line)
exp = re.compile('^1\\.([^\\.]*)\\.([0-9]*)')
(major, minor) = exp.findall(line)[0]
sys.stdout.write("minor: %s major: %s\n" % (minor, major))
return (line, major, minor)
# you can pass an optional message to append to aboutmsg
def radiant_makeversion(append_about):
(line, major, minor) = get_version()
f = open('include/version.h', 'w')
f.write('// generated header, see makeversion.py\n')
f.write('#define RADIANT_VERSION "%s"\n' % line)
f.write('#define RADIANT_MINOR_VERSION "%s"\n' % minor)
f.write('#define RADIANT_MAJOR_VERSION "%s"\n' % major)
f.close()
f = open('include/RADIANT_MINOR', 'w')
f.write(minor)
f.close()
f = open('include/RADIANT_MAJOR', 'w')
f.write(major)
f.close()
f = open('include/version', 'w')
f.write(line)
f.close()
# aboutmsg
aboutfile = 'include/aboutmsg.default'
if ( os.environ.has_key('RADIANT_ABOUTMSG') ):
aboutfile = os.environ['RADIANT_ABOUTMSG']
sys.stdout.write("about message is in %s\n" % aboutfile)
f = open(aboutfile, 'r')
buffer = f.read()
line = string.split(buffer, '\n')[0]
f.close()
# optional additional message
if ( not append_about is None ):
line += append_about
sys.stdout.write("about: %s\n" % line)
f = open('include/aboutmsg.h', 'w')
f.write('// generated header, see makeversion.py\n')
f.write('#define RADIANT_ABOUTMSG "%s"\n' % line)
f.close()
# can be used as module (scons build), or by direct call
if __name__ == '__main__':
radiant_makeversion(None)
# version and about message management
# NOTE: this module is meant to be used on all platforms, it is not SCons centric
# version:
# input:
# include/version.default
# output:
# include/version.h include/RADIANT_MAJOR include/RADIANT_MINOR
# the header is used by C/C++ code, the straight text file by setup
# about message
# for non-official builds, we have a default message
# otherwise, use environment variable $RADIANT_ABOUTMSG
# input:
# include/aboutmsg.default
# or file pointed to by $RADIANT_ABOUTMSG if exists
# ouput:
# include/aboutmsg.h
import sys, re, string, os
def get_version():
# version
f = open('include/version.default', 'r')
buffer = f.read()
line = string.split(buffer, '\n')[0]
f.close()
sys.stdout.write("version: %s\n" % line)
exp = re.compile('^1\\.([^\\.]*)\\.([0-9]*)')
(major, minor) = exp.findall(line)[0]
sys.stdout.write("minor: %s major: %s\n" % (minor, major))
return (line, major, minor)
# you can pass an optional message to append to aboutmsg
def radiant_makeversion(append_about):
(line, major, minor) = get_version()
f = open('include/version.h', 'w')
f.write('// generated header, see makeversion.py\n')
f.write('#define RADIANT_VERSION "%s"\n' % line)
f.write('#define RADIANT_MINOR_VERSION "%s"\n' % minor)
f.write('#define RADIANT_MAJOR_VERSION "%s"\n' % major)
f.close()
f = open('include/RADIANT_MINOR', 'w')
f.write(minor)
f.close()
f = open('include/RADIANT_MAJOR', 'w')
f.write(major)
f.close()
f = open('include/version', 'w')
f.write(line)
f.close()
# aboutmsg
aboutfile = 'include/aboutmsg.default'
if ( os.environ.has_key('RADIANT_ABOUTMSG') ):
aboutfile = os.environ['RADIANT_ABOUTMSG']
sys.stdout.write("about message is in %s\n" % aboutfile)
f = open(aboutfile, 'r')
buffer = f.read()
line = string.split(buffer, '\n')[0]
f.close()
# optional additional message
if ( not append_about is None ):
line += append_about
sys.stdout.write("about: %s\n" % line)
f = open('include/aboutmsg.h', 'w')
f.write('// generated header, see makeversion.py\n')
f.write('#define RADIANT_ABOUTMSG "%s"\n' % line)
f.close()
# can be used as module (scons build), or by direct call
if __name__ == '__main__':
radiant_makeversion(None)

View file

@ -1,8 +1,8 @@
; fgd.def : Declares the module parameters for the DLL.
LIBRARY "FGD"
DESCRIPTION 'FGD Windows Dynamic Link Library'
EXPORTS
; Explicit exports can go here
Synapse_EnumerateInterfaces @1
; fgd.def : Declares the module parameters for the DLL.
LIBRARY "FGD"
DESCRIPTION 'FGD Windows Dynamic Link Library'
EXPORTS
; Explicit exports can go here
Synapse_EnumerateInterfaces @1

View file

@ -1,8 +1,8 @@
; entity.def : Declares the module parameters for the DLL.
LIBRARY "ENTITY"
DESCRIPTION 'ENTITY Windows Dynamic Link Library'
EXPORTS
; Explicit exports can go here
Synapse_EnumerateInterfaces @1
; entity.def : Declares the module parameters for the DLL.
LIBRARY "ENTITY"
DESCRIPTION 'ENTITY Windows Dynamic Link Library'
EXPORTS
; Explicit exports can go here
Synapse_EnumerateInterfaces @1

View file

@ -1,8 +1,8 @@
; image.def : Declares the module parameters for the DLL.
LIBRARY "Image"
DESCRIPTION 'Image Windows Dynamic Link Library'
EXPORTS
; Explicit exports can go here
Synapse_EnumerateInterfaces @1
; image.def : Declares the module parameters for the DLL.
LIBRARY "Image"
DESCRIPTION 'Image Windows Dynamic Link Library'
EXPORTS
; Explicit exports can go here
Synapse_EnumerateInterfaces @1

View file

@ -1,8 +1,8 @@
; hlimage.def : Declares the module parameters for the DLL.
LIBRARY "ImageHL"
DESCRIPTION 'ImageHL Windows Dynamic Link Library'
EXPORTS
; Explicit exports can go here
Synapse_EnumerateInterfaces @1
; hlimage.def : Declares the module parameters for the DLL.
LIBRARY "ImageHL"
DESCRIPTION 'ImageHL Windows Dynamic Link Library'
EXPORTS
; Explicit exports can go here
Synapse_EnumerateInterfaces @1

View file

@ -1,30 +1,30 @@
ImageHL
=======
Coding by Dominic Clifton - Hydra - hydra@hydras-world.com
What is it ?
------------
This GTKRadiant 1.2+ plugin handles the loading of textures from .WAD files.
I'll refer to these textures as .HLW files, even though they don't have any
extension when they're stored in the .WAD file itself.
You need a VFS plugin to go with this plugin that can open and read .WAD files
My VFSWAD plugin does just this.
Developer Notes
---------------
The project file will copy the compiled DLL file and this .TXT file to
"$(HLRADIANTDIR)modules" so make sure you have that environment variable
defined.
For my GTKRadiant 1.2 HalfLife game pack files I use the directory:
"E:\games\HalfLife\Tools\GTKR12N". Under which there are the directories
"modules" and "plugins"
Credits
-------
Thanks to the guys that made Wally for releasing an example WAD loader.
without it this would not have been possible.
ImageHL
=======
Coding by Dominic Clifton - Hydra - hydra@hydras-world.com
What is it ?
------------
This GTKRadiant 1.2+ plugin handles the loading of textures from .WAD files.
I'll refer to these textures as .HLW files, even though they don't have any
extension when they're stored in the .WAD file itself.
You need a VFS plugin to go with this plugin that can open and read .WAD files
My VFSWAD plugin does just this.
Developer Notes
---------------
The project file will copy the compiled DLL file and this .TXT file to
"$(HLRADIANTDIR)modules" so make sure you have that environment variable
defined.
For my GTKRadiant 1.2 HalfLife game pack files I use the directory:
"E:\games\HalfLife\Tools\GTKR12N". Under which there are the directories
"modules" and "plugins"
Credits
-------
Thanks to the guys that made Wally for releasing an example WAD loader.
without it this would not have been possible.

View file

@ -1,8 +1,8 @@
; imagem8.def : Declares the module parameters for the DLL.
LIBRARY "ImageM8"
DESCRIPTION 'ImageM8 Windows Dynamic Link Library'
EXPORTS
; Explicit exports can go here
Synapse_EnumerateInterfaces @1
; imagem8.def : Declares the module parameters for the DLL.
LIBRARY "ImageM8"
DESCRIPTION 'ImageM8 Windows Dynamic Link Library'
EXPORTS
; Explicit exports can go here
Synapse_EnumerateInterfaces @1

View file

@ -1,8 +1,8 @@
; imagepng.def : Declares the module parameters for the DLL.
LIBRARY "IMAGEPNG"
DESCRIPTION 'IMAGEPNG Windows Dynamic Link Library'
EXPORTS
; Explicit exports can go here
Synapse_EnumerateInterfaces @1
; imagepng.def : Declares the module parameters for the DLL.
LIBRARY "IMAGEPNG"
DESCRIPTION 'IMAGEPNG Windows Dynamic Link Library'
EXPORTS
; Explicit exports can go here
Synapse_EnumerateInterfaces @1

View file

@ -1,8 +1,8 @@
; mapq3.def : Declares the module parameters for the DLL.
LIBRARY "MAPQ3"
DESCRIPTION 'MAPQ3 Windows Dynamic Link Library'
EXPORTS
; Explicit exports can go here
Synapse_EnumerateInterfaces @1
; mapq3.def : Declares the module parameters for the DLL.
LIBRARY "MAPQ3"
DESCRIPTION 'MAPQ3 Windows Dynamic Link Library'
EXPORTS
; Explicit exports can go here
Synapse_EnumerateInterfaces @1

View file

@ -1,8 +1,8 @@
; mapxml.def : Declares the module parameters for the DLL.
LIBRARY "MAPXML"
DESCRIPTION 'MAPXML Windows Dynamic Link Library'
EXPORTS
; Explicit exports can go here
Synapse_EnumerateInterfaces @1
; mapxml.def : Declares the module parameters for the DLL.
LIBRARY "MAPXML"
DESCRIPTION 'MAPXML Windows Dynamic Link Library'
EXPORTS
; Explicit exports can go here
Synapse_EnumerateInterfaces @1

View file

@ -1,8 +1,8 @@
; model.def : Declares the module parameters for the DLL.
LIBRARY "MODEL"
DESCRIPTION 'MODEL Windows Dynamic Link Library'
EXPORTS
; Explicit exports can go here
; model.def : Declares the module parameters for the DLL.
LIBRARY "MODEL"
DESCRIPTION 'MODEL Windows Dynamic Link Library'
EXPORTS
; Explicit exports can go here
Synapse_EnumerateInterfaces @1

View file

@ -1,8 +1,8 @@
; shaders.def : Declares the module parameters for the DLL.
LIBRARY "Shaders"
DESCRIPTION 'Shaders Windows Dynamic Link Library'
EXPORTS
; Explicit exports can go here
Synapse_EnumerateInterfaces @1
; shaders.def : Declares the module parameters for the DLL.
LIBRARY "Shaders"
DESCRIPTION 'Shaders Windows Dynamic Link Library'
EXPORTS
; Explicit exports can go here
Synapse_EnumerateInterfaces @1

View file

@ -1,8 +1,8 @@
; shaders.def : Declares the module parameters for the DLL.
LIBRARY "ShadersHL"
DESCRIPTION 'ShadersHL Windows Dynamic Link Library'
EXPORTS
; Explicit exports can go here
Synapse_EnumerateInterfaces @1
; shaders.def : Declares the module parameters for the DLL.
LIBRARY "ShadersHL"
DESCRIPTION 'ShadersHL Windows Dynamic Link Library'
EXPORTS
; Explicit exports can go here
Synapse_EnumerateInterfaces @1

View file

@ -1,8 +1,8 @@
; md3model.def : Declares the module parameters for the DLL.
LIBRARY "SPRITEMODEL"
DESCRIPTION 'SPRITEMODEL Windows Dynamic Link Library'
EXPORTS
; Explicit exports can go here
Synapse_EnumerateInterfaces @1
; md3model.def : Declares the module parameters for the DLL.
LIBRARY "SPRITEMODEL"
DESCRIPTION 'SPRITEMODEL Windows Dynamic Link Library'
EXPORTS
; Explicit exports can go here
Synapse_EnumerateInterfaces @1

View file

@ -1,8 +1,8 @@
; surface_heretic2.def : Declares the module parameters for the DLL.
LIBRARY "Surface_Heretic2"
DESCRIPTION 'Surface_Heretic2 Windows Dynamic Link Library'
EXPORTS
; Explicit exports can go here
Synapse_EnumerateInterfaces @1
; surface_heretic2.def : Declares the module parameters for the DLL.
LIBRARY "Surface_Heretic2"
DESCRIPTION 'Surface_Heretic2 Windows Dynamic Link Library'
EXPORTS
; Explicit exports can go here
Synapse_EnumerateInterfaces @1

View file

@ -1,12 +1,12 @@
; TexTool.def : Declares the module parameters for the DLL.
LIBRARY "TexTool"
DESCRIPTION 'TexTool Windows Dynamic Link Library'
EXPORTS
; Explicit exports can go here
QERPlug_Init @1
QERPlug_GetName @2
QERPlug_GetCommandList @3
QERPlug_Dispatch @4
QERPlug_GetFuncTable @5
; TexTool.def : Declares the module parameters for the DLL.
LIBRARY "TexTool"
DESCRIPTION 'TexTool Windows Dynamic Link Library'
EXPORTS
; Explicit exports can go here
QERPlug_Init @1
QERPlug_GetName @2
QERPlug_GetCommandList @3
QERPlug_Dispatch @4
QERPlug_GetFuncTable @5

View file

@ -1,8 +1,8 @@
11/19/99
first usable version
here is the TODO-list for next release, ( most certainly a wish list )
- TODO: add hooks with the selected face and selected patch data. tell the plugin when selected face
or selected patch has changed.
the hooks should use a generic interface inside Radiant for "observers"
11/19/99
first usable version
here is the TODO-list for next release, ( most certainly a wish list )
- TODO: add hooks with the selected face and selected patch data. tell the plugin when selected face
or selected patch has changed.
the hooks should use a generic interface inside Radiant for "observers"
- TODO: add other usefull texturing tools, if designers come up with good ideas

View file

@ -1,8 +1,8 @@
; vfspk3.def : Declares the module parameters for the DLL.
LIBRARY "VFSPK3"
DESCRIPTION 'VFSPK3 Windows Dynamic Link Library'
EXPORTS
; Explicit exports can go here
Synapse_EnumerateInterfaces @1
; vfspk3.def : Declares the module parameters for the DLL.
LIBRARY "VFSPK3"
DESCRIPTION 'VFSPK3 Windows Dynamic Link Library'
EXPORTS
; Explicit exports can go here
Synapse_EnumerateInterfaces @1

View file

@ -1,8 +1,8 @@
; vfswad.def : Declares the module parameters for the DLL.
LIBRARY "vfswad"
DESCRIPTION 'vfswad Windows Dynamic Link Library'
EXPORTS
; Explicit exports can go here
Synapse_EnumerateInterfaces @1
; vfswad.def : Declares the module parameters for the DLL.
LIBRARY "vfswad"
DESCRIPTION 'vfswad Windows Dynamic Link Library'
EXPORTS
; Explicit exports can go here
Synapse_EnumerateInterfaces @1

View file

@ -1,30 +1,30 @@
VFSWAD
======
Coding by Dominic Clifton - Hydra - hydra@hydras-world.com
What is it ?
------------
This GTKRadiant 1.2+ plugin handles the extracting of files from .WAD files.
I'll refer to these files as .HLW files, even though they don't have any
extension when they're stored in the .WAD file itself.
You need an image plugin to go with this plugin that can read .HLW files
My ImageHL plugin does just this.
Developer Notes
---------------
The project file will copy the compiled DLL file and this .TXT file to
"$(HLRADIANTDIR)\modules" so make sure you have that environment variable
defined.
For my GTKRadiant 1.2 HalfLife game pack files I use the directory:
"E:\games\HalfLife\Tools\GTKR12N\". Under which there are the directories
"modules" and "plugins"
Credits
-------
Thanks to the guys that made Wally for releasing an example WAD loader.
without it this would not have been possible.
VFSWAD
======
Coding by Dominic Clifton - Hydra - hydra@hydras-world.com
What is it ?
------------
This GTKRadiant 1.2+ plugin handles the extracting of files from .WAD files.
I'll refer to these files as .HLW files, even though they don't have any
extension when they're stored in the .WAD file itself.
You need an image plugin to go with this plugin that can read .HLW files
My ImageHL plugin does just this.
Developer Notes
---------------
The project file will copy the compiled DLL file and this .TXT file to
"$(HLRADIANTDIR)\modules" so make sure you have that environment variable
defined.
For my GTKRadiant 1.2 HalfLife game pack files I use the directory:
"E:\games\HalfLife\Tools\GTKR12N\". Under which there are the directories
"modules" and "plugins"
Credits
-------
Thanks to the guys that made Wally for releasing an example WAD loader.
without it this would not have been possible.

File diff suppressed because it is too large Load diff

View file

@ -1,46 +1,46 @@
#!/usr/bin/perl -w
use IO::Socket;
use Net::hostent;
my $port = shift || 13131;
my $server = IO::Socket::INET->new(
Proto => 'tcp',
LocalPort => $port,
Listen => SOMAXCONN,
Reuse => 1 )
|| die "can't setup server";
print "[Q3Map2 listener $0 is now active on port $port]\n";
while( $client = $server->accept() )
{
$client->autoflush( 1 );
$hostinfo = gethostbyaddr( $client->peeraddr );
printf "[Connect from %s]\n\n", $hostinfo ? $hostinfo->name : $client->peerhost;
#ask the client for a command
print $client "[server]\$";
my $text = "";
while( <$client> )
{
$text .= $_;
while( $text =~ s|<message[^>]*>([^<]+)</message>|| )
{
my $msg = $1;
# fix xml ents
$msg =~ s|&lt;|<|g;
$msg =~ s|&gt;|>|g;
$msg =~ s|&quot;|"|g;#"
$msg =~ s|&apos;|'|g;#'
print $msg;
}
}
printf "\n[Disconnected: %s]\n\n", $hostinfo ? $hostinfo->name : $client->peerhost;
close $client;
}
#!/usr/bin/perl -w
use IO::Socket;
use Net::hostent;
my $port = shift || 13131;
my $server = IO::Socket::INET->new(
Proto => 'tcp',
LocalPort => $port,
Listen => SOMAXCONN,
Reuse => 1 )
|| die "can't setup server";
print "[Q3Map2 listener $0 is now active on port $port]\n";
while( $client = $server->accept() )
{
$client->autoflush( 1 );
$hostinfo = gethostbyaddr( $client->peeraddr );
printf "[Connect from %s]\n\n", $hostinfo ? $hostinfo->name : $client->peerhost;
#ask the client for a command
print $client "[server]\$";
my $text = "";
while( <$client> )
{
$text .= $_;
while( $text =~ s|<message[^>]*>([^<]+)</message>|| )
{
my $msg = $1;
# fix xml ents
$msg =~ s|&lt;|<|g;
$msg =~ s|&gt;|>|g;
$msg =~ s|&quot;|"|g;#"
$msg =~ s|&apos;|'|g;#'
print $msg;
}
}
printf "\n[Disconnected: %s]\n\n", $hostinfo ? $hostinfo->name : $client->peerhost;
close $client;
}

260
utils.py
View file

@ -1,130 +1,130 @@
# -*- mode: python -*-
# QuakeZero build scripts
# TTimo <ttimo@idsoftware.com>
# http://scons.sourceforge.net
import os, commands, platform, xml.sax, re, string, platform
class vcproj( xml.sax.handler.ContentHandler ):
def __init__( self, filepath ):
self.source_files = []
self.misc_files = []
self._files = []
print 'parse %s' % filepath
xml.sax.parse( filepath, self )
def getSourceFiles( self ):
return self.source_files
def filterSource( self, expression, filelist = None ):
if ( filelist is None ):
filelist = self.source_files
match = []
nomatch = []
for s in filelist:
if ( re.match( expression, s ) ):
match.append( s )
else:
nomatch.append( s )
return ( match, nomatch )
def startElement( self, name, attrs ):
if ( name == 'File' ):
self._files.append( attrs.getValue('RelativePath') )
def endDocument( self ):
# split into source and headers, remap path seperator to the platform
for f in self._files:
if ( platform.system() != 'Windows' ):
f = f.replace( '\\', '/' )
if ( f[-2:] == '.c' or f[-4:] == '.cpp' ):
self.source_files.append( f.encode('ascii') )
else:
self.misc_files.append( f )
print '%d source files' % len( self.source_files )
# action uses LDD to verify that the source doesn't hold unresolved symbols
# setup as an AddPostAction of a regular SharedLibrary call
def CheckUnresolved( source, target, env ):
# TODO: implement this for OSX
if ( platform.system() == 'Darwin' ):
return None
print 'CheckUnresolved %s' % target[0].abspath
if ( not os.path.isfile( target[0].abspath ) ):
print 'CheckUnresolved: %s does not exist' % target[0]
return 1 # fail
( status, output ) = commands.getstatusoutput( 'ldd -r %s' % target[0] )
if ( status != 0 ):
print 'CheckUnresolved: ldd command failed (exit code %d)' % status
os.system( 'rm %s' % target[ 0 ] )
return 1 # fail
lines = string.split( output, '\n' )
have_undef = 0
for i_line in lines:
regex = re.compile('undefined symbol: (.*)\t\\((.*)\\)')
if ( regex.match( i_line ) ):
symbol = regex.sub( '\\1', i_line )
try:
env['ALLOWED_SYMBOLS'].index( symbol )
except:
have_undef = 1
if ( have_undef ):
print output
print "CheckUnresolved: undefined symbols"
os.system('rm %s' % target[0])
return 1
# http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/413486
def Enum(*names):
##assert names, "Empty enums are not supported" # <- Don't like empty enums? Uncomment!
class EnumClass(object):
__slots__ = names
def __iter__(self): return iter(constants)
def __len__(self): return len(constants)
def __getitem__(self, i): return constants[i]
def __repr__(self): return 'Enum' + str(names)
def __str__(self): return 'enum ' + str(constants)
class EnumValue(object):
__slots__ = ('__value')
def __init__(self, value): self.__value = value
Value = property(lambda self: self.__value)
EnumType = property(lambda self: EnumType)
def __hash__(self): return hash(self.__value)
def __cmp__(self, other):
# C fans might want to remove the following assertion
# to make all enums comparable by ordinal value {;))
assert self.EnumType is other.EnumType, "Only values from the same enum are comparable"
return cmp(self.__value, other.__value)
def __invert__(self): return constants[maximum - self.__value]
def __nonzero__(self): return bool(self.__value)
def __repr__(self): return str(names[self.__value])
maximum = len(names) - 1
constants = [None] * len(names)
for i, each in enumerate(names):
val = EnumValue(i)
setattr(EnumClass, each, val)
constants[i] = val
constants = tuple(constants)
EnumType = EnumClass()
return EnumType
#if __name__ == '__main__':
# print '\n*** Enum Demo ***'
# print '--- Days of week ---'
# Days = Enum('Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su')
# print Days
# print Days.Mo
# print Days.Fr
# print Days.Mo < Days.Fr
# print list(Days)
# for each in Days:
# print 'Day:', each
# print '--- Yes/No ---'
# Confirmation = Enum('No', 'Yes')
# answer = Confirmation.No
# print 'Your answer is not', ~answer
# -*- mode: python -*-
# QuakeZero build scripts
# TTimo <ttimo@idsoftware.com>
# http://scons.sourceforge.net
import os, commands, platform, xml.sax, re, string, platform
class vcproj( xml.sax.handler.ContentHandler ):
def __init__( self, filepath ):
self.source_files = []
self.misc_files = []
self._files = []
print 'parse %s' % filepath
xml.sax.parse( filepath, self )
def getSourceFiles( self ):
return self.source_files
def filterSource( self, expression, filelist = None ):
if ( filelist is None ):
filelist = self.source_files
match = []
nomatch = []
for s in filelist:
if ( re.match( expression, s ) ):
match.append( s )
else:
nomatch.append( s )
return ( match, nomatch )
def startElement( self, name, attrs ):
if ( name == 'File' ):
self._files.append( attrs.getValue('RelativePath') )
def endDocument( self ):
# split into source and headers, remap path seperator to the platform
for f in self._files:
if ( platform.system() != 'Windows' ):
f = f.replace( '\\', '/' )
if ( f[-2:] == '.c' or f[-4:] == '.cpp' ):
self.source_files.append( f.encode('ascii') )
else:
self.misc_files.append( f )
print '%d source files' % len( self.source_files )
# action uses LDD to verify that the source doesn't hold unresolved symbols
# setup as an AddPostAction of a regular SharedLibrary call
def CheckUnresolved( source, target, env ):
# TODO: implement this for OSX
if ( platform.system() == 'Darwin' ):
return None
print 'CheckUnresolved %s' % target[0].abspath
if ( not os.path.isfile( target[0].abspath ) ):
print 'CheckUnresolved: %s does not exist' % target[0]
return 1 # fail
( status, output ) = commands.getstatusoutput( 'ldd -r %s' % target[0] )
if ( status != 0 ):
print 'CheckUnresolved: ldd command failed (exit code %d)' % status
os.system( 'rm %s' % target[ 0 ] )
return 1 # fail
lines = string.split( output, '\n' )
have_undef = 0
for i_line in lines:
regex = re.compile('undefined symbol: (.*)\t\\((.*)\\)')
if ( regex.match( i_line ) ):
symbol = regex.sub( '\\1', i_line )
try:
env['ALLOWED_SYMBOLS'].index( symbol )
except:
have_undef = 1
if ( have_undef ):
print output
print "CheckUnresolved: undefined symbols"
os.system('rm %s' % target[0])
return 1
# http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/413486
def Enum(*names):
##assert names, "Empty enums are not supported" # <- Don't like empty enums? Uncomment!
class EnumClass(object):
__slots__ = names
def __iter__(self): return iter(constants)
def __len__(self): return len(constants)
def __getitem__(self, i): return constants[i]
def __repr__(self): return 'Enum' + str(names)
def __str__(self): return 'enum ' + str(constants)
class EnumValue(object):
__slots__ = ('__value')
def __init__(self, value): self.__value = value
Value = property(lambda self: self.__value)
EnumType = property(lambda self: EnumType)
def __hash__(self): return hash(self.__value)
def __cmp__(self, other):
# C fans might want to remove the following assertion
# to make all enums comparable by ordinal value {;))
assert self.EnumType is other.EnumType, "Only values from the same enum are comparable"
return cmp(self.__value, other.__value)
def __invert__(self): return constants[maximum - self.__value]
def __nonzero__(self): return bool(self.__value)
def __repr__(self): return str(names[self.__value])
maximum = len(names) - 1
constants = [None] * len(names)
for i, each in enumerate(names):
val = EnumValue(i)
setattr(EnumClass, each, val)
constants[i] = val
constants = tuple(constants)
EnumType = EnumClass()
return EnumType
#if __name__ == '__main__':
# print '\n*** Enum Demo ***'
# print '--- Days of week ---'
# Days = Enum('Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su')
# print Days
# print Days.Mo
# print Days.Fr
# print Days.Mo < Days.Fr
# print list(Days)
# for each in Days:
# print 'Day:', each
# print '--- Yes/No ---'
# Confirmation = Enum('No', 'Yes')
# answer = Confirmation.No
# print 'Your answer is not', ~answer

View file

@ -1,166 +1,166 @@
# install the fucking files
# check the md5 to decide for a copy
# we have a site.conf to go through
# and a data list of stuff
# it's called at the end of each build to copy what needs to be
# it could be called only at GtkRadiant link time
# command line: a bunch of config switches default would be debug?, and release flag
import sys, traceback, os, re, filecmp, shutil, pickle, string
from makeversion import get_version
(line, major, minor) = get_version()
paths = {
'CORERADIANTDIR' : 'C:\\Program Files\\GtkRadiant-1.' + major,
'RTCWRADIANTDIR' : 'C:\\Program Files\\Return to Castle Wolfenstein - Game of The Year Edition\\Radiant-1.' + major,
'HLRADIANTDIR' : 'C:\\Sierra\\Half-Life\\Radiant-1.' + major,
'SOF2RADIANTDIR' : 'C:\\Program Files\\Soldier of Fortune II - Double Helix\\Radiant-1.' + major,
'QUAKE2RADIANTDIR' : 'C:\\Quake2\\Radiant-1.' + major,
'HERETIC2RADIANTDIR' : 'C:\\Heretic2\\Radiant-1.' + major
}
conf_filename='site.conf.win32'
# site settings ----------------------
if (os.path.exists(conf_filename)):
site_file = open(conf_filename, 'r')
p = pickle.Unpickler(site_file)
paths = p.load()
print 'Loaded configuration from ' + conf_filename
# end site settings ------------------
# command line overrides -------------
print '\nCommand line:'
regex = re.compile("(.*)=(.*)")
for i in sys.argv[1:]:
#print i
if ( regex.match(i) ):
(key, val) = string.split(i, '=')
#print 'key: %s val: %s' % (key, val)
paths[key] = val
else:
print 'Can''t parse command line - ignore: ' + i
# end command line overrides ---------
# save config ------------------------
site_file = open(conf_filename, 'w')
p = pickle.Pickler(site_file)
p.dump(paths)
site_file.close()
print '\nConfiguration:'
for i in paths.keys():
print '%s -> %s' % (i, paths[i])
# end save config --------------------
q3map2_list = [
# ( ( '..\\libpng\\projects\\msvc\\win32\\zlib\\dll_dbg\\zlibd.dll', '..\\libpng\\projects\\msvc\\win32\\zlib\\dll\\zlib.dll' ), '$CORERADIANTDIR' ),
# ( ( '..\\libpng\\projects\\msvc\\win32\\libpng\\dll_dbg\\libpng13d.dll', '..\\libpng\\projects\\msvc\\win32\\libpng\\dll\\libpng13.dll' ), '$CORERADIANTDIR' ),
# ( ( '..\\libxml2\\win32\\binaries-debug\\libxml2.dll', '..\\libxml2\\win32\\binaries-release\\libxml2.dll' ), '$CORERADIANTDIR' ),
( ( 'tools\\quake3\\q3map2\\Debug\\Q3Map2.exe', 'tools\\quake3\\q3map2\\Release\\Q3Map2.exe' ), '$CORERADIANTDIR' ),
]
all = [
( ( 'radiant\\Debug\\GtkRadiant.exe', 'radiant\\Release\\GtkRadiant.exe' ) , '$CORERADIANTDIR' ),
( ( 'contrib\\bobtoolz\\Debug\\bobToolz.dll', 'contrib\\bobtoolz\\Release\\bobToolz.dll' ), '$CORERADIANTDIR\\plugins' ),
( ( 'contrib\\camera\\Debug\\camera.dll', 'contrib\\camera\\Release\\camera.dll' ), '$CORERADIANTDIR\\plugins' ),
( ( 'plugins\\entity\\Debug\\entity.dll', 'plugins\\entity\\Release\\entity.dll' ), '$CORERADIANTDIR\\modules' ),
( ( 'plugins\\eclassfgd\\Debug\\fgd.dll', 'plugins\\eclassfgd\\Release\\fgd.dll' ), '$CORERADIANTDIR\\modules' ),
( ( 'contrib\\gtkgensurf\\Debug\\gensurf.dll', 'contrib\\gtkgensurf\\Release\\gensurf.dll' ), '$CORERADIANTDIR\\plugins' ),
( ( 'contrib\\hydratoolz\\Debug\\hydratoolz.dll', 'contrib\\hydratoolz\\Release\\hydratoolz.dll' ), '$HLRADIANTDIR\\plugins' ),
( ( 'plugins\\image\\Debug\\image.dll', 'plugins\\image\\Release\\image.dll' ), '$CORERADIANTDIR\\modules' ),
( ( 'plugins\\imagewal\\Debug\\imagewal.dll', 'plugins\\imagewal\\Release\\imagewal.dll' ), '$QUAKE2RADIANTDIR\\modules' ),
( ( 'plugins\\imagehl\\Debug\\imagehl.dll', 'plugins\\imagehl\\Release\\imagehl.dll' ), '$CORERADIANTDIR\\modules' ),
( ( 'plugins\\imagepng\\Debug\\imagepng.dll', 'plugins\\imagepng\\Release\\imagepng.dll' ), '$CORERADIANTDIR\\modules' ),
( ( 'plugins\\map\\Debug\\map.dll', 'plugins\\map\\Release\\map.dll' ), '$CORERADIANTDIR\\modules' ),
( ( 'plugins\\mapxml\\Debug\\mapxml.dll', 'plugins\\mapxml\\Release\\mapxml.dll' ), '$CORERADIANTDIR\\modules' ),
( ( 'plugins\\model\\Debug\\model.dll', 'plugins\\model\\Release\\model.dll' ), '$CORERADIANTDIR\\modules' ),
( ( 'contrib\\prtview\\Debug\\PrtView.dll', 'contrib\\prtview\\Release\\PrtView.dll' ), '$CORERADIANTDIR\\plugins' ),
( ( 'tools\\quake3\\q3data\\Debug\\q3data.exe', 'tools\\quake3\\q3data\\Release\\q3data.exe' ), '$CORERADIANTDIR' ),
( ( 'plugins\\shaders\\Debug\\shaders.dll', 'plugins\\shaders\\Release\\shaders.dll' ), '$CORERADIANTDIR\\modules' ),
( ( 'plugins\\spritemodel\\Debug\\spritemodel.dll', 'plugins\\spritemodel\\Release\\spritemodel.dll' ), '$CORERADIANTDIR\\modules' ),
# ( ( 'Debug\\TexTool.dll', 'Release\\TexTool.dll' ), '$CORERADIANTDIR\\plugins' ),
( ( 'plugins\\vfspk3\\Debug\\vfspk3.dll', 'plugins\\vfspk3\\Release\\vfspk3.dll' ), '$CORERADIANTDIR\\modules' ),
( ( 'plugins\\vfspak\\Debug\\vfspak.dll', 'plugins\\vfspak\\Release\\vfspak.dll' ), '$QUAKE2RADIANTDIR\\modules' ),
( ( 'plugins\\vfswad\\Debug\\vfswad.dll', 'plugins\\vfswad\\Release\\vfswad.dll' ), '$CORERADIANTDIR\\modules' ),
( ( 'plugins\\surface\\Debug\\surface.dll', 'plugins\\surface\\Release\\surface.dll' ), '$CORERADIANTDIR\\modules' ),
( ( 'plugins\\surface_quake2\\Debug\\surface_quake2.dll', 'plugins\\surface_quake2\\Release\\surface_quake2.dll' ), '$QUAKE2RADIANTDIR\\modules' ),
( ( 'tools\\quake2\\q2map\\Debug\\q2map.exe', 'tools\\quake2\\q2map\\Release\\q2map.exe' ) , '$QUAKE2RADIANTDIR' ),
( ( 'tools\\quake2\\qdata\\Debug\\qdata3.exe', 'tools\\quake2\\qdata\\Release\\qdata3.exe' ) , '$QUAKE2RADIANTDIR' ),
( ( 'plugins\\vfspak\\Debug\\vfspak.dll', 'plugins\\vfspak\\Release\\vfspak.dll' ), '$HERETIC2RADIANTDIR\\modules' ),
( ( 'plugins\\imagem8\\Debug\\imagem8.dll', 'plugins\\imagem8\\Release\\imagem8.dll' ), '$HERETIC2RADIANTDIR\\modules' ),
( ( 'plugins\\surface_heretic2\\Debug\\surface_heretic2.dll', 'plugins\\surface_heretic2\\Release\\surface_heretic2.dll' ), '$HERETIC2RADIANTDIR\\modules' ),
( ( 'tools\\quake2\\qdata_heretic2\\Debug\\qdata3.exe', 'tools\\quake2\\qdata_heretic2\\Release\\qdata3.exe' ) , '$HERETIC2RADIANTDIR' ),
( ( 'contrib\\bkgrnd2d\\Debug\\bkgrnd2d.dll', 'contrib\\bkgrnd2d\\Release\\bkgrnd2d.dll' ), '$CORERADIANTDIR\\plugins' ),
]
config = 0
q3map2 = 0
# config check
for i in sys.argv:
if ( i == 'release' ):
config = 1
elif ( i == 'q3map2' ):
q3map2 = 1
if ( config == 1 ):
print 'installing release binaries'
else:
print 'installing debug binaries'
def expand(path_in):
for matches in paths.keys():
exp = re.compile('\\$%s' % matches)
if ( not re.match(exp, path_in) is None ):
#print "Got a match for %s on %s" % ( matches, path_in )
path_in = re.sub(exp, paths[matches], path_in)
#print "Processed to: %s" % path_in
return path_in
# don't bother about stderr
sys.stderr = sys.stdout
if ( q3map2 == 0 ):
stuff = q3map2_list
stuff += all
else:
stuff = q3map2_list
for entries in stuff:
try:
src = expand(entries[0][config])
#print "src basename: %s -> %s" % (src, os.path.basename(src))
dst = entries[1]
dst = os.path.join( entries[1], os.path.basename(src) )
dst = expand(dst)
#print "src: %s dst: %s" % (src, dst)
if (os.path.isfile(src)):
if (os.path.isfile(dst)):
if (not filecmp.cmp(src, dst)):
shutil.copy(src, dst)
print "%s: OK - updated" % dst
else:
print "%s: OK - already up to date" % dst
else:
shutil.copy(src, dst)
print "%s: OK - installed" % dst
else:
print "%s: FAILED - not found" % src
if (os.path.isfile(dst)):
print "delete %s" % dst
os.remove(dst)
except:
print "%s: FAILED" % src
traceback.print_exc()
# install the fucking files
# check the md5 to decide for a copy
# we have a site.conf to go through
# and a data list of stuff
# it's called at the end of each build to copy what needs to be
# it could be called only at GtkRadiant link time
# command line: a bunch of config switches default would be debug?, and release flag
import sys, traceback, os, re, filecmp, shutil, pickle, string
from makeversion import get_version
(line, major, minor) = get_version()
paths = {
'CORERADIANTDIR' : 'C:\\Program Files\\GtkRadiant-1.' + major,
'RTCWRADIANTDIR' : 'C:\\Program Files\\Return to Castle Wolfenstein - Game of The Year Edition\\Radiant-1.' + major,
'HLRADIANTDIR' : 'C:\\Sierra\\Half-Life\\Radiant-1.' + major,
'SOF2RADIANTDIR' : 'C:\\Program Files\\Soldier of Fortune II - Double Helix\\Radiant-1.' + major,
'QUAKE2RADIANTDIR' : 'C:\\Quake2\\Radiant-1.' + major,
'HERETIC2RADIANTDIR' : 'C:\\Heretic2\\Radiant-1.' + major
}
conf_filename='site.conf.win32'
# site settings ----------------------
if (os.path.exists(conf_filename)):
site_file = open(conf_filename, 'r')
p = pickle.Unpickler(site_file)
paths = p.load()
print 'Loaded configuration from ' + conf_filename
# end site settings ------------------
# command line overrides -------------
print '\nCommand line:'
regex = re.compile("(.*)=(.*)")
for i in sys.argv[1:]:
#print i
if ( regex.match(i) ):
(key, val) = string.split(i, '=')
#print 'key: %s val: %s' % (key, val)
paths[key] = val
else:
print 'Can''t parse command line - ignore: ' + i
# end command line overrides ---------
# save config ------------------------
site_file = open(conf_filename, 'w')
p = pickle.Pickler(site_file)
p.dump(paths)
site_file.close()
print '\nConfiguration:'
for i in paths.keys():
print '%s -> %s' % (i, paths[i])
# end save config --------------------
q3map2_list = [
# ( ( '..\\libpng\\projects\\msvc\\win32\\zlib\\dll_dbg\\zlibd.dll', '..\\libpng\\projects\\msvc\\win32\\zlib\\dll\\zlib.dll' ), '$CORERADIANTDIR' ),
# ( ( '..\\libpng\\projects\\msvc\\win32\\libpng\\dll_dbg\\libpng13d.dll', '..\\libpng\\projects\\msvc\\win32\\libpng\\dll\\libpng13.dll' ), '$CORERADIANTDIR' ),
# ( ( '..\\libxml2\\win32\\binaries-debug\\libxml2.dll', '..\\libxml2\\win32\\binaries-release\\libxml2.dll' ), '$CORERADIANTDIR' ),
( ( 'tools\\quake3\\q3map2\\Debug\\Q3Map2.exe', 'tools\\quake3\\q3map2\\Release\\Q3Map2.exe' ), '$CORERADIANTDIR' ),
]
all = [
( ( 'radiant\\Debug\\GtkRadiant.exe', 'radiant\\Release\\GtkRadiant.exe' ) , '$CORERADIANTDIR' ),
( ( 'contrib\\bobtoolz\\Debug\\bobToolz.dll', 'contrib\\bobtoolz\\Release\\bobToolz.dll' ), '$CORERADIANTDIR\\plugins' ),
( ( 'contrib\\camera\\Debug\\camera.dll', 'contrib\\camera\\Release\\camera.dll' ), '$CORERADIANTDIR\\plugins' ),
( ( 'plugins\\entity\\Debug\\entity.dll', 'plugins\\entity\\Release\\entity.dll' ), '$CORERADIANTDIR\\modules' ),
( ( 'plugins\\eclassfgd\\Debug\\fgd.dll', 'plugins\\eclassfgd\\Release\\fgd.dll' ), '$CORERADIANTDIR\\modules' ),
( ( 'contrib\\gtkgensurf\\Debug\\gensurf.dll', 'contrib\\gtkgensurf\\Release\\gensurf.dll' ), '$CORERADIANTDIR\\plugins' ),
( ( 'contrib\\hydratoolz\\Debug\\hydratoolz.dll', 'contrib\\hydratoolz\\Release\\hydratoolz.dll' ), '$HLRADIANTDIR\\plugins' ),
( ( 'plugins\\image\\Debug\\image.dll', 'plugins\\image\\Release\\image.dll' ), '$CORERADIANTDIR\\modules' ),
( ( 'plugins\\imagewal\\Debug\\imagewal.dll', 'plugins\\imagewal\\Release\\imagewal.dll' ), '$QUAKE2RADIANTDIR\\modules' ),
( ( 'plugins\\imagehl\\Debug\\imagehl.dll', 'plugins\\imagehl\\Release\\imagehl.dll' ), '$CORERADIANTDIR\\modules' ),
( ( 'plugins\\imagepng\\Debug\\imagepng.dll', 'plugins\\imagepng\\Release\\imagepng.dll' ), '$CORERADIANTDIR\\modules' ),
( ( 'plugins\\map\\Debug\\map.dll', 'plugins\\map\\Release\\map.dll' ), '$CORERADIANTDIR\\modules' ),
( ( 'plugins\\mapxml\\Debug\\mapxml.dll', 'plugins\\mapxml\\Release\\mapxml.dll' ), '$CORERADIANTDIR\\modules' ),
( ( 'plugins\\model\\Debug\\model.dll', 'plugins\\model\\Release\\model.dll' ), '$CORERADIANTDIR\\modules' ),
( ( 'contrib\\prtview\\Debug\\PrtView.dll', 'contrib\\prtview\\Release\\PrtView.dll' ), '$CORERADIANTDIR\\plugins' ),
( ( 'tools\\quake3\\q3data\\Debug\\q3data.exe', 'tools\\quake3\\q3data\\Release\\q3data.exe' ), '$CORERADIANTDIR' ),
( ( 'plugins\\shaders\\Debug\\shaders.dll', 'plugins\\shaders\\Release\\shaders.dll' ), '$CORERADIANTDIR\\modules' ),
( ( 'plugins\\spritemodel\\Debug\\spritemodel.dll', 'plugins\\spritemodel\\Release\\spritemodel.dll' ), '$CORERADIANTDIR\\modules' ),
# ( ( 'Debug\\TexTool.dll', 'Release\\TexTool.dll' ), '$CORERADIANTDIR\\plugins' ),
( ( 'plugins\\vfspk3\\Debug\\vfspk3.dll', 'plugins\\vfspk3\\Release\\vfspk3.dll' ), '$CORERADIANTDIR\\modules' ),
( ( 'plugins\\vfspak\\Debug\\vfspak.dll', 'plugins\\vfspak\\Release\\vfspak.dll' ), '$QUAKE2RADIANTDIR\\modules' ),
( ( 'plugins\\vfswad\\Debug\\vfswad.dll', 'plugins\\vfswad\\Release\\vfswad.dll' ), '$CORERADIANTDIR\\modules' ),
( ( 'plugins\\surface\\Debug\\surface.dll', 'plugins\\surface\\Release\\surface.dll' ), '$CORERADIANTDIR\\modules' ),
( ( 'plugins\\surface_quake2\\Debug\\surface_quake2.dll', 'plugins\\surface_quake2\\Release\\surface_quake2.dll' ), '$QUAKE2RADIANTDIR\\modules' ),
( ( 'tools\\quake2\\q2map\\Debug\\q2map.exe', 'tools\\quake2\\q2map\\Release\\q2map.exe' ) , '$QUAKE2RADIANTDIR' ),
( ( 'tools\\quake2\\qdata\\Debug\\qdata3.exe', 'tools\\quake2\\qdata\\Release\\qdata3.exe' ) , '$QUAKE2RADIANTDIR' ),
( ( 'plugins\\vfspak\\Debug\\vfspak.dll', 'plugins\\vfspak\\Release\\vfspak.dll' ), '$HERETIC2RADIANTDIR\\modules' ),
( ( 'plugins\\imagem8\\Debug\\imagem8.dll', 'plugins\\imagem8\\Release\\imagem8.dll' ), '$HERETIC2RADIANTDIR\\modules' ),
( ( 'plugins\\surface_heretic2\\Debug\\surface_heretic2.dll', 'plugins\\surface_heretic2\\Release\\surface_heretic2.dll' ), '$HERETIC2RADIANTDIR\\modules' ),
( ( 'tools\\quake2\\qdata_heretic2\\Debug\\qdata3.exe', 'tools\\quake2\\qdata_heretic2\\Release\\qdata3.exe' ) , '$HERETIC2RADIANTDIR' ),
( ( 'contrib\\bkgrnd2d\\Debug\\bkgrnd2d.dll', 'contrib\\bkgrnd2d\\Release\\bkgrnd2d.dll' ), '$CORERADIANTDIR\\plugins' ),
]
config = 0
q3map2 = 0
# config check
for i in sys.argv:
if ( i == 'release' ):
config = 1
elif ( i == 'q3map2' ):
q3map2 = 1
if ( config == 1 ):
print 'installing release binaries'
else:
print 'installing debug binaries'
def expand(path_in):
for matches in paths.keys():
exp = re.compile('\\$%s' % matches)
if ( not re.match(exp, path_in) is None ):
#print "Got a match for %s on %s" % ( matches, path_in )
path_in = re.sub(exp, paths[matches], path_in)
#print "Processed to: %s" % path_in
return path_in
# don't bother about stderr
sys.stderr = sys.stdout
if ( q3map2 == 0 ):
stuff = q3map2_list
stuff += all
else:
stuff = q3map2_list
for entries in stuff:
try:
src = expand(entries[0][config])
#print "src basename: %s -> %s" % (src, os.path.basename(src))
dst = entries[1]
dst = os.path.join( entries[1], os.path.basename(src) )
dst = expand(dst)
#print "src: %s dst: %s" % (src, dst)
if (os.path.isfile(src)):
if (os.path.isfile(dst)):
if (not filecmp.cmp(src, dst)):
shutil.copy(src, dst)
print "%s: OK - updated" % dst
else:
print "%s: OK - already up to date" % dst
else:
shutil.copy(src, dst)
print "%s: OK - installed" % dst
else:
print "%s: FAILED - not found" % src
if (os.path.isfile(dst)):
print "delete %s" % dst
os.remove(dst)
except:
print "%s: FAILED" % src
traceback.print_exc()