mirror of
https://github.com/id-Software/DOOM-3-BFG.git
synced 2025-03-15 07:00:58 +00:00
Merge branch 'master' into vkdoom3-merge
This commit is contained in:
commit
ee4ade8c11
4 changed files with 467 additions and 13 deletions
43
README.txt
43
README.txt
|
@ -81,9 +81,11 @@ covered by the original EULA and must be obeyed as usual.
|
|||
|
||||
You must patch the game to the latest version.
|
||||
|
||||
Note that Doom 3 BFG Edition is available from the Steam store at
|
||||
http://store.steampowered.com/app/208200/
|
||||
You can purchase Doom 3 BFG Edition from GOG (DRM Free):
|
||||
https://www.gog.com/game/doom_3_bfg_edition
|
||||
|
||||
Or the game can be purchased from Steam (with DRM):
|
||||
http://store.steampowered.com/app/208200/
|
||||
|
||||
Steam:
|
||||
------
|
||||
|
@ -214,11 +216,11 @@ C:\Program Files (x86)\Steam\SteamApps\common\Doom 3 BFG Edition\ directory and
|
|||
|
||||
The following instructions are primarily intented for Linux users and all hackers on other operating systems.
|
||||
|
||||
To play the game, you need the game data from a legal copy of the game, which
|
||||
unfortunately requires Steam for Windows - Steam for Linux or OSX won't do, because
|
||||
(at least currently) the Doom 3 BFG game is only installable on Steam for Windows.
|
||||
Even the DVD version of Doom 3 BFG only contains encrytped data that is decoded
|
||||
by Steam on install.
|
||||
To play the game, you need the game data from a legal copy of the game.
|
||||
|
||||
Currently this requires a Windows installer, whether that be the GOG installer or by using Steam for Windows.
|
||||
|
||||
Note: the original DVD release of Doom 3 BFG contains encrypted data that is decoded by Steam on install.
|
||||
|
||||
On Linux and OSX the easiest way to install is with SteamCMD: https://developer.valvesoftware.com/wiki/SteamCMD
|
||||
See the description on https://developer.valvesoftware.com/wiki/SteamCMD#Linux (OS X is directly below that) on how to install SteamCMD on your system. You won't have to create a new user.
|
||||
|
@ -233,6 +235,29 @@ That number is the "AppID" of Doom 3 BFG; if you wanna use this to get the data
|
|||
|
||||
NOTE that we've previously recommended using download_depot in the Steam console to install the game data. That turned out to be unreliable and result in broken, unusable game data. So use SteamCMD instead, as described above.
|
||||
|
||||
Alternatively with the GOG installer, you can use Wine to install the game. See https://winehq.org/download for details on how to install wine for Linux and Mac.
|
||||
|
||||
Once Wine is installed and configured on your system install Doom 3 BFG edition using the downloaded installers from gog.com:
|
||||
|
||||
> wine setup_doom_3_bfg_1.14_\(13452\)_\(g\).exe
|
||||
|
||||
(there will be several .exe files from GOG, make sure all of them are in the same directory)
|
||||
|
||||
Once this is complete, by default you can find your Doom 3 BFG "base/" directory at ".wine/drive_c/GOG\ Games/DOOM\ 3\ BFG/base".
|
||||
|
||||
Note that you may want to add the following line to the bottom of the default.cfg in whatever "base/" directory you use:
|
||||
|
||||
> set sys_lang "english"
|
||||
|
||||
This will ensure the game and its menus are in english and don't default to something else. Alternatives include:
|
||||
|
||||
set sys_lang "english"
|
||||
set sys_lang "french"
|
||||
set sys_lang "german"
|
||||
set sys_lang "italian"
|
||||
set sys_lang "japanese"
|
||||
set sys_lang "spanish"
|
||||
|
||||
Anyway:
|
||||
|
||||
1. Install Doom 3 BFG in Steam (Windows version) or SteamCMD, make sure it's getting
|
||||
|
@ -240,10 +265,10 @@ Anyway:
|
|||
|
||||
2. Create your own Doom 3 BFG directory, e.g. /path/to/Doom3BFG/
|
||||
|
||||
3. Copy the game-data's base dir from Steam to that directory
|
||||
3. Copy the game-data's base dir from Steam or GOG to that directory
|
||||
(e.g. /path/to/Doom3BFG/), it's in
|
||||
/your/path/to/Steam/steamapps/common/DOOM 3 BFG Edition/base/
|
||||
or, if you used SteamCMD, in the path you used above.
|
||||
or, if you used SteamCMD or GOG installer with Wine, in the path you used above.
|
||||
|
||||
4. Copy your RBDoom3BFG executable that you created in 5) or 6) and the FFmpeg DLLs to your own
|
||||
Doom 3 BFG directory (/path/to/Doom3BFG).
|
||||
|
|
429
blender/scripts/addons/io_import_rbdoom_flash_json.py
Normal file
429
blender/scripts/addons/io_import_rbdoom_flash_json.py
Normal file
|
@ -0,0 +1,429 @@
|
|||
# THIS SCRIPT IS EXPERIMENTAL, UNFINISHED AND UNSUPPORTED
|
||||
|
||||
# RB: My intention of this script is to provide it as a backup before it gets lost.
|
||||
# Feel free to experiment with it and to load the id Tech 4.x Flash guis into Blender without animation
|
||||
|
||||
import json, sys, bpy
|
||||
import mathutils
|
||||
import time
|
||||
import os
|
||||
from decimal import *
|
||||
from math import *
|
||||
|
||||
jsonfilename = "G:\\Projects\\RBDOOM-3-BFG\\base\\exported\\swf\\shell.json"
|
||||
basepath = "G:\\Projects\\RBDOOM-3-BFG\\base\\"
|
||||
|
||||
start = time.time()
|
||||
data = json.loads( open( jsonfilename ).read() )
|
||||
end = time.time()
|
||||
print( "loading {0} took {1} seconds".format( jsonfilename, ( end - start ) ) )
|
||||
|
||||
|
||||
scene = bpy.context.scene
|
||||
|
||||
#[ %f, %f, %f, %f, %f, %f ]", m.xx, m.yy, m.xy, m.yx, m.tx, m.ty
|
||||
def transform_by_stylematrix( m, uv ):
|
||||
return ( ( uv[0] * m[0] ) + ( uv[1] * m[2] ) + m[4], ( uv[1] * m[1] ) + ( uv[0] * m[3] ) + m[5] )
|
||||
|
||||
def inverse_stylematrix( m ):
|
||||
inverse = [ 0, 0, 0, 0, 0, 0 ];
|
||||
|
||||
det = ( ( m[0] * m[1] ) - ( m[2] * m[3] ) )
|
||||
#if( idMath::Fabs( det ) < idMath::FLT_SMALLEST_NON_DENORMAL )
|
||||
#{
|
||||
# return *this;
|
||||
#}
|
||||
|
||||
invDet = 1.0 / det
|
||||
|
||||
inverse[0] = invDet * m[1]
|
||||
inverse[3] = invDet * -m[3]
|
||||
inverse[2] = invDet * -m[2]
|
||||
inverse[1] = invDet * m[0]
|
||||
#inverse.tx = invDet * ( xy * ty ) - ( yy * tx );
|
||||
#inverse.ty = invDet * ( yx * tx ) - ( xx * ty );
|
||||
return inverse
|
||||
|
||||
|
||||
def convert_flash_object( entry ):
|
||||
#print( entry["type"] )
|
||||
|
||||
origin = ( 0, 0, 0 )
|
||||
characterID = entry["characterID"]
|
||||
characterIDStr = "characterID.{0}".format( entry["characterID"] )
|
||||
|
||||
#print( "processing characterID {0} = {1}".format( characterID, entry["type"] ) )
|
||||
|
||||
|
||||
if entry["type"] == "IMAGE":
|
||||
|
||||
imgfile = entry["imageFile"]
|
||||
imgfilename = os.path.normpath( basepath + imgfile )
|
||||
|
||||
width = entry["width"]
|
||||
height = entry["height"]
|
||||
|
||||
if os.path.exists( imgfilename ):
|
||||
print( "found " + imgfilename )
|
||||
|
||||
# create material
|
||||
bmat = None
|
||||
if characterIDStr in bpy.data.materials:
|
||||
bmat = bpy.data.materials[ characterIDStr ]
|
||||
else:
|
||||
bmat = bpy.data.materials.new( characterIDStr )
|
||||
bmat.preview_render_type = 'FLAT'
|
||||
bmat.use_shadeless = True
|
||||
bmat.use_transparency = True
|
||||
bmat.alpha = 0
|
||||
bmattex = bmat.texture_slots.add()
|
||||
bmattex.use_map_alpha = True
|
||||
|
||||
# create image and assign to material
|
||||
image = None
|
||||
if characterIDStr in bpy.data.images:
|
||||
image = bpy.data.images[ characterIDStr ]
|
||||
else:
|
||||
image = bpy.data.images.load( imgfilename )
|
||||
image.use_alpha = True
|
||||
|
||||
btex = None
|
||||
if characterIDStr in bpy.data.textures:
|
||||
btex = bpy.data.textures[ characterIDStr ]
|
||||
else:
|
||||
btex = bpy.data.textures.new( characterIDStr, type = 'IMAGE' )
|
||||
btex.image = image
|
||||
|
||||
bmattex.texture = btex
|
||||
bmattex.texture_coords = 'UV'
|
||||
bmattex.mapping = 'FLAT'
|
||||
|
||||
|
||||
if entry["type"] == "SHAPE":
|
||||
|
||||
if "startBounds" in entry:
|
||||
startBounds = entry["startBounds"]
|
||||
origin = ( startBounds[0], startBounds[1], 0 )
|
||||
|
||||
meName = "shape.{0}".format( characterID )
|
||||
|
||||
me = bpy.data.meshes.new( meName )
|
||||
ob = bpy.data.objects.new( meName, me )
|
||||
ob.location = origin
|
||||
#ob.show_name = True
|
||||
|
||||
# give object unique characterID so any sprite can reference it
|
||||
ob["characterID"] = characterID
|
||||
|
||||
# link object to scene and make active
|
||||
scene.objects.link( ob )
|
||||
scene.objects.active = ob
|
||||
ob.select = True
|
||||
|
||||
bpy.ops.group.create( name = characterIDStr )
|
||||
group = bpy.data.groups[ characterIDStr ]
|
||||
group["characterID"] = characterID
|
||||
|
||||
#for i in range( len( entry["fillDraws"] ) ):
|
||||
# fillDraw = entry["fillDraws"][i]
|
||||
|
||||
#if len( entry["fillDraws"] ) > 1:
|
||||
# error
|
||||
|
||||
# build basic mesh from all fillDraws and assign different materials to the faces
|
||||
verts = []
|
||||
faces = []
|
||||
numverts = 0
|
||||
|
||||
if "fillDraws" in entry:
|
||||
for fillDraw in entry["fillDraws"]:
|
||||
|
||||
if "startVerts" not in fillDraw:
|
||||
continue
|
||||
|
||||
# convert triangles to faces
|
||||
indices = fillDraw["indices"]
|
||||
for i in range( 0, len( indices ), 3 ):
|
||||
faces.append( ( numverts + indices[i], numverts + indices[i+1], numverts + indices[i+2] ) )
|
||||
|
||||
fillDraw["firstVert"] = numverts
|
||||
|
||||
for v in fillDraw["startVerts"]:
|
||||
verts.append( ( v["v"][0], v["v"][1], 0.0 ) )
|
||||
numverts += 1
|
||||
|
||||
if "lineDraws" in entry:
|
||||
|
||||
print( "characterID {0} = {1} has lineDraws".format( characterID, entry["type"] ) )
|
||||
|
||||
for lineDraw in entry["lineDraws"]:
|
||||
|
||||
if "startVerts" not in lineDraw:
|
||||
continue
|
||||
|
||||
# convert triangles to faces
|
||||
indices = lineDraw["indices"]
|
||||
for i in range( 0, len( indices ), 3 ):
|
||||
faces.append( ( numverts + indices[i], numverts + indices[i+1], numverts + indices[i+2] ) )
|
||||
|
||||
lineDraw["firstVert"] = numverts
|
||||
|
||||
for v in lineDraw["startVerts"]:
|
||||
verts.append( ( v["v"][0], v["v"][1], 0.0 ) )
|
||||
numverts += 1
|
||||
|
||||
me.from_pydata( verts, [], faces )
|
||||
|
||||
bpy.ops.object.editmode_toggle()
|
||||
#bpy.ops.mesh.quads_convert_to_tris( quad_method = 'BEAUTY', ngon_method = 'BEAUTY' )
|
||||
bpy.ops.mesh.tris_convert_to_quads()
|
||||
#bpy.ops.uv.reset()
|
||||
#bpy.ops.uv.unwrap()
|
||||
bpy.ops.object.editmode_toggle()
|
||||
|
||||
# create uv map
|
||||
me.uv_textures.new()
|
||||
me.update()
|
||||
|
||||
if "fillDraws" in entry:
|
||||
#for fillDraw in entry["fillDraws"]:
|
||||
for i in range( len( entry["fillDraws"] ) ):
|
||||
|
||||
fillDraw = entry["fillDraws"][i]
|
||||
|
||||
if fillDraw["style"]["type"] == "bitmap":
|
||||
|
||||
bitmapID = fillDraw["style"]["bitmapID"]
|
||||
|
||||
if bitmapID == 65535:
|
||||
continue
|
||||
|
||||
stylematrix = inverse_stylematrix( fillDraw["style"]["startMatrix"] )
|
||||
|
||||
# build uv coords
|
||||
#firstVert = fillDraw["firstVert"]
|
||||
|
||||
# FIXME only calculate UVs vertices of this bitmap
|
||||
for i in range( len( me.vertices ) ):
|
||||
v = me.vertices[i]
|
||||
|
||||
width = startBounds[2] - startBounds[0]
|
||||
height = startBounds[3] - startBounds[1]
|
||||
|
||||
uv = ( ( ( v.co[0] - startBounds[0] ) * ( 1.0 / width ) * 1.0 ) , ( v.co[1] - startBounds[1] ) * ( 1.0 / height ) * 1.0 )
|
||||
uv = ( 1.0 - uv[0], uv[1] )
|
||||
me.uv_layers[0].data[i].uv = uv
|
||||
|
||||
#uv = ( v.co[0] * ( 1.0 / startBounds["width"] ) * 20.0 , v.co[1] * ( 1.0 / startBounds["height"] ) * 20.0 )
|
||||
#uv = ( 1.0 - uv[0], uv[1] )
|
||||
#me.uv_layers[0].data[i].uv = transform_by_stylematrix( stylematrix, uv )
|
||||
|
||||
if characterID == 135:
|
||||
print( "v = ({0},{1}) uv = ({2},{3})".format( v.co[0], v.co[1], uv[0], uv[1] ) )
|
||||
|
||||
|
||||
# assign bitmap
|
||||
|
||||
bitmap = "characterID.{0}".format( bitmapID )
|
||||
|
||||
if bitmap not in me.materials:
|
||||
bitmapmat = bpy.data.materials[ "characterID.{0}".format( bitmapID ) ]
|
||||
me.materials.append( bitmapmat )
|
||||
|
||||
me.update()
|
||||
|
||||
|
||||
if fillDraw["style"]["type"] == "solid":
|
||||
|
||||
startColor = [ 1.0, 1.0, 1.0, 1.0 ]
|
||||
|
||||
if "startColor" in fillDraw["style"]:
|
||||
startColor = fillDraw["style"]["startColor"]
|
||||
|
||||
solidmat = bpy.data.materials.new( "shape.{0}.fillDraw.{1}".format( characterID, i ) )
|
||||
solidmat.preview_render_type = 'FLAT'
|
||||
solidmat.use_shadeless = True
|
||||
solidmat.use_transparency = True
|
||||
solidmat.diffuse_color = ( startColor[0], startColor[1], startColor[2] )
|
||||
solidmat.alpha = startColor[3]
|
||||
me.materials.append( solidmat )
|
||||
|
||||
|
||||
|
||||
if entry["type"] == "SPRITE":
|
||||
|
||||
bpy.ops.object.add(
|
||||
type='EMPTY',
|
||||
enter_editmode=False,
|
||||
location=origin)
|
||||
|
||||
sprite = bpy.context.object
|
||||
|
||||
if "mainsprite" in entry:
|
||||
sprite.name = "mainsprite"
|
||||
sprite.show_name = True
|
||||
else:
|
||||
sprite.name = "sprite.{0}".format( characterID )
|
||||
|
||||
sprite["characterID"] = characterID
|
||||
|
||||
bpy.ops.group.create( name = characterIDStr )
|
||||
|
||||
spriteGroup = bpy.data.groups[ characterIDStr ]
|
||||
spriteGroup["characterID"] = characterID
|
||||
|
||||
#sprite.select = True
|
||||
|
||||
#scene.objects.active = ob
|
||||
|
||||
for command in entry["commands"]:
|
||||
|
||||
if command["type"] == "Tag_PlaceObject2":
|
||||
|
||||
if "characterID" in command:
|
||||
targetID = command["characterID"]
|
||||
|
||||
# instantiate target
|
||||
bpy.ops.object.select_all( action = 'DESELECT' )
|
||||
|
||||
#print( bpy.context.selected_objects )
|
||||
|
||||
#print( "searching targetID ", targetID )
|
||||
|
||||
target = None
|
||||
for group in bpy.data.groups:
|
||||
if "characterID" in group and group["characterID"] == targetID:
|
||||
target = group
|
||||
break
|
||||
|
||||
if target == None:
|
||||
print( "missed target ", targetID )
|
||||
|
||||
|
||||
if target != None:
|
||||
|
||||
#print( "duplicating target = ", target.name )
|
||||
#print( bpy.context.selected_objects )
|
||||
|
||||
#bpy.ops.object.duplicate()
|
||||
bpy.ops.object.group_instance_add( name = target.name )
|
||||
bpy.ops.object.group_link( group = spriteGroup.name )
|
||||
|
||||
targetClone = bpy.context.selected_objects[0]
|
||||
|
||||
if "name" in command:
|
||||
targetClone.name = "{0}.{1}".format( sprite.name, command["name"] )
|
||||
targetClone.show_name = True
|
||||
else:
|
||||
targetClone.name = "{0}.characterID.{1}".format( sprite.name, targetID )
|
||||
|
||||
targetClone.parent = sprite
|
||||
#targetClone["characterID"] = -1
|
||||
|
||||
# move instance to startMatrix
|
||||
m = [1.0, 1.0, 0.0, 0.0, 0.0, 0.0 ]
|
||||
|
||||
if "startMatrix" in command:
|
||||
m = command["startMatrix"]
|
||||
|
||||
targetClone.location = ( m[4], m[5], -1.0 )
|
||||
targetClone.scale = ( m[0], m[1], 1.0 )
|
||||
|
||||
bpy.ops.object.select_all( action = 'DESELECT' )
|
||||
|
||||
|
||||
|
||||
"""
|
||||
if entry["type"] == "SPRITE":
|
||||
|
||||
bpy.ops.object.add(
|
||||
type='EMPTY',
|
||||
enter_editmode=False,
|
||||
location=origin)
|
||||
|
||||
sprite = bpy.context.object
|
||||
sprite.name = "sprite.{0}".format( characterID )
|
||||
#sprite.show_name = True
|
||||
sprite["characterID"] = characterID
|
||||
#sprite.select = True
|
||||
|
||||
#scene.objects.active = ob
|
||||
|
||||
for command in entry["commands"]:
|
||||
|
||||
if command["type"] == "Tag_PlaceObject2":
|
||||
|
||||
if "characterID" in command:
|
||||
targetID = command["characterID"]
|
||||
|
||||
# instantiate target
|
||||
bpy.ops.object.select_all( action = 'DESELECT' )
|
||||
|
||||
#print( bpy.context.selected_objects )
|
||||
|
||||
#print( "searching targetID ", targetID )
|
||||
|
||||
target = None
|
||||
for obj in scene.objects:
|
||||
if "characterID" in obj and obj["characterID"] == targetID:
|
||||
target = obj
|
||||
break
|
||||
|
||||
if target == None:
|
||||
print( "missed target ", targetID )
|
||||
|
||||
|
||||
if target != None:
|
||||
target.select = True
|
||||
|
||||
print( "duplicating target = ", target.name )
|
||||
print( bpy.context.selected_objects )
|
||||
|
||||
bpy.ops.object.duplicate()
|
||||
|
||||
targetClone = bpy.context.selected_objects[0]
|
||||
|
||||
if "name" in command:
|
||||
targetClone.name = "{0}.{1}".format( sprite.name, command["name"] )
|
||||
else:
|
||||
targetClone.name = "{0}.characterID.{1}".format( sprite.name, targetID )
|
||||
|
||||
targetClone.parent = sprite
|
||||
targetClone["characterID"] = -1
|
||||
|
||||
bpy.ops.object.select_all( action = 'DESELECT' )
|
||||
|
||||
for obj in target.children:
|
||||
obj.select = True
|
||||
|
||||
#scene.objects.active.parent = target
|
||||
#bpy.ops.object.select_grouped( type = 'CHILDREN_RECURSIVE' )
|
||||
print( bpy.context.selected_objects )
|
||||
|
||||
bpy.ops.object.duplicate()
|
||||
|
||||
for clone in bpy.context.selected_objects:
|
||||
|
||||
if "name" in command:
|
||||
clone.name = "{0}.{1}".format( targetClone.name, clone.name )
|
||||
else:
|
||||
clone.name = "{0}.{1}".format( sprite.name, clone.name )
|
||||
clone.parent = targetClone
|
||||
clone["characterID"] = -1
|
||||
|
||||
m = command["startMatrix"]
|
||||
clone.location = ( m[4], m[5], 0.0 )
|
||||
clone.scale = ( m[0], m[1], 1.0 )
|
||||
|
||||
"""
|
||||
|
||||
|
||||
|
||||
#remove all groups
|
||||
for group in bpy.data.groups:
|
||||
bpy.data.groups.remove( group )
|
||||
|
||||
print( bpy.data.groups )
|
||||
|
||||
for entry in data["dict"]:
|
||||
convert_flash_object( entry )
|
|
@ -1511,7 +1511,7 @@ void WI_loadData(void)
|
|||
// DHM - Nerve :: Use our background image
|
||||
//strcpy(name, "DMENUPIC");
|
||||
else
|
||||
std::snprintf(name, sizeof( name ), "WIMAP%d", ::g->wbs->epsd);
|
||||
idStr::snPrintf(name, sizeof( name ), "WIMAP%d", ::g->wbs->epsd);
|
||||
|
||||
if ( ::g->gamemode == retail )
|
||||
{
|
||||
|
|
|
@ -366,7 +366,7 @@ ID_INLINE void idCVar::Init( const char* name, const char* value, int flags, con
|
|||
this->integerValue = 0;
|
||||
this->floatValue = 0.0f;
|
||||
this->internalVar = this;
|
||||
if( staticVars != ( idCVar* )0xFFFFFFFF )
|
||||
if( staticVars != ( idCVar* )UINTPTR_MAX )
|
||||
{
|
||||
this->next = staticVars;
|
||||
staticVars = this;
|
||||
|
@ -379,13 +379,13 @@ ID_INLINE void idCVar::Init( const char* name, const char* value, int flags, con
|
|||
|
||||
ID_INLINE void idCVar::RegisterStaticVars()
|
||||
{
|
||||
if( staticVars != ( idCVar* )0xFFFFFFFF )
|
||||
if( staticVars != ( idCVar* )UINTPTR_MAX )
|
||||
{
|
||||
for( idCVar* cvar = staticVars; cvar; cvar = cvar->next )
|
||||
{
|
||||
cvarSystem->Register( cvar );
|
||||
}
|
||||
staticVars = ( idCVar* )0xFFFFFFFF;
|
||||
staticVars = ( idCVar* )UINTPTR_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue