簡體   English   中英

這段Tiled C ++代碼有什么作用?

[英]What does this piece of Tiled C++ code do?

我試圖從Tiled實用程序的地圖格式文檔中找出這段代碼的目的。

const int gid = data[i] |
                data[i + 1] << 8 |
                data[i + 2] << 16 |
                data[i + 3] << 24;

看起來有一些“or-ing”和位移,但我不知道這是什么目的,在使用平鋪程序的數據的情況下。

Tiled將其“Global Tile ID”(GID)數據層存儲在32位整數數組中,在XML文件中進行base64編碼和(可選)壓縮。

根據文檔,這些32位整數以小端格式存儲 - 也就是說,整數的第一個字節包含數字的最低有效字節。 作為類比,在十進制中,在little-endian中寫入數字“1234”看起來像4321 - 4是數字中最不重要的數字(表示僅為4的值), 3是下一個 - 最少 -顯着(代表30),依此類推。 這個例子和Tiled正在做的唯一區別是我們使用十進制數字,而Tiled使用的是字節,這些字節實際上是數字,每個數字可以容納256個不同的值而不是10個。

但是,如果我們用十進制數來考慮代碼,實際上很容易理解它在做什么。 它基本上通過這樣做來重建數字中的整數值:

int digit[4] = { 4, 3, 2, 1 }; // our decimal digits in little-endian order
int gid = digit[0] +
          digit[1] * 10 +
          digit[2] * 100 +
          digit[3] * 1000;

它只是將每個數字移動到位以創建完整的整數值。 (在二進制中,以8的倍數進行位移,就像乘以十進制的10的冪;它將值移入下一個“有效數字”槽中)

關於big-endian和little-endian的更多信息以及為什么差異很重要可以在On Holy Wars和A Plea For Peace中找到 ,這是1980年的重要(並且有趣的書面)文件,其中Danny Cohen認為需要標准化網絡協議的單字節排序。 (劇透:big-endian最終贏得了這場戰斗,因此整數的大端表示現在是表示文件和網絡傳輸中整數的標准方式 - 並且已經持續了數十年.Tiled使用小端整數文件格式有點不尋常。導致需要像您引​​用的代碼一樣的代碼,以便可靠地將數據文件中的小端整數轉換為計算機的本機格式。如果他們將數據存儲為標准的大端格式,每個操作系統提供標准的實用程序函數,用於從big-endian到native進行來回轉換,你可以簡單地調用ntohl()來組裝本機格式的整數,而不需要手動編寫和理解這種字節操作代碼)。

如您所述, <<運算符將位向左移位給定數字。

該塊采用data[]數組,該數組有四個(可能是一個字節)元素,並將這四個值“編碼”為一個整數。

示例時間!

data[0] = 0x3A; // 0x3A =  58 = 0011 1010 in binary
data[1] = 0x48; // 0x48 =  72 = 0100 1000 in binary
data[2] = 0xD2; // 0xD2 = 210 = 1101 0010 in binary
data[3] = 0x08; // 0x08 =   8 = 0000 1000 in binary

int tmp0 = data[0];       // 00 00 00 3A = 0000 0000 0000 0000 0000 0000 0011 1010
int tmp1 = data[1] << 8;  // 00 00 48 00 = 0000 0000 0000 0000 0100 1000 0000 0000
int tmp2 = data[2] << 16; // 00 D2 00 00 = 0000 0000 1101 0010 0000 0000 0000 0000
int tmp3 = data[3] << 24; // 08 00 00 00 = 0000 1000 0000 0000 0000 0000 0000 0000

// "or-ing" these together will set each bit to 1 if any of the bits are 1
int gid = tmp1 | // 00 00 00 3A = 0000 0000 0000 0000 0000 0000 0011 1010
          tmp2 | // 00 00 48 00 = 0000 0000 0000 0000 0100 1000 0000 0000
          tmp3 | // 00 D2 00 00 = 0000 0000 1101 0010 0000 0000 0000 0000
          tmp4;  // 08 00 00 00 = 0000 1000 0000 0000 0000 0000 0000 0000

gid == 147998778;// 08 D2 48 3A = 0000 1000 1101 0010 0100 1000 0011 1010

現在,您剛剛將四個單字節值編碼為一個四字節整數。

如果你(理所當然)想知道,為什么有人想要在你只使用byte並將四個單字節數據直接存儲到四個byte時完成所有工作,那么你應該看看這個問題:

在背靠背for循環中的int,short,byte性能


獎金示例!

為了獲得您的編碼值,我們使用“and”運算符和右移>>

int gid = 147998778;    // 08 D2 48 3A = 0000 1000 1101 0010 0100 1000 0011 1010

// "and-ing" will set each bit to 1 if BOTH bits are 1

int tmp0 = gid &        // 08 D2 48 3A = 0000 1000 1101 0010 0100 1000 0011 1010
           0x000000FF;  // 00 00 00 FF = 0000 0000 0000 0000 0000 0000 1111 1111
int data0 = tmp0;       // 00 00 00 3A = 0000 0000 0000 0000 0000 0000 0011 1010

int tmp1 = gid &        // 08 D2 48 3A = 0000 1000 1101 0010 0100 1000 0011 1010
           0x0000FF00;  // 00 00 FF 00 = 0000 0000 0000 0000 1111 1111 0000 0000
tmp1;      //value of tmp1 00 00 48 00 = 0000 0000 0000 0000 0100 1000 0000 0000
int data1 = tmp1 >> 8;  // 00 00 00 48 = 0000 0000 0000 0000 0000 0000 0100 1000

int tmp2 = gid &        // 08 D2 48 3A = 0000 1000 1101 0010 0100 1000 0011 1010
           0x00FF0000;  // 00 FF 00 00 = 0000 0000 1111 1111 0000 0000 0000 0000
tmp2;      //value of tmp2 00 D2 00 00 = 0000 0000 1101 0010 0000 0000 0000 0000
int data2 = tmp2 >> 16; // 00 00 00 D2 = 0000 0000 0000 0000 0000 0000 1101 0010

int tmp3 = gid &        // 08 D2 48 3A = 0000 1000 1101 0010 0100 1000 0011 1010
           0xFF000000;  // FF 00 00 00 = 1111 1111 0000 0000 0000 0000 0000 0000
tmp3;      //value of tmp3 08 00 00 00 = 0000 1000 0000 0000 0000 0000 0000 0000
int data3 = tmp3 >> 24; // 00 00 00 08 = 0000 0000 0000 0000 0000 0000 0000 1000

不需要tmp3的最后一個“和”,因為在移位時“掉落”的位剛剛丟失並且進入的位為零。 所以:

gid;                   // 08 D2 48 3A = 0000 1000 1101 0010 0100 1000 0011 1010
int data3 = gid >> 24; // 00 00 00 08 = 0000 0000 0000 0000 0000 0000 0000 1000

但我想提供一個完整的例子。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM