save.inc
save.inc
CPP1/****h* PawnLibs/save2 * Summary3 * A helper library for packing and unpacking application state data.4 * Description5 * Pawn works with cells which has a size of 4 bytes. Native interfaces6 * handling generic data like application state have size limits for that7 * data. If application does not need to work with a large numbers, several8 * values can be packed into a single cell. This library provides some9 * convenient functions to pack and unpack such values from array of cells10 * which can be saved or loaded on/from flash.11 * Example12 * TBD13 * History14 * * v6.0 - added15 ******/16#define CELL_BITS 3217new save_pos = 0;1819new saveArray[GAME_SAVE_SIZE];2021/****f* PawnLibs/save/SaveReset22 * Summary23 * Reset state before storing new data to pack.24 * Synopsis25 */26SaveReset()27/*28 * Source29 */30{31 save_pos = 0;32 for (new i = 0; i < GAME_SAVE_SIZE; i++) {33 saveArray[i] = 0;34 }35}36/******/3738/****f* PawnLibs/save/SaveWriteValue39 * Summary40 * Store specified number of bits from some unsigned value.41 * Synopsis42 */43SaveWriteValue(value, bits)44/*45 * Inputs46 * * value - a value to store data from47 * * bits - a number of bits to store48 * Source49 */50{5152 if (SaveCheckOverflow(bits)) return;5354 if (value < 0) {55 LOG_i("SaveMessage::WriteInt: negative value %d may be sent incorrectly, use WriteSignedInt instead ", value);56 }57 new freeBits = SaveGetFreeBits();5859 if (freeBits >= bits) {60 SaveWriteData(SaveTrim(value, bits, 0), bits);61 } else {62 SaveWriteData(SaveTrim(value, freeBits, 0), freeBits);63 SaveWriteData(SaveTrim(value, bits - freeBits, freeBits), bits - freeBits);64 }6566}67/******/6869/****f* PawnLibs/save/SaveWriteSignedValue70 * Summary71 * Store specified number of bits from some signed value.72 * Synopsis73 */74SaveWriteSignedValue(value, bits)75/*76 * Inputs77 * * value - a value to store data from78 * * bits - a number of bits to store79 * Source80 */81{82 if (SaveCheckOverflow(bits + 1)) return;8384 SaveWriteValue((value >> (CELL_BITS - 1)) & 0x1, 1);85 SaveWriteValue(ABS(value), bits);8687}88/******/8990/****f* PawnLibs/save/SaveReadValue91 * Summary92 * Read specified number of bits of packed unsigned value.93 * Synopsis94 */95SaveReadValue(bits)96/*97 * Inputs98 * * bits - a number of bits to get99 * Return value100 * Unpacked unsigned value.101 * Source102 */103{104 if (SaveCheckOverflow(bits)) return 0;105106 new value = 0;107 new freeBits = SaveGetFreeBits();108 new intermediate_result;109110 if (SaveGetFreeBits() >= bits) {111 value = saveArray[SaveGetCell()] << (SaveGetFreeBits() - bits);112 value = value >>> (SaveGetFreeBits() - bits + SaveGetBits());113 save_pos += bits;114 } else {115 value = saveArray[SaveGetCell()] >>> (SaveGetBits());116 save_pos += freeBits;117118 intermediate_result = (saveArray[SaveGetCell()] << (CELL_BITS - (bits - freeBits))) >>> (CELL_BITS - (bits - freeBits));119 value |= intermediate_result << freeBits;120 save_pos += bits - freeBits;121 }122123 return value;124}125/******/126127/****f* PawnLibs/save/SaveReadSignedValue128 * Summary129 * Read specified number of bits of packed signed value.130 * Synopsis131 */132SaveReadSignedValue(bits)133/*134 * Inputs135 * * bits - a number of bits to get136 * Return value137 * Unpacked signed value.138 * Source139 */140{141 if (SaveCheckOverflow(bits + 1)) return 0;142143 new value = SaveReadValue(1) == 0 ? 1 : - 1;144 value *= SaveReadValue(bits);145146 return value;147}148/******/149150/****f* PawnLibs/save/SaveSetData151 * Summary152 * Populate state with a new data to unpack.153 * Synopsis154 */155SaveSetData(const pkt[], size)156/*157 * Inputs158 * * pkt - application state data to unpack159 * Source160 */161{162 for (new i = 0; i < size; i++)163 saveArray[i] = pkt[i];164}165/*166 * See also167 * * ON_Init()168 * * ON_Load()169 ******/170171/****f* PawnLibs/save/SaveGetData172 * Summary173 * Get packed data to store on flash.174 * Synopsis175 */176SaveGetData()177/*178 * Return value179 * Packed data to store.180 * Source181 */182{183 return saveArray;184}185/*186 * See also187 * * saveState()188 ******/189190191SaveGetCell() {192 return save_pos / CELL_BITS;193}194SaveGetBits() {195 return save_pos % CELL_BITS;196}197SaveGetFreeBits() {198 return CELL_BITS - save_pos % CELL_BITS;199}200SaveCheckOverflow(bits) {201 if (save_pos + bits > GAME_SAVE_SIZE * 32) {202 LOG_i("SaveMessage: maximum message size exceeded");203 return true;204 }205206 return false;207}208SaveTrim(value, bits, right) {209 return (value << (CELL_BITS - bits - right)) >>> (CELL_BITS - bits);210}211SaveWriteData(value, bits) {212 saveArray[SaveGetCell()] |= value << SaveGetBits();213 save_pos += bits;214}215216
Wrapped for easier reading. Turn wrap off to inspect exact line lengths.