core/smn_bitbuffer.cpp
author Nicholas Hastings <skamonkey@gmail.com>
Sat Aug 10 12:22:09 2013 -0400 (2013-08-10)
changeset 3981 af3681eade3f
parent 3872 4c93f74cae51
permissions -rw-r--r--
Debug build fixes.
     1 /**
     2  * vim: set ts=4 :
     3  * =============================================================================
     4  * SourceMod
     5  * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
     6  * =============================================================================
     7  *
     8  * This program is free software; you can redistribute it and/or modify it under
     9  * the terms of the GNU General Public License, version 3.0, as published by the
    10  * Free Software Foundation.
    11  * 
    12  * This program is distributed in the hope that it will be useful, but WITHOUT
    13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    14  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
    15  * details.
    16  *
    17  * You should have received a copy of the GNU General Public License along with
    18  * this program.  If not, see <http://www.gnu.org/licenses/>.
    19  *
    20  * As a special exception, AlliedModders LLC gives you permission to link the
    21  * code of this program (as well as its derivative works) to "Half-Life 2," the
    22  * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
    23  * by the Valve Corporation.  You must obey the GNU General Public License in
    24  * all respects for all other code used.  Additionally, AlliedModders LLC grants
    25  * this exception to all derivative works.  AlliedModders LLC defines further
    26  * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
    27  * or <http://www.sourcemod.net/license.php>.
    28  *
    29  * Version: $Id$
    30  */
    31 
    32 #include "UserMessages.h"
    33 
    34 #ifndef USE_PROTOBUF_USERMESSAGES
    35 
    36 #include "sourcemod.h"
    37 #include <bitbuf.h>
    38 #include <vector.h>
    39 #include <HalfLife2.h>
    40 #include "smn_usermsgs.h"
    41 #include "sourcemod.h"
    42 #include "logic_bridge.h"
    43 
    44 static cell_t smn_BfWriteBool(IPluginContext *pCtx, const cell_t *params)
    45 {
    46 	Handle_t hndl = static_cast<Handle_t>(params[1]);
    47 	HandleError herr;
    48 	HandleSecurity sec;
    49 	bf_write *pBitBuf;
    50 
    51 	sec.pOwner = NULL;
    52 	sec.pIdentity = g_pCoreIdent;
    53 
    54 	if ((herr=handlesys->ReadHandle(hndl, g_WrBitBufType, &sec, (void **)&pBitBuf))
    55 		!= HandleError_None)
    56 	{
    57 		return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr);
    58 	}
    59 
    60 	pBitBuf->WriteOneBit(params[2]);
    61 
    62 	return 1;
    63 }
    64 
    65 static cell_t smn_BfWriteByte(IPluginContext *pCtx, const cell_t *params)
    66 {
    67 	Handle_t hndl = static_cast<Handle_t>(params[1]);
    68 	HandleError herr;
    69 	HandleSecurity sec;
    70 	bf_write *pBitBuf;
    71 
    72 	sec.pOwner = NULL;
    73 	sec.pIdentity = g_pCoreIdent;
    74 
    75 	if ((herr=handlesys->ReadHandle(hndl, g_WrBitBufType, &sec, (void **)&pBitBuf))
    76 		!= HandleError_None)
    77 	{
    78 		return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr);
    79 	}
    80 
    81 	pBitBuf->WriteByte(params[2]);
    82 
    83 	return 1;
    84 }
    85 
    86 static cell_t smn_BfWriteChar(IPluginContext *pCtx, const cell_t *params)
    87 {
    88 	Handle_t hndl = static_cast<Handle_t>(params[1]);
    89 	HandleError herr;
    90 	HandleSecurity sec;
    91 	bf_write *pBitBuf;
    92 
    93 	sec.pOwner = NULL;
    94 	sec.pIdentity = g_pCoreIdent;
    95 
    96 	if ((herr=handlesys->ReadHandle(hndl, g_WrBitBufType, &sec, (void **)&pBitBuf))
    97 		!= HandleError_None)
    98 	{
    99 		return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr);
   100 	}
   101 
   102 	pBitBuf->WriteChar(params[2]);
   103 
   104 	return 1;
   105 }
   106 
   107 static cell_t smn_BfWriteShort(IPluginContext *pCtx, const cell_t *params)
   108 {
   109 	Handle_t hndl = static_cast<Handle_t>(params[1]);
   110 	HandleError herr;
   111 	HandleSecurity sec;
   112 	bf_write *pBitBuf;
   113 
   114 	sec.pOwner = NULL;
   115 	sec.pIdentity = g_pCoreIdent;
   116 
   117 	if ((herr=handlesys->ReadHandle(hndl, g_WrBitBufType, &sec, (void **)&pBitBuf))
   118 		!= HandleError_None)
   119 	{
   120 		return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr);
   121 	}
   122 
   123 	pBitBuf->WriteShort(params[2]);
   124 
   125 	return 1;
   126 }
   127 
   128 static cell_t smn_BfWriteWord(IPluginContext *pCtx, const cell_t *params)
   129 {
   130 	Handle_t hndl = static_cast<Handle_t>(params[1]);
   131 	HandleError herr;
   132 	HandleSecurity sec;
   133 	bf_write *pBitBuf;
   134 
   135 	sec.pOwner = NULL;
   136 	sec.pIdentity = g_pCoreIdent;
   137 
   138 	if ((herr=handlesys->ReadHandle(hndl, g_WrBitBufType, &sec, (void **)&pBitBuf))
   139 		!= HandleError_None)
   140 	{
   141 		return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr);
   142 	}
   143 
   144 	pBitBuf->WriteWord(params[2]);
   145 
   146 	return 1;
   147 }
   148 
   149 static cell_t smn_BfWriteNum(IPluginContext *pCtx, const cell_t *params)
   150 {
   151 	Handle_t hndl = static_cast<Handle_t>(params[1]);
   152 	HandleError herr;
   153 	HandleSecurity sec;
   154 	bf_write *pBitBuf;
   155 
   156 	sec.pOwner = NULL;
   157 	sec.pIdentity = g_pCoreIdent;
   158 
   159 	if ((herr=handlesys->ReadHandle(hndl, g_WrBitBufType, &sec, (void **)&pBitBuf))
   160 		!= HandleError_None)
   161 	{
   162 		return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr);
   163 	}
   164 
   165 	pBitBuf->WriteLong(static_cast<long>(params[2]));
   166 
   167 	return 1;
   168 }
   169 
   170 static cell_t smn_BfWriteFloat(IPluginContext *pCtx, const cell_t *params)
   171 {
   172 	Handle_t hndl = static_cast<Handle_t>(params[1]);
   173 	HandleError herr;
   174 	HandleSecurity sec;
   175 	bf_write *pBitBuf;
   176 
   177 	sec.pOwner = NULL;
   178 	sec.pIdentity = g_pCoreIdent;
   179 
   180 	if ((herr=handlesys->ReadHandle(hndl, g_WrBitBufType, &sec, (void **)&pBitBuf))
   181 		!= HandleError_None)
   182 	{
   183 		return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr);
   184 	}
   185 
   186 	pBitBuf->WriteFloat(sp_ctof(params[2]));
   187 
   188 	return 1;
   189 }
   190 
   191 static cell_t smn_BfWriteString(IPluginContext *pCtx, const cell_t *params)
   192 {
   193 	Handle_t hndl = static_cast<Handle_t>(params[1]);
   194 	HandleError herr;
   195 	HandleSecurity sec;
   196 	bf_write *pBitBuf;
   197 	int err;
   198 
   199 	sec.pOwner = NULL;
   200 	sec.pIdentity = g_pCoreIdent;
   201 
   202 	if ((herr=handlesys->ReadHandle(hndl, g_WrBitBufType, &sec, (void **)&pBitBuf))
   203 		!= HandleError_None)
   204 	{
   205 		return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr);
   206 	}
   207 
   208 	char *str;
   209 	if ((err=pCtx->LocalToString(params[2], &str)) != SP_ERROR_NONE)
   210 	{
   211 		pCtx->ThrowNativeErrorEx(err, NULL);
   212 		return 0;
   213 	}
   214 
   215 	pBitBuf->WriteString(str);
   216 
   217 	return 1;
   218 }
   219 
   220 static cell_t smn_BfWriteEntity(IPluginContext *pCtx, const cell_t *params)
   221 {
   222 	Handle_t hndl = static_cast<Handle_t>(params[1]);
   223 	HandleError herr;
   224 	HandleSecurity sec;
   225 	bf_write *pBitBuf;
   226 
   227 	sec.pOwner = NULL;
   228 	sec.pIdentity = g_pCoreIdent;
   229 
   230 	if ((herr=handlesys->ReadHandle(hndl, g_WrBitBufType, &sec, (void **)&pBitBuf))
   231 		!= HandleError_None)
   232 	{
   233 		return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr);
   234 	}
   235 
   236 	int index = g_HL2.ReferenceToIndex(params[2]);
   237 
   238 	if (index == -1)
   239 	{
   240 		return 0;
   241 	}
   242 
   243 	pBitBuf->WriteShort(index);
   244 
   245 	return 1;
   246 }
   247 
   248 static cell_t smn_BfWriteAngle(IPluginContext *pCtx, const cell_t *params)
   249 {
   250 	Handle_t hndl = static_cast<Handle_t>(params[1]);
   251 	HandleError herr;
   252 	HandleSecurity sec;
   253 	bf_write *pBitBuf;
   254 
   255 	sec.pOwner = NULL;
   256 	sec.pIdentity = g_pCoreIdent;
   257 
   258 	if ((herr=handlesys->ReadHandle(hndl, g_WrBitBufType, &sec, (void **)&pBitBuf))
   259 		!= HandleError_None)
   260 	{
   261 		return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr);
   262 	}
   263 
   264 	pBitBuf->WriteBitAngle(sp_ctof(params[2]), params[3]);
   265 
   266 	return 1;
   267 }
   268 
   269 static cell_t smn_BfWriteCoord(IPluginContext *pCtx, const cell_t *params)
   270 {
   271 	Handle_t hndl = static_cast<Handle_t>(params[1]);
   272 	HandleError herr;
   273 	HandleSecurity sec;
   274 	bf_write *pBitBuf;
   275 
   276 	sec.pOwner = NULL;
   277 	sec.pIdentity = g_pCoreIdent;
   278 
   279 	if ((herr=handlesys->ReadHandle(hndl, g_WrBitBufType, &sec, (void **)&pBitBuf))
   280 		!= HandleError_None)
   281 	{
   282 		return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr);
   283 	}
   284 
   285 	pBitBuf->WriteBitCoord(sp_ctof(params[2]));
   286 
   287 	return 1;
   288 }
   289 
   290 static cell_t smn_BfWriteVecCoord(IPluginContext *pCtx, const cell_t *params)
   291 {
   292 	Handle_t hndl = static_cast<Handle_t>(params[1]);
   293 	HandleError herr;
   294 	HandleSecurity sec;
   295 	bf_write *pBitBuf;
   296 
   297 	sec.pOwner = NULL;
   298 	sec.pIdentity = g_pCoreIdent;
   299 
   300 	if ((herr=handlesys->ReadHandle(hndl, g_WrBitBufType, &sec, (void **)&pBitBuf))
   301 		!= HandleError_None)
   302 	{
   303 		return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr);
   304 	}
   305 
   306 	cell_t *pVec;
   307 	pCtx->LocalToPhysAddr(params[2], &pVec);
   308 	Vector vec(sp_ctof(pVec[0]), sp_ctof(pVec[1]), sp_ctof(pVec[2]));
   309 	pBitBuf->WriteBitVec3Coord(vec);
   310 
   311 	return 1;
   312 }
   313 
   314 static cell_t smn_BfWriteVecNormal(IPluginContext *pCtx, const cell_t *params)
   315 {
   316 	Handle_t hndl = static_cast<Handle_t>(params[1]);
   317 	HandleError herr;
   318 	HandleSecurity sec;
   319 	bf_write *pBitBuf;
   320 
   321 	sec.pOwner = NULL;
   322 	sec.pIdentity = g_pCoreIdent;
   323 
   324 	if ((herr=handlesys->ReadHandle(hndl, g_WrBitBufType, &sec, (void **)&pBitBuf))
   325 		!= HandleError_None)
   326 	{
   327 		return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr);
   328 	}
   329 
   330 	cell_t *pVec;
   331 	pCtx->LocalToPhysAddr(params[2], &pVec);
   332 	Vector vec(sp_ctof(pVec[0]), sp_ctof(pVec[1]), sp_ctof(pVec[2]));
   333 	pBitBuf->WriteBitVec3Normal(vec);
   334 
   335 	return 1;
   336 }
   337 
   338 static cell_t smn_BfWriteAngles(IPluginContext *pCtx, const cell_t *params)
   339 {
   340 	Handle_t hndl = static_cast<Handle_t>(params[1]);
   341 	HandleError herr;
   342 	HandleSecurity sec;
   343 	bf_write *pBitBuf;
   344 
   345 	sec.pOwner = NULL;
   346 	sec.pIdentity = g_pCoreIdent;
   347 
   348 	if ((herr=handlesys->ReadHandle(hndl, g_WrBitBufType, &sec, (void **)&pBitBuf))
   349 		!= HandleError_None)
   350 	{
   351 		return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr);
   352 	}
   353 
   354 	cell_t *pAng;
   355 	pCtx->LocalToPhysAddr(params[2], &pAng);
   356 	QAngle ang(sp_ctof(pAng[0]), sp_ctof(pAng[1]), sp_ctof(pAng[2]));
   357 	pBitBuf->WriteBitAngles(ang);
   358 
   359 	return 1;
   360 }
   361 
   362 static cell_t smn_BfReadBool(IPluginContext *pCtx, const cell_t *params)
   363 {
   364 	Handle_t hndl = static_cast<Handle_t>(params[1]);
   365 	HandleError herr;
   366 	HandleSecurity sec;
   367 	bf_read *pBitBuf;
   368 
   369 	sec.pOwner = NULL;
   370 	sec.pIdentity = g_pCoreIdent;
   371 
   372 	if ((herr=handlesys->ReadHandle(hndl, g_RdBitBufType, &sec, (void **)&pBitBuf))
   373 		!= HandleError_None)
   374 	{
   375 		return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr);
   376 	}
   377 
   378 	return pBitBuf->ReadOneBit() ? 1 : 0;
   379 }
   380 
   381 static cell_t smn_BfReadByte(IPluginContext *pCtx, const cell_t *params)
   382 {
   383 	Handle_t hndl = static_cast<Handle_t>(params[1]);
   384 	HandleError herr;
   385 	HandleSecurity sec;
   386 	bf_read *pBitBuf;
   387 
   388 	sec.pOwner = NULL;
   389 	sec.pIdentity = g_pCoreIdent;
   390 
   391 	if ((herr=handlesys->ReadHandle(hndl, g_RdBitBufType, &sec, (void **)&pBitBuf))
   392 		!= HandleError_None)
   393 	{
   394 		return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr);
   395 	}
   396 
   397 	return pBitBuf->ReadByte();
   398 }
   399 
   400 static cell_t smn_BfReadChar(IPluginContext *pCtx, const cell_t *params)
   401 {
   402 	Handle_t hndl = static_cast<Handle_t>(params[1]);
   403 	HandleError herr;
   404 	HandleSecurity sec;
   405 	bf_read *pBitBuf;
   406 
   407 	sec.pOwner = NULL;
   408 	sec.pIdentity = g_pCoreIdent;
   409 
   410 	if ((herr=handlesys->ReadHandle(hndl, g_RdBitBufType, &sec, (void **)&pBitBuf))
   411 		!= HandleError_None)
   412 	{
   413 		return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr);
   414 	}
   415 
   416 	return pBitBuf->ReadChar();
   417 }
   418 
   419 static cell_t smn_BfReadShort(IPluginContext *pCtx, const cell_t *params)
   420 {
   421 	Handle_t hndl = static_cast<Handle_t>(params[1]);
   422 	HandleError herr;
   423 	HandleSecurity sec;
   424 	bf_read *pBitBuf;
   425 
   426 	sec.pOwner = NULL;
   427 	sec.pIdentity = g_pCoreIdent;
   428 
   429 	if ((herr=handlesys->ReadHandle(hndl, g_RdBitBufType, &sec, (void **)&pBitBuf))
   430 		!= HandleError_None)
   431 	{
   432 		return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr);
   433 	}
   434 
   435 	return pBitBuf->ReadShort();
   436 }
   437 
   438 static cell_t smn_BfReadWord(IPluginContext *pCtx, const cell_t *params)
   439 {
   440 	Handle_t hndl = static_cast<Handle_t>(params[1]);
   441 	HandleError herr;
   442 	HandleSecurity sec;
   443 	bf_read *pBitBuf;
   444 
   445 	sec.pOwner = NULL;
   446 	sec.pIdentity = g_pCoreIdent;
   447 
   448 	if ((herr=handlesys->ReadHandle(hndl, g_RdBitBufType, &sec, (void **)&pBitBuf))
   449 		!= HandleError_None)
   450 	{
   451 		return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr);
   452 	}
   453 
   454 	return pBitBuf->ReadWord();
   455 }
   456 
   457 static cell_t smn_BfReadNum(IPluginContext *pCtx, const cell_t *params)
   458 {
   459 	Handle_t hndl = static_cast<Handle_t>(params[1]);
   460 	HandleError herr;
   461 	HandleSecurity sec;
   462 	bf_read *pBitBuf;
   463 
   464 	sec.pOwner = NULL;
   465 	sec.pIdentity = g_pCoreIdent;
   466 
   467 	if ((herr=handlesys->ReadHandle(hndl, g_RdBitBufType, &sec, (void **)&pBitBuf))
   468 		!= HandleError_None)
   469 	{
   470 		return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr);
   471 	}
   472 
   473 	return static_cast<cell_t>(pBitBuf->ReadLong());
   474 }
   475 
   476 static cell_t smn_BfReadFloat(IPluginContext *pCtx, const cell_t *params)
   477 {
   478 	Handle_t hndl = static_cast<Handle_t>(params[1]);
   479 	HandleError herr;
   480 	HandleSecurity sec;
   481 	bf_read *pBitBuf;
   482 
   483 	sec.pOwner = NULL;
   484 	sec.pIdentity = g_pCoreIdent;
   485 
   486 	if ((herr=handlesys->ReadHandle(hndl, g_RdBitBufType, &sec, (void **)&pBitBuf))
   487 		!= HandleError_None)
   488 	{
   489 		return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr);
   490 	}
   491 
   492 	return sp_ftoc(pBitBuf->ReadFloat());
   493 }
   494 
   495 static cell_t smn_BfReadString(IPluginContext *pCtx, const cell_t *params)
   496 {
   497 	Handle_t hndl = static_cast<Handle_t>(params[1]);
   498 	HandleError herr;
   499 	HandleSecurity sec;
   500 	bf_read *pBitBuf;
   501 	int numChars = 0;
   502 	char *buf;
   503 
   504 	sec.pOwner = NULL;
   505 	sec.pIdentity = g_pCoreIdent;
   506 
   507 	if ((herr=handlesys->ReadHandle(hndl, g_RdBitBufType, &sec, (void **)&pBitBuf))
   508 		!= HandleError_None)
   509 	{
   510 		return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr);
   511 	}
   512 
   513 	pCtx->LocalToPhysAddr(params[2], (cell_t **)&buf);
   514 	pBitBuf->ReadString(buf, params[3], params[4] ? true : false, &numChars);
   515 
   516 	if (pBitBuf->IsOverflowed())
   517 	{
   518 		return -numChars - 1;
   519 	}
   520 
   521 	return numChars;
   522 }
   523 
   524 static cell_t smn_BfReadEntity(IPluginContext *pCtx, const cell_t *params)
   525 {
   526 	Handle_t hndl = static_cast<Handle_t>(params[1]);
   527 	HandleError herr;
   528 	HandleSecurity sec;
   529 	bf_read *pBitBuf;
   530 
   531 	sec.pOwner = NULL;
   532 	sec.pIdentity = g_pCoreIdent;
   533 
   534 	if ((herr=handlesys->ReadHandle(hndl, g_RdBitBufType, &sec, (void **)&pBitBuf))
   535 		!= HandleError_None)
   536 	{
   537 		return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr);
   538 	}
   539 
   540 	int ref = g_HL2.IndexToReference(pBitBuf->ReadShort());
   541 
   542 	return g_HL2.ReferenceToBCompatRef(ref);
   543 }
   544 
   545 static cell_t smn_BfReadAngle(IPluginContext *pCtx, const cell_t *params)
   546 {
   547 	Handle_t hndl = static_cast<Handle_t>(params[1]);
   548 	HandleError herr;
   549 	HandleSecurity sec;
   550 	bf_read *pBitBuf;
   551 
   552 	sec.pOwner = NULL;
   553 	sec.pIdentity = g_pCoreIdent;
   554 
   555 	if ((herr=handlesys->ReadHandle(hndl, g_RdBitBufType, &sec, (void **)&pBitBuf))
   556 		!= HandleError_None)
   557 	{
   558 		return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr);
   559 	}
   560 
   561 	return sp_ftoc(pBitBuf->ReadBitAngle(params[2]));
   562 }
   563 
   564 static cell_t smn_BfReadCoord(IPluginContext *pCtx, const cell_t *params)
   565 {
   566 	Handle_t hndl = static_cast<Handle_t>(params[1]);
   567 	HandleError herr;
   568 	HandleSecurity sec;
   569 	bf_read *pBitBuf;
   570 
   571 	sec.pOwner = NULL;
   572 	sec.pIdentity = g_pCoreIdent;
   573 
   574 	if ((herr=handlesys->ReadHandle(hndl, g_RdBitBufType, &sec, (void **)&pBitBuf))
   575 		!= HandleError_None)
   576 	{
   577 		return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr);
   578 	}
   579 
   580 	return sp_ftoc(pBitBuf->ReadBitCoord());
   581 }
   582 
   583 static cell_t smn_BfReadVecCoord(IPluginContext *pCtx, const cell_t *params)
   584 {
   585 	Handle_t hndl = static_cast<Handle_t>(params[1]);
   586 	HandleError herr;
   587 	HandleSecurity sec;
   588 	bf_read *pBitBuf;
   589 
   590 	sec.pOwner = NULL;
   591 	sec.pIdentity = g_pCoreIdent;
   592 
   593 	if ((herr=handlesys->ReadHandle(hndl, g_RdBitBufType, &sec, (void **)&pBitBuf))
   594 		!= HandleError_None)
   595 	{
   596 		return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr);
   597 	}
   598 
   599 	cell_t *pVec;
   600 	pCtx->LocalToPhysAddr(params[2], &pVec);
   601 
   602 	Vector vec;
   603 	pBitBuf->ReadBitVec3Coord(vec);
   604 
   605 	pVec[0] = sp_ftoc(vec.x);
   606 	pVec[1] = sp_ftoc(vec.y);
   607 	pVec[2] = sp_ftoc(vec.z);
   608 
   609 	return 1;
   610 }
   611 
   612 static cell_t smn_BfReadVecNormal(IPluginContext *pCtx, const cell_t *params)
   613 {
   614 	Handle_t hndl = static_cast<Handle_t>(params[1]);
   615 	HandleError herr;
   616 	HandleSecurity sec;
   617 	bf_read *pBitBuf;
   618 
   619 	sec.pOwner = NULL;
   620 	sec.pIdentity = g_pCoreIdent;
   621 
   622 	if ((herr=handlesys->ReadHandle(hndl, g_RdBitBufType, &sec, (void **)&pBitBuf))
   623 		!= HandleError_None)
   624 	{
   625 		return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr);
   626 	}
   627 
   628 	cell_t *pVec;
   629 	pCtx->LocalToPhysAddr(params[2], &pVec);
   630 
   631 	Vector vec;
   632 	pBitBuf->ReadBitVec3Normal(vec);
   633 
   634 	pVec[0] = sp_ftoc(vec.x);
   635 	pVec[1] = sp_ftoc(vec.y);
   636 	pVec[2] = sp_ftoc(vec.z);
   637 
   638 	return 1;
   639 }
   640 
   641 static cell_t smn_BfReadAngles(IPluginContext *pCtx, const cell_t *params)
   642 {
   643 	Handle_t hndl = static_cast<Handle_t>(params[1]);
   644 	HandleError herr;
   645 	HandleSecurity sec;
   646 	bf_read *pBitBuf;
   647 
   648 	sec.pOwner = NULL;
   649 	sec.pIdentity = g_pCoreIdent;
   650 
   651 	if ((herr=handlesys->ReadHandle(hndl, g_RdBitBufType, &sec, (void **)&pBitBuf))
   652 		!= HandleError_None)
   653 	{
   654 		return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr);
   655 	}
   656 
   657 	cell_t *pAng;
   658 	pCtx->LocalToPhysAddr(params[2], &pAng);
   659 
   660 	QAngle ang;
   661 	pBitBuf->ReadBitAngles(ang);
   662 
   663 	pAng[0] = sp_ftoc(ang.x);
   664 	pAng[1] = sp_ftoc(ang.y);
   665 	pAng[2] = sp_ftoc(ang.z);
   666 
   667 	return 1;
   668 }
   669 
   670 static cell_t smn_BfGetNumBytesLeft(IPluginContext *pCtx, const cell_t *params)
   671 {
   672 	Handle_t hndl = static_cast<Handle_t>(params[1]);
   673 	HandleError herr;
   674 	HandleSecurity sec;
   675 	bf_read *pBitBuf;
   676 
   677 	sec.pOwner = NULL;
   678 	sec.pIdentity = g_pCoreIdent;
   679 
   680 	if ((herr=handlesys->ReadHandle(hndl, g_RdBitBufType, &sec, (void **)&pBitBuf))
   681 		!= HandleError_None)
   682 	{
   683 		return pCtx->ThrowNativeError("Invalid bit buffer handle %x (error %d)", hndl, herr);
   684 	}
   685 
   686 	return pBitBuf->GetNumBitsLeft() >> 3;
   687 }
   688 
   689 REGISTER_NATIVES(bitbufnatives)
   690 {
   691 	{"BfWriteBool",				smn_BfWriteBool},
   692 	{"BfWriteByte",				smn_BfWriteByte},
   693 	{"BfWriteChar",				smn_BfWriteChar},
   694 	{"BfWriteShort",			smn_BfWriteShort},
   695 	{"BfWriteWord",				smn_BfWriteWord},
   696 	{"BfWriteNum",				smn_BfWriteNum},
   697 	{"BfWriteFloat",			smn_BfWriteFloat},
   698 	{"BfWriteString",			smn_BfWriteString},
   699 	{"BfWriteEntity",			smn_BfWriteEntity},
   700 	{"BfWriteAngle",			smn_BfWriteAngle},
   701 	{"BfWriteCoord",			smn_BfWriteCoord},
   702 	{"BfWriteVecCoord",			smn_BfWriteVecCoord},
   703 	{"BfWriteVecNormal",		smn_BfWriteVecNormal},
   704 	{"BfWriteAngles",			smn_BfWriteAngles},
   705 	{"BfReadBool",				smn_BfReadBool},
   706 	{"BfReadByte",				smn_BfReadByte},
   707 	{"BfReadChar",				smn_BfReadChar},
   708 	{"BfReadShort",				smn_BfReadShort},
   709 	{"BfReadWord",				smn_BfReadWord},
   710 	{"BfReadNum",				smn_BfReadNum},
   711 	{"BfReadFloat",				smn_BfReadFloat},
   712 	{"BfReadString",			smn_BfReadString},
   713 	{"BfReadEntity",			smn_BfReadEntity},
   714 	{"BfReadAngle",				smn_BfReadAngle},
   715 	{"BfReadCoord",				smn_BfReadCoord},
   716 	{"BfReadVecCoord",			smn_BfReadVecCoord},
   717 	{"BfReadVecNormal",			smn_BfReadVecNormal},
   718 	{"BfReadAngles",			smn_BfReadAngles},
   719 	{"BfGetNumBytesLeft",		smn_BfGetNumBytesLeft},
   720 	{NULL,						NULL}
   721 };
   722 
   723 #endif