sv_nchan.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. /*
  2. Copyright (C) 1996-1997 Id Software, Inc.
  3. This program is free software; you can redistribute it and/or
  4. modify it under the terms of the GNU General Public License
  5. as published by the Free Software Foundation; either version 2
  6. of the License, or (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. See the GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, write to the Free Software
  13. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  14. */
  15. // sv_nchan.c, user reliable data stream writes
  16. #include "qwsvdef.h"
  17. // check to see if client block will fit, if not, rotate buffers
  18. void ClientReliableCheckBlock(client_t *cl, int maxsize)
  19. {
  20. if (cl->num_backbuf ||
  21. cl->netchan.message.cursize >
  22. cl->netchan.message.maxsize - maxsize - 1) {
  23. // we would probably overflow the buffer, save it for next
  24. if (!cl->num_backbuf) {
  25. memset(&cl->backbuf, 0, sizeof(cl->backbuf));
  26. cl->backbuf.allowoverflow = true;
  27. cl->backbuf.data = cl->backbuf_data[0];
  28. cl->backbuf.maxsize = sizeof(cl->backbuf_data[0]);
  29. cl->backbuf_size[0] = 0;
  30. cl->num_backbuf++;
  31. }
  32. if (cl->backbuf.cursize > cl->backbuf.maxsize - maxsize - 1) {
  33. if (cl->num_backbuf == MAX_BACK_BUFFERS) {
  34. Con_Printf ("WARNING: MAX_BACK_BUFFERS for %s\n", cl->name);
  35. cl->backbuf.cursize = 0; // don't overflow without allowoverflow set
  36. cl->netchan.message.overflowed = true; // this will drop the client
  37. return;
  38. }
  39. memset(&cl->backbuf, 0, sizeof(cl->backbuf));
  40. cl->backbuf.allowoverflow = true;
  41. cl->backbuf.data = cl->backbuf_data[cl->num_backbuf];
  42. cl->backbuf.maxsize = sizeof(cl->backbuf_data[cl->num_backbuf]);
  43. cl->backbuf_size[cl->num_backbuf] = 0;
  44. cl->num_backbuf++;
  45. }
  46. }
  47. }
  48. // begin a client block, estimated maximum size
  49. void ClientReliableWrite_Begin(client_t *cl, int c, int maxsize)
  50. {
  51. ClientReliableCheckBlock(cl, maxsize);
  52. ClientReliableWrite_Byte(cl, c);
  53. }
  54. void ClientReliable_FinishWrite(client_t *cl)
  55. {
  56. if (cl->num_backbuf) {
  57. cl->backbuf_size[cl->num_backbuf - 1] = cl->backbuf.cursize;
  58. if (cl->backbuf.overflowed) {
  59. Con_Printf ("WARNING: backbuf [%d] reliable overflow for %s\n",cl->num_backbuf,cl->name);
  60. cl->netchan.message.overflowed = true; // this will drop the client
  61. }
  62. }
  63. }
  64. void ClientReliableWrite_Angle(client_t *cl, float f)
  65. {
  66. if (cl->num_backbuf) {
  67. MSG_WriteAngle(&cl->backbuf, f);
  68. ClientReliable_FinishWrite(cl);
  69. } else
  70. MSG_WriteAngle(&cl->netchan.message, f);
  71. }
  72. void ClientReliableWrite_Angle16(client_t *cl, float f)
  73. {
  74. if (cl->num_backbuf) {
  75. MSG_WriteAngle16(&cl->backbuf, f);
  76. ClientReliable_FinishWrite(cl);
  77. } else
  78. MSG_WriteAngle16(&cl->netchan.message, f);
  79. }
  80. void ClientReliableWrite_Byte(client_t *cl, int c)
  81. {
  82. if (cl->num_backbuf) {
  83. MSG_WriteByte(&cl->backbuf, c);
  84. ClientReliable_FinishWrite(cl);
  85. } else
  86. MSG_WriteByte(&cl->netchan.message, c);
  87. }
  88. void ClientReliableWrite_Char(client_t *cl, int c)
  89. {
  90. if (cl->num_backbuf) {
  91. MSG_WriteChar(&cl->backbuf, c);
  92. ClientReliable_FinishWrite(cl);
  93. } else
  94. MSG_WriteChar(&cl->netchan.message, c);
  95. }
  96. void ClientReliableWrite_Float(client_t *cl, float f)
  97. {
  98. if (cl->num_backbuf) {
  99. MSG_WriteFloat(&cl->backbuf, f);
  100. ClientReliable_FinishWrite(cl);
  101. } else
  102. MSG_WriteFloat(&cl->netchan.message, f);
  103. }
  104. void ClientReliableWrite_Coord(client_t *cl, float f)
  105. {
  106. if (cl->num_backbuf) {
  107. MSG_WriteCoord(&cl->backbuf, f);
  108. ClientReliable_FinishWrite(cl);
  109. } else
  110. MSG_WriteCoord(&cl->netchan.message, f);
  111. }
  112. void ClientReliableWrite_Long(client_t *cl, int c)
  113. {
  114. if (cl->num_backbuf) {
  115. MSG_WriteLong(&cl->backbuf, c);
  116. ClientReliable_FinishWrite(cl);
  117. } else
  118. MSG_WriteLong(&cl->netchan.message, c);
  119. }
  120. void ClientReliableWrite_Short(client_t *cl, int c)
  121. {
  122. if (cl->num_backbuf) {
  123. MSG_WriteShort(&cl->backbuf, c);
  124. ClientReliable_FinishWrite(cl);
  125. } else
  126. MSG_WriteShort(&cl->netchan.message, c);
  127. }
  128. void ClientReliableWrite_String(client_t *cl, char *s)
  129. {
  130. if (cl->num_backbuf) {
  131. MSG_WriteString(&cl->backbuf, s);
  132. ClientReliable_FinishWrite(cl);
  133. } else
  134. MSG_WriteString(&cl->netchan.message, s);
  135. }
  136. void ClientReliableWrite_SZ(client_t *cl, void *data, int len)
  137. {
  138. if (cl->num_backbuf) {
  139. SZ_Write(&cl->backbuf, data, len);
  140. ClientReliable_FinishWrite(cl);
  141. } else
  142. SZ_Write(&cl->netchan.message, data, len);
  143. }