/* =========================================================================== Doom 3 GPL Source Code Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company. This file is part of the Doom 3 GPL Source Code ("Doom 3 Source Code"). Doom 3 Source Code is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Doom 3 Source Code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Doom 3 Source Code. If not, see . In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below. If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA. =========================================================================== */ #include "sys/platform.h" #include "idlib/LangDict.h" #include "framework/DemoFile.h" #include "ui/DeviceContext.h" #include "ui/Window.h" #include "ui/UserInterfaceLocal.h" #include "ui/RegExp.h" int idRegister::REGCOUNT[NUMTYPES] = {4, 1, 1, 1, 0, 2, 3, 4}; /* ==================== idRegister::SetToRegs ==================== */ void idRegister::SetToRegs( float *registers ) { int i; idVec4 v; idVec2 v2; idVec3 v3; idRectangle rect; if ( !enabled || var == NULL || ( var && ( var->GetDict() || !var->GetEval() ) ) ) { return; } switch( type ) { case VEC4: { v = *static_cast(var); break; } case RECTANGLE: { rect = *static_cast(var); v = rect.ToVec4(); break; } case VEC2: { v2 = *static_cast(var); v[0] = v2[0]; v[1] = v2[1]; break; } case VEC3: { v3 = *static_cast(var); v[0] = v3[0]; v[1] = v3[1]; v[2] = v3[2]; break; } case FLOAT: { v[0] = *static_cast(var); break; } case INT: { v[0] = *static_cast(var); break; } case BOOL: { v[0] = *static_cast(var); break; } default: { common->FatalError( "idRegister::SetToRegs: bad reg type" ); break; } } for ( i = 0; i < regCount; i++ ) { registers[ regs[ i ] ] = v[i]; } } /* ================= idRegister::GetFromRegs ================= */ void idRegister::GetFromRegs( float *registers ) { idVec4 v; idRectangle rect; if (!enabled || var == NULL || (var && (var->GetDict() || !var->GetEval()))) { return; } for ( int i = 0; i < regCount; i++ ) { v[i] = registers[regs[i]]; } switch( type ) { case VEC4: { *dynamic_cast(var) = v; break; } case RECTANGLE: { rect.x = v.x; rect.y = v.y; rect.w = v.z; rect.h = v.w; *static_cast(var) = rect; break; } case VEC2: { *static_cast(var) = v.ToVec2(); break; } case VEC3: { *static_cast(var) = v.ToVec3(); break; } case FLOAT: { *static_cast(var) = v[0]; break; } case INT: { *static_cast(var) = v[0]; break; } case BOOL: { *static_cast(var) = ( v[0] != 0.0f ); break; } default: { common->FatalError( "idRegister::GetFromRegs: bad reg type" ); break; } } } /* ================= idRegister::ReadFromDemoFile ================= */ void idRegister::ReadFromDemoFile(idDemoFile *f) { f->ReadBool( enabled ); f->ReadShort( type ); f->ReadInt( regCount ); for ( int i = 0; i < 4; i++ ) f->ReadUnsignedShort( regs[i] ); name = f->ReadHashString(); } /* ================= idRegister::WriteToDemoFile ================= */ void idRegister::WriteToDemoFile( idDemoFile *f ) { f->WriteBool( enabled ); f->WriteShort( type ); f->WriteInt( regCount ); for (int i = 0; i < 4; i++) f->WriteUnsignedShort( regs[i] ); f->WriteHashString( name ); } /* ================= idRegister::WriteToSaveGame ================= */ void idRegister::WriteToSaveGame( idFile *savefile ) { int len; savefile->Write( &enabled, sizeof( enabled ) ); savefile->Write( &type, sizeof( type ) ); savefile->Write( ®Count, sizeof( regCount ) ); savefile->Write( ®s[0], sizeof( regs ) ); len = name.Length(); savefile->Write( &len, sizeof( len ) ); savefile->Write( name.c_str(), len ); var->WriteToSaveGame( savefile ); } /* ================ idRegister::ReadFromSaveGame ================ */ void idRegister::ReadFromSaveGame( idFile *savefile ) { int len; savefile->Read( &enabled, sizeof( enabled ) ); savefile->Read( &type, sizeof( type ) ); savefile->Read( ®Count, sizeof( regCount ) ); savefile->Read( ®s[0], sizeof( regs ) ); savefile->Read( &len, sizeof( len ) ); name.Fill( ' ', len ); savefile->Read( &name[0], len ); var->ReadFromSaveGame( savefile ); } /* ==================== idRegisterList::AddReg ==================== */ void idRegisterList::AddReg( const char *name, int type, idVec4 data, idWindow *win, idWinVar *var ) { if ( FindReg( name ) == NULL ) { assert( type >= 0 && type < idRegister::NUMTYPES ); int numRegs = idRegister::REGCOUNT[type]; idRegister *reg = new idRegister( name, type ); reg->var = var; for ( int i = 0; i < numRegs; i++ ) { reg->regs[i] = win->ExpressionConstant(data[i]); } int hash = regHash.GenerateKey( name, false ); regHash.Add( hash, regs.Append( reg ) ); } } /* ==================== idRegisterList::AddReg ==================== */ void idRegisterList::AddReg( const char *name, int type, idParser *src, idWindow *win, idWinVar *var ) { idRegister* reg; reg = FindReg( name ); if ( reg == NULL ) { assert(type >= 0 && type < idRegister::NUMTYPES); int numRegs = idRegister::REGCOUNT[type]; reg = new idRegister( name, type ); reg->var = var; if ( type == idRegister::STRING ) { idToken tok; if ( src->ReadToken( &tok ) ) { tok = common->GetLanguageDict()->GetString( tok ); var->Init( tok, win ); } } else { for ( int i = 0; i < numRegs; i++ ) { reg->regs[i] = win->ParseExpression(src, NULL); if ( i < numRegs-1 ) { src->ExpectTokenString(","); } } } int hash = regHash.GenerateKey( name, false ); regHash.Add( hash, regs.Append( reg ) ); } else { int numRegs = idRegister::REGCOUNT[type]; reg->var = var; if ( type == idRegister::STRING ) { idToken tok; if ( src->ReadToken( &tok ) ) { var->Init( tok, win ); } } else { for ( int i = 0; i < numRegs; i++ ) { reg->regs[i] = win->ParseExpression( src, NULL ); if ( i < numRegs-1 ) { src->ExpectTokenString(","); } } } } } /* ==================== idRegisterList::GetFromRegs ==================== */ void idRegisterList::GetFromRegs(float *registers) { for ( int i = 0; i < regs.Num(); i++ ) { regs[i]->GetFromRegs( registers ); } } /* ==================== idRegisterList::SetToRegs ==================== */ void idRegisterList::SetToRegs( float *registers ) { int i; for ( i = 0; i < regs.Num(); i++ ) { regs[i]->SetToRegs( registers ); } } /* ==================== idRegisterList::FindReg ==================== */ idRegister *idRegisterList::FindReg( const char *name ) { int hash = regHash.GenerateKey( name, false ); for ( int i = regHash.First( hash ); i != -1; i = regHash.Next( i ) ) { if ( regs[i]->name.Icmp( name ) == 0 ) { return regs[i]; } } return NULL; } /* ==================== idRegisterList::Reset ==================== */ void idRegisterList::Reset() { regs.DeleteContents( true ); regHash.Clear(); } /* ==================== idRegisterList::ReadFromSaveGame ==================== */ void idRegisterList::ReadFromDemoFile(idDemoFile *f) { int c; f->ReadInt( c ); regs.DeleteContents( true ); for ( int i = 0; i < c; i++ ) { idRegister *reg = new idRegister; reg->ReadFromDemoFile( f ); regs.Append( reg ); } } /* ==================== idRegisterList::ReadFromSaveGame ==================== */ void idRegisterList::WriteToDemoFile(idDemoFile *f) { int c = regs.Num(); f->WriteInt( c ); for ( int i = 0 ; i < c; i++ ) { regs[i]->WriteToDemoFile(f); } } /* ===================== idRegisterList::WriteToSaveGame ===================== */ void idRegisterList::WriteToSaveGame( idFile *savefile ) { int i, num; num = regs.Num(); savefile->Write( &num, sizeof( num ) ); for ( i = 0; i < num; i++ ) { regs[i]->WriteToSaveGame( savefile ); } } /* ==================== idRegisterList::ReadFromSaveGame ==================== */ void idRegisterList::ReadFromSaveGame( idFile *savefile ) { int i, num; savefile->Read( &num, sizeof( num ) ); for ( i = 0; i < num; i++ ) { regs[i]->ReadFromSaveGame( savefile ); } }