static int GLua_BitStream_ReadBool(lua_State *L) { GLua_Bitstream_t *stream = GLua_CheckBitStream(L, 1); int val; if (!stream->reading) { luaL_error(L, "Attempted to read from a write-only bitstream"); return 0; } val = BitStream_ReadBool(&stream->stream); lua_pushboolean(L, val); return 1; }
// Message Processor void JKG_Slice_ProcessCommand_f(void) { char arg[1024] = {0}; char data[840]; int len; int i, row, col; sfxHandle_t sfx; bitstream_t stream; trap->Cmd_Argv(1, arg, 1024); len = Base128_DecodeLength(strlen(arg)); Base128_Decode(arg, strlen(arg), data, 840); BitStream_Init(&stream, (unsigned char *)data, len); BitStream_BeginReading(&stream); for (;;) { switch (BitStream_ReadBits(&stream, 4)) // Get the next instruction { case SLICECMD_EOM: // End of message return; case SLICECMD_START: // Reset data memset(&sliceData, 0, sizeof(sliceData)); sliceData.active = qtrue; // Bring up UI trap->Cvar_Set("ui_hidehud", "1"); Menus_CloseAll(); if (Menus_ActivateByName("jkg_slice")) { trap->Key_SetCatcher( trap->Key_GetCatcher() | KEYCATCH_UI & ~KEYCATCH_CONSOLE ); } Menu_ClearFocus(Menus_FindByName("jkg_slice")); // Field is locked until all data is available sliceData.fieldLocked = qtrue; break; case SLICECMD_STOP: // End the slicing minigame sliceData.active = qfalse; Menus_CloseByName("jkg_slice"); trap->Cvar_Set("ui_hidehud", "0"); trap->Key_SetCatcher( trap->Key_GetCatcher() & ~KEYCATCH_UI ); break; case SLICECMD_CONFIG: // Receive configuration sliceData.width = BitStream_ReadBits(&stream, 3) + 1; sliceData.height = BitStream_ReadBits(&stream, 3) + 1; sliceData.securityLevels = BitStream_ReadBits(&stream, 3); sliceData.warningThreshold = BitStream_ReadBits(&stream, 5); sliceData.intrusionDetection = BitStream_ReadBool(&stream); if (sliceData.intrusionDetection) { sliceData.intrusionTime = BitStream_ReadByte(&stream) * 10; } else { sliceData.intrusionTime = 0; } sliceData.intrusionStart = 0; break; case SLICECMD_REVEAL: row = BitStream_ReadBits(&stream, 3); col = BitStream_ReadBits(&stream, 3); sliceData.grid[row][col].active = 1; sliceData.grid[row][col].revealTime = trap->Milliseconds(); sliceData.grid[row][col].type = BitStream_ReadBits(&stream, 3); break; case SLICECMD_LOCK: if (BitStream_ReadBool(&stream)) { sliceData.fieldLocked = qtrue; } else { sliceData.fieldLocked = qfalse; } break; case SLICECMD_PROGLST: JKG_Slice_ProgramListReset(); sliceData.selectedProgram = -1; sliceData.programCount = BitStream_ReadBits(&stream, 4); for (i = 0; i < sliceData.programCount; i++) { Q_strncpyz(sliceData.programs[i].ID, BitStream_ReadStringBuffered(&stream), sizeof(sliceData.programs[i].ID)); Q_strncpyz(sliceData.programs[i].name, BitStream_ReadStringBuffered(&stream), sizeof(sliceData.programs[i].name)); Q_strncpyz(sliceData.programs[i].desc, BitStream_ReadStringBuffered(&stream), sizeof(sliceData.programs[i].desc)); sliceData.programs[i].type = BitStream_ReadBits(&stream, 2); } break; case SLICECMD_SHOWMSG: { int mode = BitStream_ReadBits(&stream, 2); char buffer[3][256]; BitStream_ReadString(&stream, buffer[0], 256); BitStream_ReadString(&stream, buffer[1], 256); BitStream_ReadString(&stream, buffer[2], 256); JKG_Slice_Dialog_Show(buffer[0], buffer[1], buffer[2], mode, DLGID_SERVER); } break; case SLICECMD_ENDMSG: JKG_Slice_Dialog_Close(); break; case SLICECMD_SUMMARY: // Process column summaries for (i=0; i < sliceData.width; i++) { sliceData.summaries[i].value = BitStream_ReadBits(&stream, 6); sliceData.summaries[i].alarms = BitStream_ReadBits(&stream, 4); } // Process row summaries for (i=0; i < sliceData.height; i++) { sliceData.summaries[8+i].value = BitStream_ReadBits(&stream, 6); sliceData.summaries[8+i].alarms = BitStream_ReadBits(&stream, 4); } sliceData.summariesKnown = qtrue; break; case SLICECMD_SECUPDATE: for (i = 0; i < sliceData.securityLevels; i++) { sliceData.securityState[i] = BitStream_ReadBits(&stream, 2); } break; case SLICECMD_INTRUSION: // TODO: Play sound effect? sliceData.intrusionState = BitStream_ReadBits(&stream, 2); if (sliceData.intrusionState == 1) { sliceData.intrusionStart = trap->Milliseconds(); } else { sliceData.intrusionStart = 0; } break; case SLICECMD_WARNLEVEL: sliceData.warningLevel = BitStream_ReadBits(&stream, 5); break; case SLICECMD_BLINKNODE: row = BitStream_ReadBits(&stream, 3); col = BitStream_ReadBits(&stream, 3); sliceData.grid[row][col].blinkTime = trap->Milliseconds(); sliceData.grid[row][col].blinkColor = BitStream_ReadBool(&stream); break; case SLICECMD_INITFIELD: // Ready to play sliceData.fieldLocked = qfalse; break; case SLICECMD_ALARM: sfx = trap->S_RegisterSound("sound/effects/mpalarm.wav"); trap->S_StartLocalSound(sfx, CHAN_AUTO); break; default: Com_Printf("Error processing slice command, unknown command ID\n"); return; } } }