-- Input and output functions for grid maps local worldpath = mapgen_rivers.world_data_path local floor = math.floor local sbyte, schar = string.byte, string.char local unpk = unpack -- Loading files -- Never load the full map during mapgen. Instead, create an empty lookup table -- and read the file on-the-fly when an element is requested for the first time, -- using __index metamethod. local loader_mt = { __index = function(loader, i) -- Called when accessing a missing key local file = loader.file local bytes = loader.bytes file:seek('set', (i-1)*bytes) local strnum = file:read(bytes) local n = sbyte(strnum, 1) if loader.signed and n >= 128 then n = n - 256 end for j=2, bytes do n = n*256 + sbyte(strnum, j) end if loader.conv then n = loader.conv(n) end -- Cache key for next use loader[i] = n return n end, } function mapgen_rivers.load_file(filename, bytes, signed, size, converter) local file = io.open(worldpath .. filename, 'rb') if file then converter = converter or false return setmetatable({file=file, bytes=bytes, signed=signed, size=size, conv=converter}, loader_mt) end end -- Writing files function mapgen_rivers.write_file(filename, data, bytes) local file = io.open(worldpath .. filename, 'wb') local bytelist = {} for j=1, bytes do bytelist[j] = 0 end for i=1, #data do local n = floor(data[i]) data[i] = n for j=bytes, 2, -1 do bytelist[j] = n % 256 n = floor(n / 256) end bytelist[1] = n % 256 file:write(schar(unpk(bytelist))) end file:close() end