mirror of
https://github.com/TTimo/GtkRadiant.git
synced 2024-11-10 07:11:54 +00:00
Merge branch 'master' of https://github.com/TTimo/GtkRadiant
This commit is contained in:
commit
fee655c15f
34 changed files with 1758 additions and 633 deletions
40
.gitignore
vendored
40
.gitignore
vendored
|
@ -1,18 +1,30 @@
|
|||
/apple/target/*
|
||||
/build
|
||||
/install/games
|
||||
/install/installs
|
||||
/install/q3data
|
||||
/install/q3map2
|
||||
/install/q3map2_urt
|
||||
/install/radiant.bin
|
||||
/install/share
|
||||
/packs
|
||||
/site.sconf
|
||||
/.sconsign.dblite
|
||||
*.pyc
|
||||
*.so
|
||||
.settings
|
||||
.DS_Store
|
||||
|
||||
/apple/target/*
|
||||
/build
|
||||
/install
|
||||
/packs
|
||||
/tools/urt/tools/quake3/q3map2/Debug
|
||||
/tools/urt/tools/quake3/q3map2/Release
|
||||
/.sconsign.dblite
|
||||
/.vs/radiant/v14/.suo
|
||||
/radiant.opensdf
|
||||
/radiant.sdf
|
||||
/radiant.suo
|
||||
/radiant.v11.suo
|
||||
/radiant.v12.suo
|
||||
/radiant.VC.db
|
||||
/site.sconf
|
||||
|
||||
*.obj
|
||||
*.pyc
|
||||
*.so
|
||||
*.tlog
|
||||
*.vcxproj.user
|
||||
*.zip
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
[submodule "bspc"]
|
||||
path = bspc
|
||||
url = git@github.com:TTimo/bspc.git
|
1
bspc
Submodule
1
bspc
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit a1287590f17c35a612f33708aeec5815402866b8
|
|
@ -137,16 +137,6 @@ struct _QERModelLoad
|
|||
|
||||
//=========================================
|
||||
// plugin functions
|
||||
#if 0
|
||||
// NOTE TTimo: hack to make old plugin tech and new plugin tech live together
|
||||
#ifndef _IPLUGIN_H_
|
||||
// toolkit-independant interface, cast hwndMain to GtkWidget*
|
||||
typedef const char* ( WINAPI * PFN_QERPLUG_INIT )( void* hApp, void* hwndMain );
|
||||
typedef const char* ( WINAPI * PFN_QERPLUG_GETNAME )();
|
||||
typedef const char* ( WINAPI * PFN_QERPLUG_GETCOMMANDLIST )();
|
||||
typedef void ( WINAPI * PFN_QERPLUG_DISPATCH )( const char* p, vec3_t vMin, vec3_t vMax, bool bSingleBrush );
|
||||
#endif
|
||||
#endif
|
||||
|
||||
typedef char* ( WINAPI * PFN_QERPLUG_GETFUNCTABLE )();
|
||||
|
||||
|
@ -275,115 +265,6 @@ typedef char* ( WINAPI * PFN_QERAPP_PROFILE_LOADSTR )( const char *filename, con
|
|||
// To use the active or selected brush lists, you must first allocate them (which returns a count) and then
|
||||
// release them when you are finish manipulating brushes in one of those lists.
|
||||
|
||||
//++timo NOTE : the #defines here are never used, but can help finding where things are done in the editor
|
||||
#if 0
|
||||
// brush manipulation routines
|
||||
#define QERAPP_CREATEBRUSH "QERApp_CreateBrush"
|
||||
#define QERAPP_CREATEBRUSHHANDLE "QERApp_CreateBrushHandle"
|
||||
#define QERAPP_DELETEBRUSHHANDLE "QERApp_DeleteBrushHandle"
|
||||
#define QERAPP_COMMITBRUSHHANDLETOMAP "QERApp_CommitBrushHandleToMap"
|
||||
//++timo not implemented .. remove
|
||||
// #define QERAPP_BINDHANDLESTOENTITY "QERApp_BindHandlesToEntity"
|
||||
#define QERAPP_ADDFACE "QERApp_AddFace"
|
||||
#define QERAPP_ADDFACEDATA "QERApp_AddFaceData"
|
||||
#define QERAPP_GETFACECOUNT "QERApp_GetFaceCount"
|
||||
#define QERAPP_GETFACEDATA "QERApp_GetFaceData"
|
||||
#define QERAPP_SETFACEDATA "QERApp_SetFaceData"
|
||||
#define QERAPP_DELETEFACE "QERApp_DeleteFace"
|
||||
#define QERAPP_TEXTUREBRUSH "QERApp_TextureBrush"
|
||||
#define QERAPP_BUILDBRUSH "QERApp_BuildBrush" // PGM
|
||||
#define QERAPP_SELECTEDBRUSHCOUNT "QERApp_SelectedBrushCount"
|
||||
#define QERAPP_ALLOCATESELECTEDBRUSHHANDLES "QERApp_AllocateSelectedBrushHandles"
|
||||
#define QERAPP_RELEASESELECTEDBRUSHHANDLES "QERApp_ReleaseSelectedBrushHandles"
|
||||
#define QERAPP_GETSELECTEDBRUSHHANDLE "QERApp_GetSelectedBrushHandle"
|
||||
#define QERAPP_ACTIVEBRUSHCOUNT "QERApp_ActiveBrushCount"
|
||||
#define QERAPP_ALLOCATEACTIVEBRUSHHANDLES "QERApp_AllocateActiveBrushHandles"
|
||||
#define QERAPP_RELEASEACTIVEBRUSHHANDLES "QERApp_ReleaseActiveBrushHandles"
|
||||
#define QERAPP_GETACTIVEBRUSHHANDLE "QERApp_GetActiveBrushHandle"
|
||||
|
||||
// texture stuff
|
||||
#define QERAPP_TEXTURECOUNT "QERApp_TextureCount"
|
||||
#define QERAPP_GETTEXTURE "QERApp_GetTexture"
|
||||
#define QERAPP_GETCURRENTTEXTURE "QERApp_GetCurrentTexture"
|
||||
#define QERAPP_SETCURRENTTEXTURE "QERApp_SetCurrentTexture"
|
||||
|
||||
// selection
|
||||
#define QERAPP_DELETESELECTION "QERApp_DeleteSelection"
|
||||
#define QERAPP_SELECTBRUSH "QERApp_SelectBrush" // PGM
|
||||
#define QERAPP_DESELECTBRUSH "QERApp_DeselectBrush" // PGM
|
||||
#define QERAPP_DESELECTALLBRUSHES "QERApp_DeselectAllBrushes" // PGM
|
||||
|
||||
// data gathering
|
||||
#define QERAPP_GETPOINTS "QERApp_GetPoints"
|
||||
#define QERAPP_SELECTBRUSHES "QERApp_GetBrushes"
|
||||
|
||||
// entity class stuff
|
||||
// the entity handling is very basic for 1.0
|
||||
#define QERAPP_GETECLASSCOUNT "QERApp_GetEClassCount"
|
||||
#define QERAPP_GETECLASS "QERApp_GetEClass"
|
||||
|
||||
// misc
|
||||
#define QERAPP_SYSMSG "QERApp_SysMsg"
|
||||
#define QERAPP_INFOMSG "QERApp_InfoMsg"
|
||||
#define QERAPP_HIDEINFOMSG "QERApp_HideInfoMsg"
|
||||
#define QERAPP_RESET_PLUGINS "QERApp_ResetPlugins"
|
||||
|
||||
// texture loading
|
||||
#define QERAPP_LOADTEXTURERGBA "QERApp_LoadTextureRGBA"
|
||||
|
||||
// FIXME: the following are not implemented yet
|
||||
// hook registrations
|
||||
#define QERAPP_REGISTER_MAPLOADFUNC "QERApp_Register_MapLoadFunc"
|
||||
#define QERAPP_REGISTER_MAPSAVEFUNC "QERApp_Register_MapSaveFunc"
|
||||
|
||||
// FIXME: the following are not implemented yet
|
||||
#define QERAPP_REGISTER_PROJECTLOADFUNC "QERApp_Register_ProjectLoadFunc"
|
||||
#define QERAPP_REGISTER_MOUSEHANDLER "QERApp_Register_MouseHandler"
|
||||
#define QERAPP_REGISTER_KEYHANDLER "QERApp_Register_KeyHandler"
|
||||
|
||||
// FIXME: new primtives do not work in v1.00
|
||||
// primitives are new types of things in the map
|
||||
// for instance, the Q3 curves could have been done as
|
||||
// primitives instead of being built in
|
||||
// it will be a plugins responsibility to hook the map load and save funcs to load
|
||||
// and/or save any additional data (like new primitives of some type)
|
||||
// the editor will call each registered renderer during the rendering process to repaint
|
||||
// any primitives the plugin owns
|
||||
// each primitive object has a temporary sibling brush that lives in the map
|
||||
// FIXME: go backwards on this a bit.. orient it more towards the temp brush mode as it will be cleaner
|
||||
// basically a plugin will hook the map load and save and will add the primitives to the map.. this will
|
||||
// produce a temporary 'primitive' brush and the appropriate renderer will be called as well as the
|
||||
// edit handler (for edge drags, sizes, rotates, etc.. ) and the vertex maker will be called when vertex
|
||||
// mode is attemped on the brush.. there will need to be a GetPrimitiveBounds callback in the edit handler
|
||||
// so the brush can resize appropriately as needed.. this might be the plugins responsibility to set the
|
||||
// sibling brushes size.. it will then be the plugins responsibility to hook map save to save the primitives
|
||||
// as the editor will discard any temp primitive brushes.. (there probably needs to be some kind of sanity check
|
||||
// here as far as keeping the brushes and the plugin in sync.. i suppose the edit handler can deal with all of that
|
||||
// crap but it looks like a nice place for a mess)
|
||||
#define QERAPP_REGISTER_PRIMITIVE "QERApp_Register_Primitive"
|
||||
#define QERAPP_REGISTER_RENDERER "QERApp_Register_Renderer"
|
||||
#define QERAPP_REGISTER_EDITHANDLER "QERApp_Register_EditHandler"
|
||||
#define QERAPP_REGISTER_VERTEXMAKER "QERApp_Register_VertexMaker"
|
||||
#define QERAPP_ADDPRIMITIVE "QERApp_AddPrimitive"
|
||||
|
||||
// v1.70
|
||||
#define QERAPP_GETENTITYCOUNT "QERApp_GetEntityCount"
|
||||
#define QERAPP_GETENTITYHANDLE "QERApp_GetEntityHandle"
|
||||
//++timo not implemented for the moment
|
||||
// #define QERAPP_GETENTITYINFO "QERApp_GetEntityInfo"
|
||||
//++timo does the keyval need some more funcs to add/remove ?
|
||||
// get the pointer and do the changes yourself
|
||||
#define QERAPP_ALLOCATEEPAIR "QERApp_AllocateEpair"
|
||||
#define QERAPP_ALLOCATEENTITYBRUSHHANDLES "QERApp_AllocateEntityBrushHandles"
|
||||
#define QERAPP_RELEASEENTITYBRUSHHANDLES "QERApp_ReleaseEntityBrushHandles"
|
||||
#define QERAPP_GETENTITYBRUSHHANDLE "QERApp_GetEntityBrushHandle"
|
||||
#define QERAPP_CREATEENTITYHANDLE "QERApp_CreateEntityHandle"
|
||||
#define QERAPP_COMMITBRUSHHANDLETOENTITY "QERApp_CommitBrushHandleToEntity"
|
||||
#define QERAPP_COMMITENTITYHANDLETOMAP "QERApp_CommitEntityHandleToMap"
|
||||
#define QERAPP_SETSCREENUPDATE "QERApp_SetScreenUpdate"
|
||||
#define QERAPP_BUILDBRUSH2 "QERApp_BuildBrush2"
|
||||
#endif
|
||||
|
||||
// v1.80
|
||||
#define QERAPP_GETDISPATCHPARAMS "QERApp_GetDispatchParams"
|
||||
|
||||
|
|
7
install/.gitignore
vendored
Normal file
7
install/.gitignore
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
*.dll
|
||||
*.pdb
|
||||
*.exp
|
||||
*.ilk
|
||||
*.pdb
|
||||
*.lib
|
||||
*.exe
|
1
libs/.gitignore
vendored
Normal file
1
libs/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
x64
|
|
@ -105,6 +105,7 @@ struct picoSurface_s
|
|||
int numVertexes, maxVertexes;
|
||||
picoVec3_t *xyz;
|
||||
picoVec3_t *normal;
|
||||
picoIndex_t *smoothingGroup;
|
||||
|
||||
int numSTArrays, maxSTArrays;
|
||||
picoVec2_t **st;
|
||||
|
@ -216,6 +217,9 @@ const picoModule_t **PicoModuleList( int *numModules );
|
|||
|
||||
picoModel_t *PicoLoadModel( char *name, int frameNum );
|
||||
|
||||
typedef size_t(*PicoInputStreamReadFunc)(void* inputStream, unsigned char* buffer, size_t length);
|
||||
picoModel_t* PicoModuleLoadModelStream(const picoModule_t* module, void* inputStream, PicoInputStreamReadFunc inputStreamRead, size_t streamLength, int frameNum);
|
||||
|
||||
|
||||
/* model functions */
|
||||
picoModel_t *PicoNewModel( void );
|
||||
|
@ -263,6 +267,7 @@ void PicoSetSurfaceIndex( picoSurface_t *surface, int num
|
|||
void PicoSetSurfaceIndexes( picoSurface_t *surface, int num, picoIndex_t *index, int count );
|
||||
void PicoSetFaceNormal( picoSurface_t *surface, int num, picoVec3_t normal );
|
||||
void PicoSetSurfaceSpecial( picoSurface_t *surface, int num, int special );
|
||||
void PicoSetSurfaceSmoothingGroup( picoSurface_t *surface, int num, picoIndex_t smoothingGroup );
|
||||
|
||||
|
||||
/* getter functions */
|
||||
|
@ -330,12 +335,12 @@ picoVertexCombinationHash_t *PicoFindVertexCombinationInHashTable( picoVertexCom
|
|||
picoVertexCombinationHash_t *PicoAddVertexCombinationToHashTable( picoVertexCombinationHash_t **hashTable, picoVec3_t xyz, picoVec3_t normal, picoVec3_t st, picoColor_t color, picoIndex_t index );
|
||||
|
||||
/* specialized functions */
|
||||
int PicoFindSurfaceVertexNum( picoSurface_t *surface, picoVec3_t xyz, picoVec3_t normal, int numSTs, picoVec2_t *st, int numColors, picoColor_t *color );
|
||||
int PicoFindSurfaceVertexNum( picoSurface_t *surface, picoVec3_t xyz, picoVec3_t normal, int numSTs, picoVec2_t *st, int numColors, picoColor_t *color, picoIndex_t smoothingGroup );
|
||||
void PicoFixSurfaceNormals( picoSurface_t *surface );
|
||||
int PicoRemapModel( picoModel_t *model, char *remapFile );
|
||||
|
||||
|
||||
void PicoAddTriangleToModel( picoModel_t *model, picoVec3_t** xyz, picoVec3_t** normals, int numSTs, picoVec2_t **st, int numColors, picoColor_t **colors, picoShader_t* shader );
|
||||
void PicoAddTriangleToModel( picoModel_t *model, picoVec3_t** xyz, picoVec3_t** normals, int numSTs, picoVec2_t **st, int numColors, picoColor_t **colors, picoShader_t* shader, picoIndex_t* smoothingGroup );
|
||||
|
||||
/* end marker */
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -22,6 +22,35 @@ void lwFreeClip( lwClip *clip ){
|
|||
if ( clip ) {
|
||||
lwListFree( (void*) clip->ifilter, (ListFreeFunc) lwFreePlugin );
|
||||
lwListFree( (void*) clip->pfilter, (ListFreeFunc) lwFreePlugin );
|
||||
|
||||
switch ( clip->type ) {
|
||||
case ID_STIL:
|
||||
_pico_free( clip->source.still.name );
|
||||
break;
|
||||
|
||||
case ID_ISEQ:
|
||||
_pico_free( clip->source.seq.prefix );
|
||||
_pico_free( clip->source.seq.suffix );
|
||||
break;
|
||||
|
||||
case ID_ANIM:
|
||||
_pico_free( clip->source.anim.name );
|
||||
_pico_free( clip->source.anim.server );
|
||||
_pico_free( clip->source.anim.data );
|
||||
break;
|
||||
|
||||
case ID_XREF:
|
||||
_pico_free( clip->source.xref.string );
|
||||
break;
|
||||
|
||||
case ID_STCC:
|
||||
_pico_free( clip->source.cycle.name );
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
_pico_free( clip );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -161,35 +161,23 @@ void *_pico_realloc( void **ptr, size_t oldSize, size_t newSize ){
|
|||
* as custom clone size (the string is cropped to fit into mem
|
||||
* if needed). -sea
|
||||
*/
|
||||
char *_pico_clone_alloc( char *str, int size ){
|
||||
char *cloned;
|
||||
size_t cloneSize;
|
||||
char *_pico_clone_alloc( const char *str ) {
|
||||
char* cloned;
|
||||
|
||||
/* sanity check */
|
||||
if ( str == NULL ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* set real size of cloned string */
|
||||
cloneSize = ( size < 0 ) ? strlen( str ) : size;
|
||||
|
||||
/* allocate memory */
|
||||
cloned = _pico_alloc( cloneSize + 1 ); /* bugfix! */
|
||||
cloned = _pico_alloc(strlen(str) + 1);
|
||||
if ( cloned == NULL ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* zero out memory allocated by cloned string */
|
||||
memset( cloned,0,cloneSize );
|
||||
|
||||
/* copy input string to cloned string */
|
||||
if ( cloneSize < strlen( str ) ) {
|
||||
memcpy( cloned,str,cloneSize );
|
||||
cloned[ cloneSize ] = '\0';
|
||||
}
|
||||
else {
|
||||
strcpy( cloned,str );
|
||||
}
|
||||
strcpy(cloned, str);
|
||||
|
||||
/* return ptr to cloned string */
|
||||
return cloned;
|
||||
}
|
||||
|
@ -275,6 +263,19 @@ void _pico_printf( int level, const char *format, ... ){
|
|||
_pico_ptr_print( level,str );
|
||||
}
|
||||
|
||||
/* _pico_first_token:
|
||||
* trims everything after the first whitespace-delimited token
|
||||
*/
|
||||
|
||||
void _pico_first_token( char *str ) {
|
||||
if ( !str || ! * str ) {
|
||||
return;
|
||||
}
|
||||
while (*str && !isspace(*str))
|
||||
*str++;
|
||||
*str = '\0';
|
||||
}
|
||||
|
||||
/* _pico_strltrim:
|
||||
* left trims the given string -sea
|
||||
*/
|
||||
|
@ -542,7 +543,7 @@ float _pico_big_float( float src ){
|
|||
* case-insensitive strstr. -sea
|
||||
*/
|
||||
char *_pico_stristr( char *str, const char *substr ){
|
||||
const int sublen = strlen( substr );
|
||||
const size_t sublen = strlen( substr );
|
||||
while ( *str )
|
||||
{
|
||||
if ( !_pico_strnicmp( str,substr,sublen ) ) {
|
||||
|
@ -604,24 +605,24 @@ int _pico_nofname( const char *path, char *dest, int destSize ){
|
|||
* returns ptr to filename portion in given path or an empty
|
||||
* string otherwise. given 'path' is not altered. -sea
|
||||
*/
|
||||
char *_pico_nopath( const char *path ){
|
||||
char *src;
|
||||
src = (char *)path + ( strlen( path ) - 1 );
|
||||
const char *_pico_nopath( const char *path ){
|
||||
const char *src;
|
||||
|
||||
if ( path == NULL ) {
|
||||
return (char *)"";
|
||||
return "";
|
||||
}
|
||||
if ( !strchr( (char *)path,'/' ) && !strchr( (char *)path,'\\' ) ) {
|
||||
return ( (char *)path );
|
||||
if ( !strchr( path,'/' ) && !strchr( path,'\\' ) ) {
|
||||
return ( path );
|
||||
}
|
||||
|
||||
src = path + ( strlen( path ) - 1 );
|
||||
while ( ( src-- ) != path )
|
||||
{
|
||||
if ( *src == '/' || *src == '\\' ) {
|
||||
return ( ++src );
|
||||
}
|
||||
}
|
||||
return (char *)"";
|
||||
return "";
|
||||
}
|
||||
|
||||
/* _pico_setfext:
|
||||
|
|
|
@ -116,7 +116,7 @@ extern void ( *_pico_ptr_print )( int, const char* );
|
|||
void *_pico_alloc( size_t size );
|
||||
void *_pico_calloc( size_t num, size_t size );
|
||||
void *_pico_realloc( void **ptr, size_t oldSize, size_t newSize );
|
||||
char *_pico_clone_alloc( char *str, int size );
|
||||
char *_pico_clone_alloc( const char *str );
|
||||
void _pico_free( void *ptr );
|
||||
|
||||
/* files */
|
||||
|
@ -124,6 +124,7 @@ void _pico_load_file( char *name, unsigned char **buffer, int *bufSiz
|
|||
void _pico_free_file( void *buffer );
|
||||
|
||||
/* strings */
|
||||
void _pico_first_token(char *str);
|
||||
char *_pico_strltrim( char *str );
|
||||
char *_pico_strrtrim( char *str );
|
||||
int _pico_strchcount( char *str, int ch );
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -147,6 +147,7 @@
|
|||
<ClCompile Include="lwo\surface.c" />
|
||||
<ClCompile Include="lwo\vecmath.c" />
|
||||
<ClCompile Include="lwo\vmap.c" />
|
||||
<ClCompile Include="pm_terrain.c" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
|
|
|
@ -77,5 +77,8 @@
|
|||
<ClCompile Include="lwo\vmap.c">
|
||||
<Filter>src\lwo</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="pm_terrain.c">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -54,6 +54,7 @@ extern const picoModule_t picoModuleMDC;
|
|||
extern const picoModule_t picoModuleMD2;
|
||||
extern const picoModule_t picoModuleFM;
|
||||
extern const picoModule_t picoModuleLWO;
|
||||
extern const picoModule_t picoModuleTerrain;
|
||||
|
||||
|
||||
|
||||
|
@ -68,6 +69,7 @@ const picoModule_t *picoModules[] =
|
|||
&picoModuleMD2, /* quake2 md2 */
|
||||
&picoModuleFM, /* heretic2 fm */
|
||||
&picoModuleLWO, /* lightwave object */
|
||||
&picoModuleTerrain, /* picoterrain object */
|
||||
&picoModuleOBJ, /* wavefront object */
|
||||
NULL /* arnold */
|
||||
};
|
||||
|
@ -81,7 +83,7 @@ const picoModule_t *picoModules[] =
|
|||
this param can be NULL when the count is not needed.
|
||||
*/
|
||||
|
||||
const picoModule_t **PicoModuleList( int *numModules ){
|
||||
const picoModule_t **PicoModuleList( int *numModules ) {
|
||||
/* get module count */
|
||||
if ( numModules != NULL ) {
|
||||
for ( ( *numModules ) = 0; picoModules[ *numModules ] != NULL; ( *numModules )++ ) ;
|
||||
|
|
|
@ -124,7 +124,7 @@ debugChunkNames[] =
|
|||
{ CHUNK_OBJECT_UV, "CHUNK_OBJECT_UV" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
static char *DebugGetChunkName( int id ){
|
||||
static char *DebugGetChunkName( int id ) {
|
||||
int i,max; /* imax? ;) */
|
||||
max = sizeof( debugChunkNames ) / sizeof( debugChunkNames[0] );
|
||||
|
||||
|
@ -397,6 +397,9 @@ static int GetMeshShader( T3dsLoaderPers *pers ){
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* ydnar: trim to first whitespace */
|
||||
_pico_first_token( shaderName );
|
||||
|
||||
/* now that we have the shader name we need to go through all of */
|
||||
/* the shaders and check the name against each shader. when we */
|
||||
/* find a shader in our shader list that matches this name we */
|
||||
|
@ -418,7 +421,7 @@ static int GetMeshShader( T3dsLoaderPers *pers ){
|
|||
/* we have a valid map name ptr */
|
||||
if ( mapNamePtr != NULL ) {
|
||||
char temp[128];
|
||||
char *name;
|
||||
const char *name;
|
||||
|
||||
/* copy map name to local buffer */
|
||||
strcpy( mapName,mapNamePtr );
|
||||
|
@ -523,7 +526,6 @@ static int DoNextEditorDataChunk( T3dsLoaderPers *pers, long endofs ){
|
|||
/* read in surface name */
|
||||
if ( !GetASCIIZ( pers,surfaceName,sizeof( surfaceName ) ) ) {
|
||||
return 0; /* this is bad */
|
||||
|
||||
}
|
||||
//PicoGetSurfaceName
|
||||
/* ignore NULL name surfaces */
|
||||
|
@ -606,10 +608,13 @@ static int DoNextEditorDataChunk( T3dsLoaderPers *pers, long endofs ){
|
|||
/* but for now we skip the new material's name ... */
|
||||
if ( pers->shader ) {
|
||||
char *name = (char *)( pers->bufptr + pers->cofs );
|
||||
PicoSetShaderName( pers->shader,name );
|
||||
char *cleanedName = _pico_clone_alloc( name );
|
||||
_pico_first_token( cleanedName );
|
||||
PicoSetShaderName( pers->shader, cleanedName );
|
||||
#ifdef DEBUG_PM_3DS
|
||||
printf( "NewShader: '%s'\n",name );
|
||||
printf( "NewShader: '%s'\n", cleanedName );
|
||||
#endif
|
||||
_pico_free( cleanedName );
|
||||
}
|
||||
}
|
||||
if ( chunk->id == CHUNK_MATDIFFUSE ) {
|
||||
|
|
|
@ -105,6 +105,25 @@ static aseSubMaterial_t* _ase_get_submaterial( aseMaterial_t* list, int mtlIdPar
|
|||
return subMtl;
|
||||
}
|
||||
|
||||
aseSubMaterial_t* _ase_get_submaterial_or_default( aseMaterial_t* materials, int mtlIdParent, int subMtlId ){
|
||||
aseSubMaterial_t* subMtl = _ase_get_submaterial( materials, mtlIdParent, subMtlId );
|
||||
if ( subMtl != NULL ) {
|
||||
return subMtl;
|
||||
}
|
||||
|
||||
/* ydnar: trying default submaterial */
|
||||
subMtl = _ase_get_submaterial( materials, mtlIdParent, 0 );
|
||||
if ( subMtl != NULL ) {
|
||||
return subMtl;
|
||||
}
|
||||
|
||||
_pico_printf( PICO_ERROR, "Could not find material/submaterial for id %d/%d\n", mtlIdParent, subMtlId );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static aseMaterial_t* _ase_add_material( aseMaterial_t **list, int mtlIdParent ){
|
||||
aseMaterial_t *mtl = _pico_calloc( 1, sizeof( aseMaterial_t ) );
|
||||
mtl->mtlId = mtlIdParent;
|
||||
|
@ -173,64 +192,6 @@ static void _ase_print_materials( aseMaterial_t *list ){
|
|||
}
|
||||
#endif //DEBUG_PM_ASE
|
||||
|
||||
/* ASE Face management */
|
||||
/* These are used to keep an association between a submaterial and a face definition */
|
||||
/* They are kept in parallel with the current picoSurface, */
|
||||
/* and are used by _ase_submit_triangles to lookup the proper material/submaterial IDs */
|
||||
typedef struct aseFace_s
|
||||
{
|
||||
struct aseFace_s* next;
|
||||
int mtlId;
|
||||
int subMtlId;
|
||||
int index[9];
|
||||
} aseFace_t;
|
||||
|
||||
/* ASE Face management functions */
|
||||
void _ase_add_face( aseFace_t **list, aseFace_t **tail, aseFace_t *newFace ){
|
||||
/* insert as head of list */
|
||||
if ( !( *list ) ) {
|
||||
*list = newFace;
|
||||
}
|
||||
else
|
||||
{
|
||||
( *tail )->next = newFace;
|
||||
}
|
||||
|
||||
*tail = newFace;
|
||||
newFace->next = NULL;
|
||||
|
||||
//tag the color indices so we can detect them and apply the default color to them
|
||||
newFace->index[6] = -1;
|
||||
newFace->index[7] = -1;
|
||||
newFace->index[8] = -1;
|
||||
}
|
||||
|
||||
aseFace_t* _ase_get_face_for_index( aseFace_t *list, int index ){
|
||||
int counter = 0;
|
||||
aseFace_t* face = list;
|
||||
|
||||
while ( counter < index )
|
||||
{
|
||||
face = face->next;
|
||||
counter++;
|
||||
}
|
||||
return face;
|
||||
}
|
||||
static void _ase_free_faces( aseFace_t** list, aseFace_t** tail ){
|
||||
aseFace_t* face = *list;
|
||||
aseFace_t* tempFace = NULL;
|
||||
|
||||
while ( face )
|
||||
{
|
||||
tempFace = face->next;
|
||||
_pico_free( face );
|
||||
face = tempFace;
|
||||
}
|
||||
|
||||
( *list ) = NULL;
|
||||
( *tail ) = NULL;
|
||||
}
|
||||
|
||||
/* todo:
|
||||
* - apply material specific uv offsets to uv coordinates
|
||||
*/
|
||||
|
@ -274,7 +235,65 @@ static int _ase_canload( PM_PARAMS_CANLOAD ){
|
|||
return PICO_PMV_OK;
|
||||
}
|
||||
|
||||
typedef struct aseVertex_s aseVertex_t;
|
||||
struct aseVertex_s
|
||||
{
|
||||
picoVec3_t xyz;
|
||||
picoVec3_t normal;
|
||||
picoIndex_t id;
|
||||
};
|
||||
|
||||
typedef struct aseTexCoord_s aseTexCoord_t;
|
||||
struct aseTexCoord_s
|
||||
{
|
||||
picoVec2_t texcoord;
|
||||
};
|
||||
|
||||
typedef struct aseColor_s aseColor_t;
|
||||
struct aseColor_s
|
||||
{
|
||||
picoColor_t color;
|
||||
};
|
||||
|
||||
typedef struct aseFace_s aseFace_t;
|
||||
struct aseFace_s
|
||||
{
|
||||
picoIndex_t indices[9];
|
||||
picoIndex_t smoothingGroup;
|
||||
picoIndex_t materialId;
|
||||
picoIndex_t subMaterialId;
|
||||
};
|
||||
typedef aseFace_t* aseFacesIter_t;
|
||||
|
||||
picoSurface_t* PicoModelFindOrAddSurface( picoModel_t *model, picoShader_t* shader ){
|
||||
/* see if a surface already has the shader */
|
||||
int i = 0;
|
||||
for ( ; i < model->numSurfaces ; i++ )
|
||||
{
|
||||
picoSurface_t* workSurface = model->surface[i];
|
||||
if ( workSurface->shader == shader ) {
|
||||
return workSurface;
|
||||
}
|
||||
}
|
||||
|
||||
/* no surface uses this shader yet, so create a new surface */
|
||||
|
||||
{
|
||||
/* create a new surface in the model for the unique shader */
|
||||
picoSurface_t* workSurface = PicoNewSurface( model );
|
||||
if ( !workSurface ) {
|
||||
_pico_printf( PICO_ERROR, "Could not allocate a new surface!\n" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* do surface setup */
|
||||
PicoSetSurfaceType( workSurface, PICO_TRIANGLES );
|
||||
PicoSetSurfaceName( workSurface, shader->name );
|
||||
PicoSetSurfaceShader( workSurface, shader );
|
||||
|
||||
return workSurface;
|
||||
}
|
||||
}
|
||||
|
||||
/* _ase_submit_triangles - jhefty
|
||||
use the surface and the current face list to look up material/submaterial IDs
|
||||
|
@ -286,65 +305,199 @@ static int _ase_canload( PM_PARAMS_CANLOAD ){
|
|||
indexes 6 7 8 = color indexes (new)
|
||||
*/
|
||||
|
||||
static void _ase_submit_triangles( picoSurface_t* surface, picoModel_t* model, aseMaterial_t* materials, aseFace_t* faces ){
|
||||
aseFace_t* face;
|
||||
aseSubMaterial_t* subMtl;
|
||||
picoVec3_t* xyz[3];
|
||||
picoVec3_t* normal[3];
|
||||
picoVec2_t* st[3];
|
||||
picoColor_t* color[3];
|
||||
int i;
|
||||
#if 0
|
||||
typedef picoIndex_t* picoIndexIter_t;
|
||||
|
||||
face = faces;
|
||||
while ( face != NULL )
|
||||
typedef struct aseUniqueIndices_s aseUniqueIndices_t;
|
||||
struct aseUniqueIndices_s
|
||||
{
|
||||
picoIndex_t* data;
|
||||
picoIndex_t* last;
|
||||
|
||||
aseFace_t* faces;
|
||||
};
|
||||
|
||||
size_t aseUniqueIndices_size( aseUniqueIndices_t* self ) {
|
||||
return self->last - self->data;
|
||||
}
|
||||
|
||||
void aseUniqueIndices_reserve( aseUniqueIndices_t* self, picoIndex_t size ) {
|
||||
self->data = self->last = (picoIndex_t*)_pico_calloc( size, sizeof( picoIndex_t ) );
|
||||
}
|
||||
|
||||
void aseUniqueIndices_clear( aseUniqueIndices_t* self ) {
|
||||
_pico_free( self->data );
|
||||
}
|
||||
|
||||
void aseUniqueIndices_pushBack( aseUniqueIndices_t* self, picoIndex_t index ) {
|
||||
*self->last++ = index;
|
||||
}
|
||||
|
||||
picoIndex_t aseFaces_getVertexIndex( aseFace_t* faces, picoIndex_t index ) {
|
||||
return faces[index / 3].indices[index % 3];
|
||||
}
|
||||
|
||||
picoIndex_t aseFaces_getTexCoordIndex( aseFace_t* faces, picoIndex_t index ) {
|
||||
return faces[index / 3].indices[( index % 3 ) + 3];
|
||||
}
|
||||
|
||||
picoIndex_t aseFaces_getColorIndex( aseFace_t* faces, picoIndex_t index ) {
|
||||
return faces[index / 3].indices[( index % 3 ) + 6];
|
||||
}
|
||||
|
||||
int aseUniqueIndex_equal( aseFace_t* faces, picoIndex_t index, picoIndex_t other ) {
|
||||
return aseFaces_getVertexIndex( faces, index ) == aseFaces_getVertexIndex( faces, other )
|
||||
&& aseFaces_getTexCoordIndex( faces, index ) == aseFaces_getTexCoordIndex( faces, other )
|
||||
&& aseFaces_getColorIndex( faces, index ) == aseFaces_getColorIndex( faces, other );
|
||||
}
|
||||
|
||||
picoIndex_t aseUniqueIndices_insertUniqueVertex( aseUniqueIndices_t* self, picoIndex_t index ) {
|
||||
picoIndexIter_t i = self->data;
|
||||
for (; i != self->last; ++i )
|
||||
{
|
||||
picoIndex_t other = (picoIndex_t)( i - self->data );
|
||||
if ( aseUniqueIndex_equal( self->faces, index, other ) ) {
|
||||
return other;
|
||||
}
|
||||
}
|
||||
|
||||
aseUniqueIndices_pushBack( self, index );
|
||||
return (picoIndex_t)( aseUniqueIndices_size( self ) - 1 );
|
||||
}
|
||||
|
||||
static void _ase_submit_triangles_unshared( picoModel_t* model, aseMaterial_t* materials, aseVertex_t* vertices, aseTexCoord_t* texcoords, aseColor_t* colors, aseFace_t* faces, int numFaces, int meshHasNormals ) {
|
||||
aseFacesIter_t i = faces, end = faces + numFaces;
|
||||
|
||||
aseUniqueIndices_t indices;
|
||||
aseUniqueIndices_t remap;
|
||||
aseUniqueIndices_reserve( &indices, numFaces * 3 );
|
||||
aseUniqueIndices_reserve( &remap, numFaces * 3 );
|
||||
indices.faces = faces;
|
||||
|
||||
for (; i != end; ++i )
|
||||
{
|
||||
/* look up the shader for the material/submaterial pair */
|
||||
subMtl = _ase_get_submaterial( materials, face->mtlId, face->subMtlId );
|
||||
aseSubMaterial_t* subMtl = _ase_get_submaterial_or_default( materials, ( *i ).materialId, ( *i ).subMaterialId );
|
||||
if ( subMtl == NULL ) {
|
||||
/* ydnar: trying default submaterial */
|
||||
subMtl = _ase_get_submaterial( materials, face->mtlId, 0 );
|
||||
if ( subMtl == NULL ) {
|
||||
_pico_printf( PICO_ERROR, "Could not find material/submaterial for id %d/%d\n", face->mtlId, face->subMtlId );
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* we pull the data from the surface using the facelist data */
|
||||
for ( i = 0 ; i < 3 ; i++ )
|
||||
{
|
||||
xyz[i] = (picoVec3_t*) PicoGetSurfaceXYZ( surface, face->index[ i ] );
|
||||
normal[i] = (picoVec3_t*) PicoGetSurfaceNormal( surface, face->index[ i ] );
|
||||
st[i] = (picoVec2_t*) PicoGetSurfaceST( surface, 0, face->index[ i + 3 ] );
|
||||
|
||||
if ( face->index [ i + 6] >= 0 ) {
|
||||
color[i] = (picoColor_t*)PicoGetSurfaceColor( surface, 0, face->index[ i + 6 ] );
|
||||
}
|
||||
else
|
||||
picoSurface_t* surface = PicoModelFindOrAddSurface( model, subMtl->shader );
|
||||
int j;
|
||||
/* we pull the data from the vertex, color and texcoord arrays using the face index data */
|
||||
for ( j = 0 ; j < 3 ; j++ )
|
||||
{
|
||||
color[i] = &white;
|
||||
}
|
||||
picoIndex_t index = (picoIndex_t)( ( ( i - faces ) * 3 ) + j );
|
||||
picoIndex_t size = (picoIndex_t)aseUniqueIndices_size( &indices );
|
||||
picoIndex_t unique = aseUniqueIndices_insertUniqueVertex( &indices, index );
|
||||
|
||||
picoIndex_t numVertexes = PicoGetSurfaceNumVertexes( surface );
|
||||
picoIndex_t numIndexes = PicoGetSurfaceNumIndexes( surface );
|
||||
|
||||
aseUniqueIndices_pushBack( &remap, numIndexes );
|
||||
|
||||
PicoSetSurfaceIndex( surface, numIndexes, remap.data[unique] );
|
||||
|
||||
if ( unique == size ) {
|
||||
PicoSetSurfaceXYZ( surface, numVertexes, vertices[( *i ).indices[j]].xyz );
|
||||
PicoSetSurfaceNormal( surface, numVertexes, vertices[( *i ).indices[j]].normal );
|
||||
PicoSetSurfaceST( surface, 0, numVertexes, texcoords[( *i ).indices[j + 3]].texcoord );
|
||||
|
||||
if ( ( *i ).indices[j + 6] >= 0 ) {
|
||||
PicoSetSurfaceColor( surface, 0, numVertexes, colors[( *i ).indices[j + 6]].color );
|
||||
}
|
||||
else
|
||||
{
|
||||
PicoSetSurfaceColor( surface, 0, numVertexes, white );
|
||||
}
|
||||
|
||||
PicoSetSurfaceSmoothingGroup( surface, numVertexes, ( vertices[( *i ).indices[j]].id * ( 1 << 16 ) ) + ( *i ).smoothingGroup );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
aseUniqueIndices_clear( &indices );
|
||||
aseUniqueIndices_clear( &remap );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void _ase_submit_triangles( picoModel_t* model, aseMaterial_t* materials, aseVertex_t* vertices, aseTexCoord_t* texcoords, aseColor_t* colors, aseFace_t* faces, int numFaces ){
|
||||
aseFacesIter_t i = faces, end = faces + numFaces;
|
||||
for (; i != end; ++i )
|
||||
{
|
||||
/* look up the shader for the material/submaterial pair */
|
||||
aseSubMaterial_t* subMtl = _ase_get_submaterial_or_default( materials, ( *i ).materialId, ( *i ).subMaterialId );
|
||||
if ( subMtl == NULL ) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* submit the triangle to the model */
|
||||
PicoAddTriangleToModel( model, xyz, normal, 1, st, 1, color, subMtl->shader );
|
||||
{
|
||||
picoVec3_t* xyz[3];
|
||||
picoVec3_t* normal[3];
|
||||
picoVec2_t* st[3];
|
||||
picoColor_t* color[3];
|
||||
picoIndex_t smooth[3];
|
||||
int j;
|
||||
/* we pull the data from the vertex, color and texcoord arrays using the face index data */
|
||||
for ( j = 0 ; j < 3 ; j++ )
|
||||
{
|
||||
xyz[j] = &vertices[( *i ).indices[j]].xyz;
|
||||
normal[j] = &vertices[( *i ).indices[j]].normal;
|
||||
st[j] = &texcoords[( *i ).indices[j + 3]].texcoord;
|
||||
|
||||
/* advance to the next face */
|
||||
face = face->next;
|
||||
if ( colors != NULL && ( *i ).indices[j + 6] >= 0 ) {
|
||||
color[j] = &colors[( *i ).indices[j + 6]].color;
|
||||
}
|
||||
else
|
||||
{
|
||||
color[j] = &white;
|
||||
}
|
||||
|
||||
smooth[j] = ( vertices[( *i ).indices[j]].id * ( 1 << 16 ) ) + ( *i ).smoothingGroup; /* don't merge vertices */
|
||||
|
||||
}
|
||||
|
||||
/* submit the triangle to the model */
|
||||
PicoAddTriangleToModel( model, xyz, normal, 1, st, 1, color, subMtl->shader, smooth );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void shadername_convert( char* shaderName ){
|
||||
/* unix-style path separators */
|
||||
char* s = shaderName;
|
||||
for (; *s != '\0'; ++s )
|
||||
{
|
||||
if ( *s == '\\' ) {
|
||||
*s = '/';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* _ase_load:
|
||||
* loads a 3dsmax ase model file.
|
||||
*/
|
||||
static picoModel_t *_ase_load( PM_PARAMS_LOAD ){
|
||||
picoModel_t *model;
|
||||
picoSurface_t *surface = NULL;
|
||||
picoParser_t *p;
|
||||
char lastNodeName[ 1024 ];
|
||||
|
||||
aseVertex_t* vertices = NULL;
|
||||
aseTexCoord_t* texcoords = NULL;
|
||||
aseColor_t* colors = NULL;
|
||||
aseFace_t* faces = NULL;
|
||||
aseFace_t* facesTail = NULL;
|
||||
int numVertices = 0;
|
||||
int numFaces = 0;
|
||||
int numTextureVertices = 0;
|
||||
int numTextureVertexFaces = 0;
|
||||
int numColorVertices = 0;
|
||||
int numColorVertexFaces = 0;
|
||||
int vertexId = 0;
|
||||
|
||||
aseMaterial_t* materials = NULL;
|
||||
|
||||
#ifdef DEBUG_PM_ASE
|
||||
|
@ -357,8 +510,8 @@ static picoModel_t *_ase_load( PM_PARAMS_LOAD ){
|
|||
#define _ase_error_return( m ) \
|
||||
{ \
|
||||
_pico_printf( PICO_ERROR,"%s in ASE, line %d.",m,p->curLine ); \
|
||||
_pico_free_parser( p ); \
|
||||
PicoFreeModel( model ); \
|
||||
_pico_free_parser( p ); \
|
||||
PicoFreeModel( model ); \
|
||||
return NULL; \
|
||||
}
|
||||
/* create a new pico parser */
|
||||
|
@ -413,15 +566,49 @@ static picoModel_t *_ase_load( PM_PARAMS_LOAD ){
|
|||
/* model mesh (originally contained within geomobject) */
|
||||
else if ( !_pico_stricmp( p->token,"*mesh" ) ) {
|
||||
/* finish existing surface */
|
||||
//_ase_make_surface( model, &surface );
|
||||
_ase_submit_triangles( surface, model,materials,faces );
|
||||
_ase_free_faces( &faces,&facesTail );
|
||||
_ase_submit_triangles( model, materials, vertices, texcoords, colors, faces, numFaces );
|
||||
_pico_free( faces );
|
||||
_pico_free( vertices );
|
||||
_pico_free( texcoords );
|
||||
_pico_free( colors );
|
||||
}
|
||||
else if ( !_pico_stricmp( p->token,"*mesh_numvertex" ) ) {
|
||||
if ( !_pico_parse_int( p, &numVertices ) ) {
|
||||
_ase_error_return( "Missing MESH_NUMVERTEX value" );
|
||||
}
|
||||
|
||||
/* allocate new pico surface */
|
||||
surface = PicoNewSurface( NULL );
|
||||
if ( surface == NULL ) {
|
||||
PicoFreeModel( model );
|
||||
return NULL;
|
||||
vertices = _pico_calloc( numVertices, sizeof( aseVertex_t ) );
|
||||
}
|
||||
else if ( !_pico_stricmp( p->token,"*mesh_numfaces" ) ) {
|
||||
if ( !_pico_parse_int( p, &numFaces ) ) {
|
||||
_ase_error_return( "Missing MESH_NUMFACES value" );
|
||||
}
|
||||
|
||||
faces = _pico_calloc( numFaces, sizeof( aseFace_t ) );
|
||||
}
|
||||
else if ( !_pico_stricmp( p->token,"*mesh_numtvertex" ) ) {
|
||||
if ( !_pico_parse_int( p, &numTextureVertices ) ) {
|
||||
_ase_error_return( "Missing MESH_NUMTVERTEX value" );
|
||||
}
|
||||
|
||||
texcoords = _pico_calloc( numTextureVertices, sizeof( aseTexCoord_t ) );
|
||||
}
|
||||
else if ( !_pico_stricmp( p->token,"*mesh_numtvfaces" ) ) {
|
||||
if ( !_pico_parse_int( p, &numTextureVertexFaces ) ) {
|
||||
_ase_error_return( "Missing MESH_NUMTVFACES value" );
|
||||
}
|
||||
}
|
||||
else if ( !_pico_stricmp( p->token,"*mesh_numcvertex" ) ) {
|
||||
if ( !_pico_parse_int( p, &numColorVertices ) ) {
|
||||
_ase_error_return( "Missing MESH_NUMCVERTEX value" );
|
||||
}
|
||||
|
||||
colors = _pico_calloc( numColorVertices, sizeof( aseColor_t ) );
|
||||
memset( colors, 255, numColorVertices * sizeof( aseColor_t ) ); /* ydnar: force colors to white initially */
|
||||
}
|
||||
else if ( !_pico_stricmp( p->token,"*mesh_numcvfaces" ) ) {
|
||||
if ( !_pico_parse_int( p, &numColorVertexFaces ) ) {
|
||||
_ase_error_return( "Missing MESH_NUMCVFACES value" );
|
||||
}
|
||||
}
|
||||
/* mesh material reference. this usually comes at the end of */
|
||||
|
@ -430,77 +617,63 @@ static picoModel_t *_ase_load( PM_PARAMS_LOAD ){
|
|||
/* the material reference id (shader index) now. */
|
||||
else if ( !_pico_stricmp( p->token,"*material_ref" ) ) {
|
||||
int mtlId;
|
||||
aseFace_t* face;
|
||||
|
||||
/* we must have a valid surface */
|
||||
if ( surface == NULL ) {
|
||||
_ase_error_return( "Missing mesh for material reference" );
|
||||
}
|
||||
|
||||
/* get the material ref (0..n) */
|
||||
if ( !_pico_parse_int( p,&mtlId ) ) {
|
||||
_ase_error_return( "Missing material reference ID" );
|
||||
}
|
||||
|
||||
/* fix up all of the aseFaceList in the surface to point to the parent material */
|
||||
/* we've already saved off their subMtl */
|
||||
face = faces;
|
||||
while ( face != NULL )
|
||||
{
|
||||
face->mtlId = mtlId;
|
||||
face = face->next;
|
||||
int i = 0;
|
||||
/* fix up all of the aseFaceList in the surface to point to the parent material */
|
||||
/* we've already saved off their subMtl */
|
||||
for (; i < numFaces; ++i )
|
||||
{
|
||||
faces[i].materialId = mtlId;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* model mesh vertex */
|
||||
else if ( !_pico_stricmp( p->token,"*mesh_vertex" ) ) {
|
||||
picoVec3_t v;
|
||||
int index;
|
||||
|
||||
/* we must have a valid surface */
|
||||
if ( surface == NULL ) {
|
||||
continue;
|
||||
if ( numVertices == 0 ) {
|
||||
_ase_error_return( "Vertex parse error" );
|
||||
}
|
||||
|
||||
/* get vertex data (orig: index +y -x +z) */
|
||||
if ( !_pico_parse_int( p,&index ) ) {
|
||||
_ase_error_return( "Vertex parse error" );
|
||||
}
|
||||
if ( !_pico_parse_vec( p,v ) ) {
|
||||
if ( !_pico_parse_vec( p,vertices[index].xyz ) ) {
|
||||
_ase_error_return( "Vertex parse error" );
|
||||
}
|
||||
|
||||
/* set vertex */
|
||||
PicoSetSurfaceXYZ( surface,index,v );
|
||||
vertices[index].id = vertexId++;
|
||||
}
|
||||
/* model mesh vertex normal */
|
||||
else if ( !_pico_stricmp( p->token,"*mesh_vertexnormal" ) ) {
|
||||
picoVec3_t v;
|
||||
int index;
|
||||
|
||||
/* we must have a valid surface */
|
||||
if ( surface == NULL ) {
|
||||
continue;
|
||||
if ( numVertices == 0 ) {
|
||||
_ase_error_return( "Vertex parse error" );
|
||||
}
|
||||
|
||||
/* get vertex data (orig: index +y -x +z) */
|
||||
if ( !_pico_parse_int( p,&index ) ) {
|
||||
_ase_error_return( "Vertex parse error" );
|
||||
}
|
||||
if ( !_pico_parse_vec( p,v ) ) {
|
||||
if ( !_pico_parse_vec( p,vertices[index].normal ) ) {
|
||||
_ase_error_return( "Vertex parse error" );
|
||||
}
|
||||
|
||||
/* set vertex */
|
||||
PicoSetSurfaceNormal( surface,index,v );
|
||||
}
|
||||
/* model mesh face */
|
||||
else if ( !_pico_stricmp( p->token,"*mesh_face" ) ) {
|
||||
picoIndex_t indexes[3];
|
||||
int index;
|
||||
|
||||
/* we must have a valid surface */
|
||||
if ( surface == NULL ) {
|
||||
continue;
|
||||
if ( numFaces == 0 ) {
|
||||
_ase_error_return( "Face parse error" );
|
||||
}
|
||||
|
||||
/* get face index */
|
||||
|
@ -526,75 +699,58 @@ static picoModel_t *_ase_load( PM_PARAMS_LOAD ){
|
|||
_ase_error_return( "Face parse error" );
|
||||
}
|
||||
|
||||
/* set face indexes (note interleaved offset!) */
|
||||
PicoSetSurfaceIndex( surface, ( index * 9 + 0 ), indexes[2] );
|
||||
PicoSetSurfaceIndex( surface, ( index * 9 + 1 ), indexes[1] );
|
||||
PicoSetSurfaceIndex( surface, ( index * 9 + 2 ), indexes[0] );
|
||||
|
||||
/* parse to the subMaterial ID */
|
||||
while ( 1 )
|
||||
{
|
||||
_pico_parse( p,0 );
|
||||
if ( !_pico_stricmp( p->token,"*MESH_MTLID" ) ) {
|
||||
aseFace_t* newFace;
|
||||
int subMtlId;
|
||||
|
||||
_pico_parse_int( p, &subMtlId );
|
||||
newFace = _pico_calloc( 1, sizeof( aseFace_t ) );
|
||||
|
||||
/* we fix up the mtlId later when we parse the material_ref */
|
||||
newFace->mtlId = 0;
|
||||
newFace->subMtlId = subMtlId;
|
||||
newFace->index[0] = indexes[2];
|
||||
newFace->index[1] = indexes[1];
|
||||
newFace->index[2] = indexes[0];
|
||||
|
||||
_ase_add_face( &faces,&facesTail,newFace );
|
||||
if ( !_pico_parse( p,0 ) ) { /* EOL */
|
||||
break;
|
||||
}
|
||||
if ( !_pico_stricmp( p->token,"*MESH_SMOOTHING" ) ) {
|
||||
_pico_parse_int( p, &faces[index].smoothingGroup );
|
||||
}
|
||||
if ( !_pico_stricmp( p->token,"*MESH_MTLID" ) ) {
|
||||
_pico_parse_int( p, &faces[index].subMaterialId );
|
||||
}
|
||||
}
|
||||
|
||||
faces[index].materialId = 0;
|
||||
faces[index].indices[0] = indexes[2];
|
||||
faces[index].indices[1] = indexes[1];
|
||||
faces[index].indices[2] = indexes[0];
|
||||
}
|
||||
/* model texture vertex */
|
||||
else if ( !_pico_stricmp( p->token,"*mesh_tvert" ) ) {
|
||||
picoVec2_t uv;
|
||||
int index;
|
||||
|
||||
/* we must have a valid surface */
|
||||
if ( surface == NULL ) {
|
||||
continue;
|
||||
if ( numVertices == 0 ) {
|
||||
_ase_error_return( "Texture Vertex parse error" );
|
||||
}
|
||||
|
||||
/* get uv vertex index */
|
||||
if ( !_pico_parse_int( p,&index ) ) {
|
||||
_ase_error_return( "UV vertex parse error" );
|
||||
if ( !_pico_parse_int( p,&index ) || index >= numTextureVertices ) {
|
||||
_ase_error_return( "Texture vertex parse error" );
|
||||
}
|
||||
|
||||
/* get uv vertex s */
|
||||
if ( !_pico_parse_float( p,&uv[0] ) ) {
|
||||
_ase_error_return( "UV vertex parse error" );
|
||||
if ( !_pico_parse_float( p,&texcoords[index].texcoord[0] ) ) {
|
||||
_ase_error_return( "Texture vertex parse error" );
|
||||
}
|
||||
|
||||
/* get uv vertex t */
|
||||
if ( !_pico_parse_float( p,&uv[1] ) ) {
|
||||
_ase_error_return( "UV vertex parse error" );
|
||||
if ( !_pico_parse_float( p,&texcoords[index].texcoord[1] ) ) {
|
||||
_ase_error_return( "Texture vertex parse error" );
|
||||
}
|
||||
|
||||
/* ydnar: invert t */
|
||||
uv[ 1 ] = 1.0f - uv[ 1 ];
|
||||
|
||||
/* set texture vertex */
|
||||
PicoSetSurfaceST( surface,0,index,uv );
|
||||
texcoords[index].texcoord[ 1 ] = 1.0f - texcoords[index].texcoord[ 1 ];
|
||||
}
|
||||
/* ydnar: model mesh texture face */
|
||||
else if ( !_pico_stricmp( p->token, "*mesh_tface" ) ) {
|
||||
picoIndex_t indexes[3];
|
||||
int index;
|
||||
aseFace_t* face;
|
||||
|
||||
/* we must have a valid surface */
|
||||
if ( surface == NULL ) {
|
||||
continue;
|
||||
if ( numFaces == 0 ) {
|
||||
_ase_error_return( "Texture face parse error" );
|
||||
}
|
||||
|
||||
/* get face index */
|
||||
|
@ -617,65 +773,52 @@ static picoModel_t *_ase_load( PM_PARAMS_LOAD ){
|
|||
_ase_error_return( "Texture face parse error" );
|
||||
}
|
||||
|
||||
/* set face indexes (note interleaved offset!) */
|
||||
PicoSetSurfaceIndex( surface, ( index * 9 + 3 ), indexes[2] );
|
||||
PicoSetSurfaceIndex( surface, ( index * 9 + 4 ), indexes[1] );
|
||||
PicoSetSurfaceIndex( surface, ( index * 9 + 5 ), indexes[0] );
|
||||
|
||||
face = _ase_get_face_for_index( faces,index );
|
||||
face->index[3] = indexes[2];
|
||||
face->index[4] = indexes[1];
|
||||
face->index[5] = indexes[0];
|
||||
faces[index].indices[3] = indexes[2];
|
||||
faces[index].indices[4] = indexes[1];
|
||||
faces[index].indices[5] = indexes[0];
|
||||
}
|
||||
/* model color vertex */
|
||||
else if ( !_pico_stricmp( p->token,"*mesh_vertcol" ) ) {
|
||||
picoColor_t color;
|
||||
int index;
|
||||
float colorInput;
|
||||
|
||||
/* we must have a valid surface */
|
||||
if ( surface == NULL ) {
|
||||
continue;
|
||||
if ( numVertices == 0 ) {
|
||||
_ase_error_return( "Color Vertex parse error" );
|
||||
}
|
||||
|
||||
/* get color vertex index */
|
||||
if ( !_pico_parse_int( p,&index ) ) {
|
||||
_ase_error_return( "UV vertex parse error" );
|
||||
_ase_error_return( "Color vertex parse error" );
|
||||
}
|
||||
|
||||
/* get R component */
|
||||
if ( !_pico_parse_float( p,&colorInput ) ) {
|
||||
_ase_error_return( "color vertex parse error" );
|
||||
_ase_error_return( "Color vertex parse error" );
|
||||
}
|
||||
color[0] = (picoByte_t)( colorInput * 255 );
|
||||
colors[index].color[0] = (picoByte_t)( colorInput * 255 );
|
||||
|
||||
/* get G component */
|
||||
if ( !_pico_parse_float( p,&colorInput ) ) {
|
||||
_ase_error_return( "color vertex parse error" );
|
||||
_ase_error_return( "Color vertex parse error" );
|
||||
}
|
||||
color[1] = (picoByte_t)( colorInput * 255 );
|
||||
colors[index].color[1] = (picoByte_t)( colorInput * 255 );
|
||||
|
||||
/* get B component */
|
||||
if ( !_pico_parse_float( p,&colorInput ) ) {
|
||||
_ase_error_return( "color vertex parse error" );
|
||||
_ase_error_return( "Color vertex parse error" );
|
||||
}
|
||||
color[2] = (picoByte_t)( colorInput * 255 );
|
||||
colors[index].color[2] = (picoByte_t)( colorInput * 255 );
|
||||
|
||||
/* leave alpha alone since we don't get any data from the ASE format */
|
||||
color[3] = 255;
|
||||
|
||||
/* set texture vertex */
|
||||
PicoSetSurfaceColor( surface,0,index,color );
|
||||
colors[index].color[3] = 255;
|
||||
}
|
||||
/* model color face */
|
||||
else if ( !_pico_stricmp( p->token,"*mesh_cface" ) ) {
|
||||
picoIndex_t indexes[3];
|
||||
int index;
|
||||
aseFace_t* face;
|
||||
|
||||
/* we must have a valid surface */
|
||||
if ( surface == NULL ) {
|
||||
continue;
|
||||
if ( numFaces == 0 ) {
|
||||
_ase_error_return( "Face parse error" );
|
||||
}
|
||||
|
||||
/* get face index */
|
||||
|
@ -701,20 +844,14 @@ static picoModel_t *_ase_load( PM_PARAMS_LOAD ){
|
|||
_ase_error_return( "Face parse error" );
|
||||
}
|
||||
|
||||
/* set face indexes (note interleaved offset!) */
|
||||
PicoSetSurfaceIndex( surface, ( index * 9 + 6 ), indexes[2] );
|
||||
PicoSetSurfaceIndex( surface, ( index * 9 + 7 ), indexes[1] );
|
||||
PicoSetSurfaceIndex( surface, ( index * 9 + 8 ), indexes[0] );
|
||||
|
||||
face = _ase_get_face_for_index( faces,index );
|
||||
face->index[6] = indexes[2];
|
||||
face->index[7] = indexes[1];
|
||||
face->index[8] = indexes[0];
|
||||
faces[index].indices[6] = indexes[2];
|
||||
faces[index].indices[7] = indexes[1];
|
||||
faces[index].indices[8] = indexes[0];
|
||||
}
|
||||
/* model material */
|
||||
else if ( !_pico_stricmp( p->token, "*material" ) ) {
|
||||
aseSubMaterial_t* subMaterial = NULL;
|
||||
picoShader_t *shader = NULL;
|
||||
picoShader_t *shader;
|
||||
int level = 1, index;
|
||||
char materialName[ 1024 ];
|
||||
float transValue = 0.0f, shineValue = 1.0f;
|
||||
|
@ -755,6 +892,8 @@ static picoModel_t *_ase_load( PM_PARAMS_LOAD ){
|
|||
|
||||
if ( level == subMaterialLevel ) {
|
||||
/* set material name */
|
||||
_pico_first_token( materialName );
|
||||
shadername_convert( materialName );
|
||||
PicoSetShaderName( shader, materialName );
|
||||
|
||||
/* set shader's transparency */
|
||||
|
@ -944,6 +1083,7 @@ static picoModel_t *_ase_load( PM_PARAMS_LOAD ){
|
|||
}
|
||||
|
||||
/* set material name */
|
||||
shadername_convert( materialName );
|
||||
PicoSetShaderName( shader,materialName );
|
||||
|
||||
/* set shader's transparency */
|
||||
|
@ -967,6 +1107,34 @@ static picoModel_t *_ase_load( PM_PARAMS_LOAD ){
|
|||
/* set material map name */
|
||||
PicoSetShaderMapName( shader, mapname );
|
||||
|
||||
/* extract shadername from bitmap path */
|
||||
if ( mapname != NULL ) {
|
||||
char* p = mapname;
|
||||
|
||||
/* convert to shader-name format */
|
||||
shadername_convert( mapname );
|
||||
{
|
||||
/* remove extension */
|
||||
char* last_period = strrchr( p, '.' );
|
||||
if ( last_period != NULL ) {
|
||||
*last_period = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
/* find shader path */
|
||||
for (; *p != '\0'; ++p )
|
||||
{
|
||||
if ( _pico_strnicmp( p, "models/", 7 ) == 0 || _pico_strnicmp( p, "textures/", 9 ) == 0 ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( *p != '\0' ) {
|
||||
/* set material name */
|
||||
PicoSetShaderName( shader,p );
|
||||
}
|
||||
}
|
||||
|
||||
/* this is just a material with 1 submaterial */
|
||||
subMaterial = _ase_add_submaterial( &materials, index, 0, shader );
|
||||
}
|
||||
|
@ -982,9 +1150,11 @@ static picoModel_t *_ase_load( PM_PARAMS_LOAD ){
|
|||
}
|
||||
|
||||
/* ydnar: finish existing surface */
|
||||
// _ase_make_surface( model, &surface );
|
||||
_ase_submit_triangles( surface, model,materials,faces );
|
||||
_ase_free_faces( &faces,&facesTail );
|
||||
_ase_submit_triangles( model, materials, vertices, texcoords, colors, faces, numFaces );
|
||||
_pico_free( faces );
|
||||
_pico_free( vertices );
|
||||
_pico_free( texcoords );
|
||||
_pico_free( colors );
|
||||
|
||||
#ifdef DEBUG_PM_ASE
|
||||
_ase_print_materials( materials );
|
||||
|
@ -995,6 +1165,8 @@ static picoModel_t *_ase_load( PM_PARAMS_LOAD ){
|
|||
|
||||
_ase_free_materials( &materials );
|
||||
|
||||
_pico_free_parser( p );
|
||||
|
||||
/* return allocated pico model */
|
||||
return model;
|
||||
}
|
||||
|
|
|
@ -350,7 +350,7 @@ static picoModel_t *_fm_load( PM_PARAMS_LOAD ){
|
|||
texCoord->t = _pico_little_short( texCoord[i].t );
|
||||
}
|
||||
// set Skin Name
|
||||
strncpy( skinname, (char *) fm.fm_skin, FM_SKINPATHSIZE );
|
||||
strncpy( skinname, (unsigned char *) fm.fm_skin, FM_SKINPATHSIZE );
|
||||
|
||||
#ifdef FM_VERBOSE_DBG
|
||||
// Print out md2 values
|
||||
|
|
|
@ -103,7 +103,7 @@ static picoModel_t *_lwo_load( PM_PARAMS_LOAD ){
|
|||
lwPolygon *pol;
|
||||
lwPolVert *v;
|
||||
lwVMapPt *vm;
|
||||
char name[ 64 ];
|
||||
char name[ 256 ];
|
||||
int i, j, k, numverts;
|
||||
|
||||
picoModel_t *picoModel;
|
||||
|
@ -235,6 +235,7 @@ static picoModel_t *_lwo_load( PM_PARAMS_LOAD ){
|
|||
|
||||
/* detox and set shader name */
|
||||
strncpy( name, surface->name, sizeof( name ) );
|
||||
_pico_first_token( name );
|
||||
_pico_setfext( name, "" );
|
||||
_pico_unixify( name );
|
||||
PicoSetShaderName( picoShader, name );
|
||||
|
@ -282,9 +283,22 @@ static picoModel_t *_lwo_load( PM_PARAMS_LOAD ){
|
|||
xyz[ 1 ] = pt->pos[ 2 ];
|
||||
xyz[ 2 ] = pt->pos[ 1 ];
|
||||
|
||||
///* doom3 lwo data doesn't seem to have smoothing-angle information */
|
||||
//#if 0
|
||||
if ( surface->smooth <= 0 ) {
|
||||
/* use face normals */
|
||||
normal[ 0 ] = v->norm[ 0 ];
|
||||
normal[ 1 ] = v->norm[ 2 ];
|
||||
normal[ 2 ] = v->norm[ 1 ];
|
||||
}
|
||||
else
|
||||
//#endif
|
||||
{
|
||||
/* smooth normals later */
|
||||
normal[ 0 ] = 0;
|
||||
normal[ 1 ] = 0;
|
||||
normal[ 2 ] = 0;
|
||||
}
|
||||
|
||||
st[ 0 ] = xyz[ defaultSTAxis[ 0 ] ] * defaultXYZtoSTScale[ 0 ];
|
||||
st[ 1 ] = xyz[ defaultSTAxis[ 1 ] ] * defaultXYZtoSTScale[ 1 ];
|
||||
|
|
|
@ -241,7 +241,7 @@ static int _obj_mtl_load( picoModel_t *model ){
|
|||
return 0; \
|
||||
}
|
||||
/* alloc copy of model file name */
|
||||
fileName = _pico_clone_alloc( model->fileName,-1 );
|
||||
fileName = _pico_clone_alloc( model->fileName );
|
||||
if ( fileName == NULL ) {
|
||||
return 0;
|
||||
}
|
||||
|
|
607
libs/picomodel/pm_terrain.c
Normal file
607
libs/picomodel/pm_terrain.c
Normal file
|
@ -0,0 +1,607 @@
|
|||
/* -----------------------------------------------------------------------------
|
||||
|
||||
PicoModel Library
|
||||
|
||||
Copyright (c) 2003, Randy Reddig & seaw0lf
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
Neither the names of the copyright holders nor the names of its contributors may
|
||||
be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
|
||||
/* marker */
|
||||
#define PM_TERRAIN_C
|
||||
|
||||
|
||||
|
||||
/* dependencies */
|
||||
#include "picointernal.h"
|
||||
|
||||
|
||||
|
||||
typedef struct tga_s
|
||||
{
|
||||
unsigned char id_length, colormap_type, image_type;
|
||||
unsigned short colormap_index, colormap_length;
|
||||
unsigned char colormap_size;
|
||||
unsigned short x_origin, y_origin, width, height;
|
||||
unsigned char pixel_size, attributes;
|
||||
}
|
||||
tga_t;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
_terrain_load_tga_buffer()
|
||||
loads a tga image into a newly allocated image buffer
|
||||
fixme: replace/clean this function
|
||||
*/
|
||||
|
||||
void _terrain_load_tga_buffer( unsigned char *buffer, unsigned char **pic, int *width, int *height ) {
|
||||
int row, column;
|
||||
int columns, rows, numPixels;
|
||||
unsigned char *pixbuf;
|
||||
unsigned char *buf_p;
|
||||
tga_t targa_header;
|
||||
unsigned char *targa_rgba;
|
||||
|
||||
|
||||
*pic = NULL;
|
||||
|
||||
if ( buffer == NULL ) {
|
||||
return;
|
||||
}
|
||||
|
||||
buf_p = buffer;
|
||||
|
||||
targa_header.id_length = *buf_p++;
|
||||
targa_header.colormap_type = *buf_p++;
|
||||
targa_header.image_type = *buf_p++;
|
||||
|
||||
targa_header.colormap_index = _pico_little_short( *(short*)buf_p );
|
||||
buf_p += 2;
|
||||
targa_header.colormap_length = _pico_little_short( *(short*) buf_p );
|
||||
buf_p += 2;
|
||||
targa_header.colormap_size = *buf_p++;
|
||||
targa_header.x_origin = _pico_little_short( *(short*) buf_p );
|
||||
buf_p += 2;
|
||||
targa_header.y_origin = _pico_little_short( *(short*) buf_p );
|
||||
buf_p += 2;
|
||||
targa_header.width = _pico_little_short( *(short*) buf_p );
|
||||
buf_p += 2;
|
||||
targa_header.height = _pico_little_short( *(short*) buf_p );
|
||||
buf_p += 2;
|
||||
targa_header.pixel_size = *buf_p++;
|
||||
targa_header.attributes = *buf_p++;
|
||||
|
||||
if ( targa_header.image_type != 2 && targa_header.image_type != 10 && targa_header.image_type != 3 ) {
|
||||
_pico_printf( PICO_ERROR, "Only type 2 (RGB), 3 (gray), and 10 (RGB) TGA images supported\n" );
|
||||
pic = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
if ( targa_header.colormap_type != 0 ) {
|
||||
_pico_printf( PICO_ERROR, "Indexed color TGA images not supported\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( targa_header.pixel_size != 32 && targa_header.pixel_size != 24 && targa_header.image_type != 3 ) {
|
||||
_pico_printf( PICO_ERROR, "Only 32 or 24 bit TGA images supported (not indexed color)\n" );
|
||||
pic = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
columns = targa_header.width;
|
||||
rows = targa_header.height;
|
||||
numPixels = columns * rows;
|
||||
|
||||
if ( width ) {
|
||||
*width = columns;
|
||||
}
|
||||
if ( height ) {
|
||||
*height = rows;
|
||||
}
|
||||
|
||||
targa_rgba = _pico_alloc( numPixels * 4 );
|
||||
*pic = targa_rgba;
|
||||
|
||||
if ( targa_header.id_length != 0 ) {
|
||||
buf_p += targa_header.id_length; // skip TARGA image comment
|
||||
|
||||
}
|
||||
if ( targa_header.image_type == 2 || targa_header.image_type == 3 ) {
|
||||
// Uncompressed RGB or gray scale image
|
||||
for ( row = rows - 1; row >= 0; row-- )
|
||||
{
|
||||
pixbuf = targa_rgba + row * columns * 4;
|
||||
for ( column = 0; column < columns; column++ )
|
||||
{
|
||||
unsigned char red,green,blue,alphabyte;
|
||||
switch ( targa_header.pixel_size )
|
||||
{
|
||||
|
||||
case 8:
|
||||
blue = *buf_p++;
|
||||
green = blue;
|
||||
red = blue;
|
||||
*pixbuf++ = red;
|
||||
*pixbuf++ = green;
|
||||
*pixbuf++ = blue;
|
||||
*pixbuf++ = 255;
|
||||
break;
|
||||
|
||||
case 24:
|
||||
blue = *buf_p++;
|
||||
green = *buf_p++;
|
||||
red = *buf_p++;
|
||||
*pixbuf++ = red;
|
||||
*pixbuf++ = green;
|
||||
*pixbuf++ = blue;
|
||||
*pixbuf++ = 255;
|
||||
break;
|
||||
case 32:
|
||||
blue = *buf_p++;
|
||||
green = *buf_p++;
|
||||
red = *buf_p++;
|
||||
alphabyte = *buf_p++;
|
||||
*pixbuf++ = red;
|
||||
*pixbuf++ = green;
|
||||
*pixbuf++ = blue;
|
||||
*pixbuf++ = alphabyte;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* rle encoded pixels */
|
||||
else if ( targa_header.image_type == 10 ) {
|
||||
unsigned char red,green,blue,alphabyte,packetHeader,packetSize,j;
|
||||
|
||||
red = 0;
|
||||
green = 0;
|
||||
blue = 0;
|
||||
alphabyte = 0xff;
|
||||
|
||||
for ( row = rows - 1; row >= 0; row-- ) {
|
||||
pixbuf = targa_rgba + row * columns * 4;
|
||||
for ( column = 0; column < columns; ) {
|
||||
packetHeader = *buf_p++;
|
||||
packetSize = 1 + ( packetHeader & 0x7f );
|
||||
if ( packetHeader & 0x80 ) { // run-length packet
|
||||
switch ( targa_header.pixel_size ) {
|
||||
case 24:
|
||||
blue = *buf_p++;
|
||||
green = *buf_p++;
|
||||
red = *buf_p++;
|
||||
alphabyte = 255;
|
||||
break;
|
||||
case 32:
|
||||
blue = *buf_p++;
|
||||
green = *buf_p++;
|
||||
red = *buf_p++;
|
||||
alphabyte = *buf_p++;
|
||||
break;
|
||||
default:
|
||||
//Error("LoadTGA: illegal pixel_size '%d' in file '%s'\n", targa_header.pixel_size, name );
|
||||
break;
|
||||
}
|
||||
|
||||
for ( j = 0; j < packetSize; j++ ) {
|
||||
*pixbuf++ = red;
|
||||
*pixbuf++ = green;
|
||||
*pixbuf++ = blue;
|
||||
*pixbuf++ = alphabyte;
|
||||
column++;
|
||||
if ( column == columns ) { // run spans across rows
|
||||
column = 0;
|
||||
if ( row > 0 ) {
|
||||
row--;
|
||||
}
|
||||
else{
|
||||
goto breakOut;
|
||||
}
|
||||
pixbuf = targa_rgba + row * columns * 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
else { // non run-length packet
|
||||
for ( j = 0; j < packetSize; j++ ) {
|
||||
switch ( targa_header.pixel_size ) {
|
||||
case 24:
|
||||
blue = *buf_p++;
|
||||
green = *buf_p++;
|
||||
red = *buf_p++;
|
||||
*pixbuf++ = red;
|
||||
*pixbuf++ = green;
|
||||
*pixbuf++ = blue;
|
||||
*pixbuf++ = 255;
|
||||
break;
|
||||
case 32:
|
||||
blue = *buf_p++;
|
||||
green = *buf_p++;
|
||||
red = *buf_p++;
|
||||
alphabyte = *buf_p++;
|
||||
*pixbuf++ = red;
|
||||
*pixbuf++ = green;
|
||||
*pixbuf++ = blue;
|
||||
*pixbuf++ = alphabyte;
|
||||
break;
|
||||
default:
|
||||
//Sysprintf("LoadTGA: illegal pixel_size '%d' in file '%s'\n", targa_header.pixel_size, name );
|
||||
break;
|
||||
}
|
||||
column++;
|
||||
if ( column == columns ) { // pixel packet run spans across rows
|
||||
column = 0;
|
||||
if ( row > 0 ) {
|
||||
row--;
|
||||
}
|
||||
else{
|
||||
goto breakOut;
|
||||
}
|
||||
pixbuf = targa_rgba + row * columns * 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
breakOut:;
|
||||
}
|
||||
}
|
||||
|
||||
/* fix vertically flipped image */
|
||||
if ( ( targa_header.attributes & ( 1 << 5 ) ) ) {
|
||||
int flip;
|
||||
for ( row = 0; row < .5f * rows; row++ )
|
||||
{
|
||||
for ( column = 0; column < columns; column++ )
|
||||
{
|
||||
flip = *( (int*)targa_rgba + row * columns + column );
|
||||
*( (int*)targa_rgba + row * columns + column ) = *( (int*)targa_rgba + ( ( rows - 1 ) - row ) * columns + column );
|
||||
*( (int*)targa_rgba + ( ( rows - 1 ) - row ) * columns + column ) = flip;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
_terrain_canload()
|
||||
validates a picoterrain file
|
||||
*/
|
||||
|
||||
static int _terrain_canload( PM_PARAMS_CANLOAD ) {
|
||||
picoParser_t *p;
|
||||
|
||||
|
||||
/* keep the friggin compiler happy */
|
||||
*fileName = *fileName;
|
||||
|
||||
/* create pico parser */
|
||||
p = _pico_new_parser( (picoByte_t*) buffer, bufSize );
|
||||
if ( p == NULL ) {
|
||||
return PICO_PMV_ERROR_MEMORY;
|
||||
}
|
||||
|
||||
/* get first token */
|
||||
if ( _pico_parse_first( p ) == NULL ) {
|
||||
return PICO_PMV_ERROR_IDENT;
|
||||
}
|
||||
|
||||
/* check first token */
|
||||
if ( _pico_stricmp( p->token, "picoterrain" ) ) {
|
||||
_pico_free_parser( p );
|
||||
return PICO_PMV_ERROR_IDENT;
|
||||
}
|
||||
|
||||
/* free the pico parser object */
|
||||
_pico_free_parser( p );
|
||||
|
||||
/* file seems to be a valid picoterrain file */
|
||||
return PICO_PMV_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
_terrain_load()
|
||||
loads a picoterrain file
|
||||
*/
|
||||
|
||||
static picoModel_t *_terrain_load( PM_PARAMS_LOAD ) {
|
||||
int i, j, v, pw[ 5 ], r;
|
||||
picoParser_t *p;
|
||||
|
||||
char *shader, *heightmapFile, *colormapFile;
|
||||
picoVec3_t scale, origin;
|
||||
|
||||
unsigned char *imageBuffer;
|
||||
int imageBufSize, w, h, cw, ch;
|
||||
unsigned char *heightmap, *colormap, *heightPixel, *colorPixel;
|
||||
|
||||
picoModel_t *picoModel;
|
||||
picoSurface_t *picoSurface;
|
||||
picoShader_t *picoShader;
|
||||
picoVec3_t xyz, normal;
|
||||
picoVec2_t st;
|
||||
picoColor_t color;
|
||||
|
||||
|
||||
/* keep the friggin compiler happy */
|
||||
*fileName = *fileName;
|
||||
|
||||
/* create pico parser */
|
||||
p = _pico_new_parser( (picoByte_t*) buffer, bufSize );
|
||||
if ( p == NULL ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* get first token */
|
||||
if ( _pico_parse_first( p ) == NULL ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* check first token */
|
||||
if ( _pico_stricmp( p->token, "picoterrain" ) ) {
|
||||
_pico_printf( PICO_ERROR, "Invalid PicoTerrain model" );
|
||||
_pico_free_parser( p );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* setup */
|
||||
shader = heightmapFile = colormapFile = NULL;
|
||||
_pico_set_vec( scale, 512, 512, 32 );
|
||||
|
||||
/* parse ase model file */
|
||||
while ( 1 )
|
||||
{
|
||||
/* get first token on line */
|
||||
if ( !_pico_parse_first( p ) ) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* skip empty lines */
|
||||
if ( !p->token || !p->token[ 0 ] ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* shader */
|
||||
if ( !_pico_stricmp( p->token, "shader" ) ) {
|
||||
if ( _pico_parse( p, 0 ) && p->token[ 0 ] ) {
|
||||
if ( shader != NULL ) {
|
||||
_pico_free( shader );
|
||||
}
|
||||
shader = _pico_clone_alloc( p->token );
|
||||
}
|
||||
}
|
||||
|
||||
/* heightmap */
|
||||
else if ( !_pico_stricmp( p->token, "heightmap" ) ) {
|
||||
if ( _pico_parse( p, 0 ) && p->token[ 0 ] ) {
|
||||
if ( heightmapFile != NULL ) {
|
||||
_pico_free( heightmapFile );
|
||||
}
|
||||
heightmapFile = _pico_clone_alloc( p->token );
|
||||
}
|
||||
}
|
||||
|
||||
/* colormap */
|
||||
else if ( !_pico_stricmp( p->token, "colormap" ) ) {
|
||||
if ( _pico_parse( p, 0 ) && p->token[ 0 ] ) {
|
||||
if ( colormapFile != NULL ) {
|
||||
_pico_free( colormapFile );
|
||||
}
|
||||
colormapFile = _pico_clone_alloc( p->token );
|
||||
}
|
||||
}
|
||||
|
||||
/* scale */
|
||||
else if ( !_pico_stricmp( p->token, "scale" ) ) {
|
||||
_pico_parse_vec( p, scale );
|
||||
}
|
||||
|
||||
/* skip unparsed rest of line and continue */
|
||||
_pico_parse_skip_rest( p );
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------- */
|
||||
|
||||
/* load heightmap */
|
||||
heightmap = imageBuffer = NULL;
|
||||
_pico_load_file( heightmapFile, &imageBuffer, &imageBufSize );
|
||||
_terrain_load_tga_buffer( imageBuffer, &heightmap, &w, &h );
|
||||
_pico_free( heightmapFile );
|
||||
_pico_free_file( imageBuffer );
|
||||
|
||||
if ( heightmap == NULL || w < 2 || h < 2 ) {
|
||||
_pico_printf( PICO_ERROR, "PicoTerrain model with invalid heightmap" );
|
||||
if ( shader != NULL ) {
|
||||
_pico_free( shader );
|
||||
}
|
||||
if ( colormapFile != NULL ) {
|
||||
_pico_free( colormapFile );
|
||||
}
|
||||
_pico_free_parser( p );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* set origin (bottom lowest corner of terrain mesh) */
|
||||
_pico_set_vec( origin, ( w / -2 ) * scale[ 0 ], ( h / -2 ) * scale[ 1 ], -128 * scale[ 2 ] );
|
||||
|
||||
/* load colormap */
|
||||
colormap = imageBuffer = NULL;
|
||||
_pico_load_file( colormapFile, &imageBuffer, &imageBufSize );
|
||||
_terrain_load_tga_buffer( imageBuffer, &colormap, &cw, &ch );
|
||||
_pico_free( colormapFile );
|
||||
_pico_free_file( imageBuffer );
|
||||
|
||||
if ( cw != w || ch != h ) {
|
||||
_pico_printf( PICO_WARNING, "PicoTerrain colormap/heightmap size mismatch" );
|
||||
_pico_free( colormap );
|
||||
colormap = NULL;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------- */
|
||||
|
||||
/* create new pico model */
|
||||
picoModel = PicoNewModel();
|
||||
if ( picoModel == NULL ) {
|
||||
_pico_printf( PICO_ERROR, "Unable to allocate a new model" );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* do model setup */
|
||||
PicoSetModelFrameNum( picoModel, frameNum );
|
||||
PicoSetModelNumFrames( picoModel, 1 ); /* sea */
|
||||
PicoSetModelName( picoModel, fileName );
|
||||
PicoSetModelFileName( picoModel, fileName );
|
||||
|
||||
/* allocate new pico surface */
|
||||
picoSurface = PicoNewSurface( picoModel );
|
||||
if ( picoSurface == NULL ) {
|
||||
_pico_printf( PICO_ERROR, "Unable to allocate a new model surface" );
|
||||
PicoFreeModel( picoModel ); /* sea */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* terrain surfaces are triangle meshes */
|
||||
PicoSetSurfaceType( picoSurface, PICO_TRIANGLES );
|
||||
|
||||
/* set surface name */
|
||||
PicoSetSurfaceName( picoSurface, "picoterrain" );
|
||||
|
||||
/* create new pico shader */
|
||||
picoShader = PicoNewShader( picoModel );
|
||||
if ( picoShader == NULL ) {
|
||||
_pico_printf( PICO_ERROR, "Unable to allocate a new model shader" );
|
||||
PicoFreeModel( picoModel );
|
||||
_pico_free( shader );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* detox and set shader name */
|
||||
_pico_setfext( shader, "" );
|
||||
_pico_unixify( shader );
|
||||
PicoSetShaderName( picoShader, shader );
|
||||
_pico_free( shader );
|
||||
|
||||
/* associate current surface with newly created shader */
|
||||
PicoSetSurfaceShader( picoSurface, picoShader );
|
||||
|
||||
/* make bogus normal */
|
||||
_pico_set_vec( normal, 0.0f, 0.0f, 0.0f );
|
||||
|
||||
/* create mesh */
|
||||
for ( j = 0; j < h; j++ )
|
||||
{
|
||||
for ( i = 0; i < w; i++ )
|
||||
{
|
||||
/* get pointers */
|
||||
v = i + ( j * w );
|
||||
heightPixel = heightmap + v * 4;
|
||||
colorPixel = colormap
|
||||
? colormap + v * 4
|
||||
: NULL;
|
||||
|
||||
/* set xyz */
|
||||
_pico_set_vec( xyz, origin[ 0 ] + scale[ 0 ] * i,
|
||||
origin[ 1 ] + scale[ 1 ] * j,
|
||||
origin[ 2 ] + scale[ 2 ] * heightPixel[ 0 ] );
|
||||
PicoSetSurfaceXYZ( picoSurface, v, xyz );
|
||||
|
||||
/* set normal */
|
||||
PicoSetSurfaceNormal( picoSurface, v, normal );
|
||||
|
||||
/* set st */
|
||||
st[ 0 ] = (float) i;
|
||||
st[ 1 ] = (float) j;
|
||||
PicoSetSurfaceST( picoSurface, 0, v, st );
|
||||
|
||||
/* set color */
|
||||
if ( colorPixel != NULL ) {
|
||||
_pico_set_color( color, colorPixel[ 0 ], colorPixel[ 1 ], colorPixel[ 2 ], colorPixel[ 3 ] );
|
||||
}
|
||||
else{
|
||||
_pico_set_color( color, 255, 255, 255, 255 );
|
||||
}
|
||||
PicoSetSurfaceColor( picoSurface, 0, v, color );
|
||||
|
||||
/* set triangles (zero alpha in heightmap suppresses this quad) */
|
||||
if ( i < ( w - 1 ) && j < ( h - 1 ) && heightPixel[ 3 ] >= 128 ) {
|
||||
/* set indexes */
|
||||
pw[ 0 ] = i + ( j * w );
|
||||
pw[ 1 ] = i + ( ( j + 1 ) * w );
|
||||
pw[ 2 ] = i + 1 + ( ( j + 1 ) * w );
|
||||
pw[ 3 ] = i + 1 + ( j * w );
|
||||
pw[ 4 ] = i + ( j * w ); /* same as pw[ 0 ] */
|
||||
|
||||
/* set radix */
|
||||
r = ( i + j ) & 1;
|
||||
|
||||
/* make first triangle */
|
||||
PicoSetSurfaceIndex( picoSurface, ( v * 6 + 0 ), (picoIndex_t) pw[ r + 0 ] );
|
||||
PicoSetSurfaceIndex( picoSurface, ( v * 6 + 1 ), (picoIndex_t) pw[ r + 1 ] );
|
||||
PicoSetSurfaceIndex( picoSurface, ( v * 6 + 2 ), (picoIndex_t) pw[ r + 2 ] );
|
||||
|
||||
/* make second triangle */
|
||||
PicoSetSurfaceIndex( picoSurface, ( v * 6 + 3 ), (picoIndex_t) pw[ r + 0 ] );
|
||||
PicoSetSurfaceIndex( picoSurface, ( v * 6 + 4 ), (picoIndex_t) pw[ r + 2 ] );
|
||||
PicoSetSurfaceIndex( picoSurface, ( v * 6 + 5 ), (picoIndex_t) pw[ r + 3 ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* free stuff */
|
||||
_pico_free_parser( p );
|
||||
_pico_free( heightmap );
|
||||
_pico_free( colormap );
|
||||
|
||||
/* return the new pico model */
|
||||
return picoModel;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* pico file format module definition */
|
||||
const picoModule_t picoModuleTerrain =
|
||||
{
|
||||
"1.3", /* module version string */
|
||||
"PicoTerrain", /* module display name */
|
||||
"Randy Reddig", /* author's name */
|
||||
"2003 Randy Reddig", /* module copyright */
|
||||
{
|
||||
"picoterrain", NULL, NULL, NULL /* default extensions to use */
|
||||
},
|
||||
_terrain_canload, /* validation routine */
|
||||
_terrain_load, /* load routine */
|
||||
NULL, /* save validation routine */
|
||||
NULL /* save routine */
|
||||
};
|
|
@ -91,7 +91,7 @@
|
|||
/*!
|
||||
=======================================================================
|
||||
diagnostic printing facility
|
||||
independently from any API negociation stuff,
|
||||
independently from any API negotiation stuff,
|
||||
we need a diagnostic facility that's available at all times
|
||||
=======================================================================
|
||||
*/
|
||||
|
@ -219,7 +219,7 @@ void SetType( EAPIManagerType type ) { mType = type; }
|
|||
set the API matching pattern
|
||||
supported syntax:
|
||||
any minor for a given major, for instance: PLUGIN_MAJOR, "*"
|
||||
a space seperated list of minors for a given major: IMAGE_MAJOR, "tga jpg"
|
||||
a space separated list of minors for a given major: IMAGE_MAJOR, "tga jpg"
|
||||
*/
|
||||
void SetMatchAPI( const char *major, const char *minor );
|
||||
|
||||
|
@ -236,8 +236,8 @@ static APIDescriptor_t* PrepareRequireAPI( APIDescriptor_t *pAPI );
|
|||
bool CheckSetActive();
|
||||
|
||||
/*!
|
||||
the manager answers wether it wants to load this or not
|
||||
we provide a default implementation, but this can be completely overriden if needed
|
||||
the manager answers whether it wants to load this or not
|
||||
we provide a default implementation, but this can be completely overridden if needed
|
||||
see SetMatchAPI for the documentation of the default implementation
|
||||
NOTE: this should only be called on API_MATCH type of managers
|
||||
*/
|
||||
|
@ -279,8 +279,8 @@ class CSynapseServer; // forward declare
|
|||
class CSynapseClient : public IRefCounted
|
||||
{
|
||||
/*!
|
||||
this flag indicates wether this client is active
|
||||
i.e. wether you can ask it for interfaces
|
||||
this flag indicates whether this client is active
|
||||
i.e. whether you can ask it for interfaces
|
||||
this is either a client for which all required interfaces have been filled in
|
||||
or a client we are trying to resolve (i.e. load with all it's stuff)
|
||||
*/
|
||||
|
@ -324,7 +324,7 @@ APIDescriptor_t* GetAPIDescriptor( int ) const; ///< retrieve specific informati
|
|||
SYN_PROVIDE: means this is an API we provide if anyone needs it
|
||||
SYN_REQUIRE: means this is an API we will require for operation
|
||||
SYN_REQUIRE_ANY: means this is an API we want to load *any* minor found
|
||||
(for instance a list of image fornats, or the plugins)
|
||||
(for instance a list of image formats, or the plugins)
|
||||
|
||||
\param pTable
|
||||
the function table
|
||||
|
@ -363,7 +363,7 @@ CSynapseAPIManager* GetManagerList( int ); ///< get corresponding API manager
|
|||
virtual bool RequestAPI( APIDescriptor_t *pAPI ) = 0;
|
||||
|
||||
/*!
|
||||
return the build date, can be overriden by client module
|
||||
return the build date, can be overridden by client module
|
||||
*/
|
||||
virtual const char* GetInfo();
|
||||
|
||||
|
@ -405,7 +405,7 @@ virtual bool OnActivate() { return true; }
|
|||
|
||||
\param client_name, the name of the client node to look for. If NULL, use GetName()
|
||||
|
||||
\return wether all APIs given were successfully found in the config
|
||||
\return whether all APIs given were successfully found in the config
|
||||
*/
|
||||
bool ConfigXML( CSynapseServer *pServer, const char *client_name, const XMLConfigEntry_t entries[] );
|
||||
|
||||
|
@ -451,7 +451,7 @@ typedef enum { SYN_SO, SYN_BUILTIN } EClientType;
|
|||
|
||||
/*!
|
||||
server side slot for a synapse client
|
||||
is OS dependant, except for the ISynapseClient part
|
||||
is OS dependent, except for the ISynapseClient part
|
||||
*/
|
||||
class CSynapseClientSlot
|
||||
{
|
||||
|
@ -517,7 +517,7 @@ gchar *m_content;
|
|||
|
||||
/*!
|
||||
push required interfaces for this client into the stack of things to be resolved
|
||||
it is possible that several mathing interfaces be in the stack at the same time
|
||||
it is possible that several matching interfaces be in the stack at the same time
|
||||
(for instance several modules that want to get the VFS)
|
||||
but we should never have the same APIDescriptor_t twice
|
||||
NOTE: as this function is called repeatedly during the resolve (because the list of required things is refining),
|
||||
|
@ -567,8 +567,8 @@ void AddSearchPath( char* ); ///< add a new directory to the module search path
|
|||
/*!
|
||||
do the big thing, scan for modules, scan their APIs, load up everything
|
||||
providing pf is optional, will set the diagnostics printing
|
||||
\param conf_file is the XML configuration file for the intialization (see docs/runtime.txt)
|
||||
\return false if the init failed (for instance not found/invalid conf file
|
||||
\param conf_file is the XML configuration file for the initialization (see docs/runtime.txt)
|
||||
\return false if the init failed (for instance not found/invalid configuration file
|
||||
*/
|
||||
bool Initialize( const char* conf_file = NULL, PFN_SYN_PRINTF_VA pf = NULL );
|
||||
|
||||
|
@ -593,8 +593,8 @@ bool Resolve( CSynapseClient *pClient );
|
|||
|
||||
/*!
|
||||
\brief shutdown all the clients. Should only be called when the core is about to exit
|
||||
this will force all clients to shutdown. it may destroy refcounted APIs and stuff
|
||||
\todo hafta use the release/refresh code before doing actual shutdown
|
||||
this will force all clients to shutdown. it may destroy refcounted APIs and such
|
||||
\todo have to use the release/refresh code before doing actual shutdown
|
||||
(i.e. when that code is written later on)
|
||||
we need to 'broadcast' to all the clients .. that all the modules are going to be reloaded sorta
|
||||
should clear up as many interfaces as possible to avoid unexpected crashes in the final stages of app exit
|
||||
|
|
|
@ -123,6 +123,9 @@
|
|||
<ItemGroup>
|
||||
<ClCompile Include="synapse.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\synapse.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
|
|
|
@ -11,4 +11,9 @@
|
|||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\synapse.h">
|
||||
<Filter>src</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -1618,12 +1618,12 @@ static int unzlocal_GetCurrentFileInfoInternal (unzFile file,
|
|||
|
||||
|
||||
/* we check the magic */
|
||||
if (err==UNZ_OK)
|
||||
if (err==UNZ_OK) {
|
||||
if (unzlocal_getLong(s->file,&uMagic) != UNZ_OK)
|
||||
err=UNZ_ERRNO;
|
||||
else if (uMagic!=0x02014b50)
|
||||
err=UNZ_BADZIPFILE;
|
||||
|
||||
}
|
||||
if (unzlocal_getShort(s->file,&file_info.version) != UNZ_OK)
|
||||
err=UNZ_ERRNO;
|
||||
|
||||
|
@ -1698,11 +1698,12 @@ static int unzlocal_GetCurrentFileInfoInternal (unzFile file,
|
|||
else
|
||||
uSizeRead = extraFieldBufferSize;
|
||||
|
||||
if (lSeek!=0)
|
||||
if (lSeek!=0) {
|
||||
if (fseek(s->file,lSeek,SEEK_CUR)==0)
|
||||
lSeek=0;
|
||||
else
|
||||
err=UNZ_ERRNO;
|
||||
}
|
||||
if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))
|
||||
if (fread(extraField,(uInt)uSizeRead,1,s->file)!=1)
|
||||
err=UNZ_ERRNO;
|
||||
|
@ -1723,11 +1724,12 @@ static int unzlocal_GetCurrentFileInfoInternal (unzFile file,
|
|||
else
|
||||
uSizeRead = commentBufferSize;
|
||||
|
||||
if (lSeek!=0)
|
||||
if (lSeek!=0) {
|
||||
if (fseek(s->file,lSeek,SEEK_CUR)==0)
|
||||
lSeek=0;
|
||||
else
|
||||
err=UNZ_ERRNO;
|
||||
}
|
||||
if ((file_info.size_file_comment>0) && (commentBufferSize>0))
|
||||
if (fread(szComment,(uInt)uSizeRead,1,s->file)!=1)
|
||||
err=UNZ_ERRNO;
|
||||
|
@ -1889,12 +1891,12 @@ static int unzlocal_CheckCurrentFileCoherencyHeader (unz_s* s, uInt* piSizeVar,
|
|||
return UNZ_ERRNO;
|
||||
|
||||
|
||||
if (err==UNZ_OK)
|
||||
if (err==UNZ_OK) {
|
||||
if (unzlocal_getLong(s->file,&uMagic) != UNZ_OK)
|
||||
err=UNZ_ERRNO;
|
||||
else if (uMagic!=0x04034b50)
|
||||
err=UNZ_BADZIPFILE;
|
||||
|
||||
}
|
||||
if (unzlocal_getShort(s->file,&uData) != UNZ_OK)
|
||||
err=UNZ_ERRNO;
|
||||
/*
|
||||
|
|
|
@ -1615,12 +1615,12 @@ static int unzlocal_GetCurrentFileInfoInternal (unzFile file,
|
|||
|
||||
|
||||
/* we check the magic */
|
||||
if (err==UNZ_OK)
|
||||
if (err==UNZ_OK) {
|
||||
if (unzlocal_getLong(s->file,&uMagic) != UNZ_OK)
|
||||
err=UNZ_ERRNO;
|
||||
else if (uMagic!=0x02014b50)
|
||||
err=UNZ_BADZIPFILE;
|
||||
|
||||
}
|
||||
if (unzlocal_getShort(s->file,&file_info.version) != UNZ_OK)
|
||||
err=UNZ_ERRNO;
|
||||
|
||||
|
@ -1695,11 +1695,12 @@ static int unzlocal_GetCurrentFileInfoInternal (unzFile file,
|
|||
else
|
||||
uSizeRead = extraFieldBufferSize;
|
||||
|
||||
if (lSeek!=0)
|
||||
if (lSeek!=0) {
|
||||
if (fseek(s->file,lSeek,SEEK_CUR)==0)
|
||||
lSeek=0;
|
||||
else
|
||||
err=UNZ_ERRNO;
|
||||
}
|
||||
if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))
|
||||
if (fread_ql(extraField,(uInt)uSizeRead,1,s->file)!=1)
|
||||
err=UNZ_ERRNO;
|
||||
|
@ -1720,11 +1721,12 @@ static int unzlocal_GetCurrentFileInfoInternal (unzFile file,
|
|||
else
|
||||
uSizeRead = commentBufferSize;
|
||||
|
||||
if (lSeek!=0)
|
||||
if (lSeek!=0) {
|
||||
if (fseek(s->file,lSeek,SEEK_CUR)==0)
|
||||
lSeek=0;
|
||||
else
|
||||
err=UNZ_ERRNO;
|
||||
}
|
||||
if ((file_info.size_file_comment>0) && (commentBufferSize>0))
|
||||
if (fread_ql(szComment,(uInt)uSizeRead,1,s->file)!=1)
|
||||
err=UNZ_ERRNO;
|
||||
|
@ -1886,12 +1888,12 @@ static int unzlocal_CheckCurrentFileCoherencyHeader (unz_s* s, uInt* piSizeVar,
|
|||
return UNZ_ERRNO;
|
||||
|
||||
|
||||
if (err==UNZ_OK)
|
||||
if (err==UNZ_OK) {
|
||||
if (unzlocal_getLong(s->file,&uMagic) != UNZ_OK)
|
||||
err=UNZ_ERRNO;
|
||||
else if (uMagic!=0x04034b50)
|
||||
err=UNZ_BADZIPFILE;
|
||||
|
||||
}
|
||||
if (unzlocal_getShort(s->file,&uData) != UNZ_OK)
|
||||
err=UNZ_ERRNO;
|
||||
/*
|
||||
|
|
3
tools/.gitignore
vendored
Normal file
3
tools/.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
x64
|
||||
Debug
|
||||
Release
|
|
@ -1293,7 +1293,7 @@ tree_t *BrushBSP( bspbrush_t *brushlist, vec3_t mins, vec3_t maxs ){
|
|||
|
||||
volume = BrushVolume( b );
|
||||
if ( volume < microvolume ) {
|
||||
Sys_Printf( "WARNING: entity %i, brush %i: microbrush\n",
|
||||
Sys_FPrintf( SYS_WRN, "WARNING: entity %i, brush %i: microbrush\n",
|
||||
b->original->entitynum, b->original->brushnum );
|
||||
}
|
||||
|
||||
|
|
|
@ -653,7 +653,7 @@ int GetEdge2( int v1, int v2, face_t *f ){
|
|||
}
|
||||
#if 0
|
||||
if ( v1 == edge->v[0] && v2 == edge->v[1] ) {
|
||||
Sys_Printf( "WARNING: multiple forward edge\n" );
|
||||
Sys_FPrintf( SYS_WRN, "WARNING: multiple forward edge\n" );
|
||||
return i;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -874,7 +874,7 @@ void CreateDirectLights( void ){
|
|||
if ( target[0] ) { // point towards target
|
||||
e2 = FindTargetEntity( target );
|
||||
if ( !e2 ) {
|
||||
Sys_Printf( "WARNING: light at (%i %i %i) has missing target\n",
|
||||
Sys_FPrintf( SYS_WRN, "WARNING: light at (%i %i %i) has missing target\n",
|
||||
(int)dl->origin[0], (int)dl->origin[1], (int)dl->origin[2] );
|
||||
}
|
||||
else
|
||||
|
|
|
@ -649,7 +649,7 @@ int main( int argc, char **argv ){
|
|||
Sys_Printf( "Game: %s\n", game );
|
||||
|
||||
if ( !do_info && !do_bsp && !do_vis && !do_rad ) {
|
||||
Sys_Printf( "ERROR: -bsp, -vis, -light, nor -info specified.\nWhat to you want me to do?\n\n" );
|
||||
Sys_FPrintf( SYS_ERR, "ERROR: -bsp, -vis, -light, nor -info specified.\nWhat to you want me to do?\n\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -554,13 +554,13 @@ void MakeTreePortals_r( node_t *node ){
|
|||
|
||||
CalcNodeBounds( node );
|
||||
if ( node->mins[0] >= node->maxs[0] ) {
|
||||
Sys_Printf( "WARNING: node without a volume\n" );
|
||||
Sys_FPrintf( SYS_WRN, "WARNING: node without a volume\n" );
|
||||
}
|
||||
|
||||
for ( i = 0 ; i < 3 ; i++ )
|
||||
{
|
||||
if ( node->mins[i] < -8000 || node->maxs[i] > 8000 ) {
|
||||
Sys_Printf( "WARNING: node with unbounded volume\n" );
|
||||
Sys_FPrintf( SYS_WRN, "WARNING: node with unbounded volume\n" );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -756,7 +756,7 @@ void FloodAreas_r( node_t *node ){
|
|||
|
||||
// note the current area as bounding the portal
|
||||
if ( e->portalareas[1] ) {
|
||||
Sys_Printf( "WARNING: areaportal entity %i touches > 2 areas\n", b->original->entitynum );
|
||||
Sys_FPrintf( SYS_WRN, "WARNING: areaportal entity %i touches > 2 areas\n", b->original->entitynum );
|
||||
return;
|
||||
}
|
||||
if ( e->portalareas[0] ) {
|
||||
|
@ -854,7 +854,7 @@ void SetAreaPortalAreas_r( node_t *node ){
|
|||
e = &entities[b->original->entitynum];
|
||||
node->area = e->portalareas[0];
|
||||
if ( !e->portalareas[1] ) {
|
||||
Sys_Printf( "WARNING: areaportal entity %i doesn't touch two areas\n", b->original->entitynum );
|
||||
Sys_FPrintf( SYS_WRN, "WARNING: areaportal entity %i doesn't touch two areas\n", b->original->entitynum );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -209,7 +209,7 @@ void ClusterMerge( int leafnum ){
|
|||
numvis = LeafVectorFromPortalVector( portalvector, uncompressed );
|
||||
|
||||
if ( uncompressed[leafnum >> 3] & ( 1 << ( leafnum & 7 ) ) ) {
|
||||
Sys_Printf( "WARNING: Leaf portals saw into leaf\n" );
|
||||
Sys_FPrintf( SYS_WRN, "WARNING: Leaf portals saw into leaf\n" );
|
||||
}
|
||||
|
||||
uncompressed[leafnum >> 3] |= ( 1 << ( leafnum & 7 ) );
|
||||
|
|
|
@ -472,7 +472,7 @@ static void ASE_KeyMAP_DIFFUSE( const char *token ){
|
|||
else
|
||||
{
|
||||
sprintf( ase.materials[ase.numMaterials].name, "(not converted: '%s')", bitmap );
|
||||
Sys_Printf( "WARNING: illegal material name '%s'\n", bitmap );
|
||||
Sys_FPrintf( SYS_WRN, "WARNING: illegal material name '%s'\n", bitmap );
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
@ -778,7 +778,7 @@ int BSPMain( int argc, char **argv ){
|
|||
else if ( !strcmp( argv[ i ], "-np" ) ) {
|
||||
npDegrees = atof( argv[ i + 1 ] );
|
||||
if ( npDegrees < 0.0f ) {
|
||||
shadeAngleDegrees = 0.0f;
|
||||
npDegrees = 0.0f;
|
||||
}
|
||||
else if ( npDegrees > 0.0f ) {
|
||||
Sys_Printf( "Forcing nonplanar surfaces with a breaking angle of %f degrees\n", npDegrees );
|
||||
|
|
Loading…
Reference in a new issue