forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   BlitzMax (http://forum.boolean.name/forumdisplay.php?f=104)
-   -   подскажите пожалуйста хороший упаковщик (http://forum.boolean.name/showthread.php?t=10386)

SBJoker 23.12.2009 00:56

Ответ: подскажите пожалуйста хороший упаковщик
 
мда а самим думать?
---
Ну обычно это наличие заголовка с нужными данными, далее сами данные потом или конец или оглавление архива.

Жека 23.12.2009 13:10

Ответ: подскажите пожалуйста хороший упаковщик
 
Цитата:

Сообщение от SBJoker (Сообщение 130569)
а он у тебя обычным способом то загружается по тому пути?

ага.

Жека 23.12.2009 13:37

Ответ: подскажите пожалуйста хороший упаковщик
 
Цитата:

Сообщение от G.A.D (Сообщение 130673)
если можно то примеры частых способов реализации структуры пак файла.

Я дам не частый, а частНый способ реализации.
А заодно (если повезёт) услышу мнения по поводу кода.

В коде представлен класс "пакера" и функции, формирующей пак-файл.
Пример работы:
1. создаём пак-файл (с помощью функции, подобной той что приведена в коде после описания класса)
Код:

'пакуем все наши ресурсы в один файл
Global packer:TPacker = New TPacker
Local resFile:String = "data.res"
fnPackResAll(resFile)

2. читаем структуру пака
Код:

'подготовка данных о ресурсах, находящихся в паке
packer.fnUnpack(resFile)

3. грузим нужные ресурсы
Код:

Local imgLogo:TImage = LoadImage(packer.fnGet(RES_IMG_LOGO))
Номера ресурсов можно сделать константами, например:
Код:

Const RES_IMG_LOGO = 1
Const RES_IMG_BUTTON = 2

Эти константы РАВНЫ порядковому номеру соответствующего ресурса в паке.
Это может быть не очень удобно, но занимает мало места.
Опираясь на приведённый код довольно просто можно сделать вместо порядкового номера вводимые на этапе формирования пака идентификаторы, хоть числовые хоть строковые.
Лишь дописать проверку на их уникальность, и поиск в паке.

Напоминаю, что шрифты таким образом (сразу в память из потока) грузить оказалось невозможным.
Как вариант - распаковывать их в темп. Но тогда чё - после закрытия проги удалять их? А если не удалять, то эти лишний "мусор", и проще их сразу хранить в папке с данными и всё.

Вот код.

Код:

'класс TPacker - упаковщик/распаковщик игровых ресурсов
Type TPacker
        Field list:TList = New TList
        'Field listTmp:TList = New TList 'список распакованных в темп
        Field resCount, size, k, path:String
        Field file:TStream
        Field bank:TBank
        Field seekData, seek
        Field masSizes[]
       
       
        'добавление файла в список для последующей запаковки
        Method fnAdd(ppath:String)
                path = ppath.ToLower()
                If(list.Contains(path) = True) Return
                list.AddLast(path)
        End Method
       
       
        'запаковка всего что в списке в файл
        Method fnPack(fileName:String)
               
                If(list.IsEmpty()) Return
                resCount = list.Count()
                file = WriteFile(fileName)
                WriteInt(file, resCount)
               
                For path = EachIn list
                        If(FileType(path) <> 1)
                                RuntimeError("file not found: " + path)
                        Else
                                size = FileSize(path)
                                WriteInt(file, size)
                                'DebugLog "sz = " + size
                        EndIf
                Next
               
                For path = EachIn list
                        If(FileType(path) <> 1)
                                RuntimeError("file not found: " + path)
                        Else
                                bank = LoadBank(path)
                                WriteBank(bank, file, 0, bank.Size())
                        EndIf
                Next
                CloseFile(file)
        End Method
       
       
        '"распаковка". получение информации о содержимом файла ресурсов
        Method fnUnpack(fileName:String)
               
                If(FileType(fileName) <> 1) Return
               
                file = ReadFile(fileName)
               
                resCount = ReadInt(file)
               
                masSizes = New Int[resCount]
               
                For k = 0 Until resCount
                        size = ReadInt(file)
                        masSizes[k] = size
                Next
               
                seekData = StreamPos (file)
               
                CloseFile(file)
               
                path = fileName
        End Method
       
       
        'получение ресурса по индексу, т.е. по порядковому номеру в файле ресурсов
        Method fnGet:TStream(id)
                If(id < 0 Or id > resCount - 1) Return Null
               
                seek = seekData
                For k = 0 Until id
                        seek:+masSizes[k]
                Next
               
                file = ReadFile(path)
                SeekStream(file, seek)
               
                bank = CreateBank()
               
                Local stream:TStream = OpenStream(bank)
               
                For k = 0 Until masSizes[id]
                        WriteByte(stream, ReadByte(file))
                Next
               
                CloseFile(file)
               
                FlushStream(stream)
                SeekStream(stream, 0)
                bank = Null
               
                Return stream
        End Method
       
       
        'извлечение во временную папку ресурса по индексу
        'возвращает путь к распакованному файлу
        Method fnUnpackToTemp:String(id, fileName:String)
                If(id < 0 Or id > resCount - 1) Return Null
               
                seek = seekData
                For k = 0 Until id
                        seek:+masSizes[k]
                Next
               
                file = ReadFile(path)
                SeekStream(file, seek)
               
                CreateDir("temp")
               
                Local stream:TStream = WriteFile("temp\" + fileName)
                               
                For k = 0 Until masSizes[id]
                        WriteByte(stream, ReadByte(file))
                Next
               
                CloseFile(file)
                CloseFile(stream)
               
                Return "temp\" + fileName
               
        End Method
       
       
        'удаление файлов из временной папки
        Method fnClearTemp()
                Local files:String[] = LoadDir("temp")
                Local fn:String
               
                For fn = EachIn files
                        DebugLog "fn = " + fn
                        'DeleteFile("temp\" + fn)
                        'CloseFile(WriteFile("temp\" + fn))
                Next
               
        End Method
       
       
        'очистка информации
        Method fnClear()
                list.Clear()
                path = ""
                masSizes = Null
        End Method
       
End Type

'запаковываем наши ресурсы
Function fnPackResAll(packFile:String = "data.res")
       
        packer.fnAdd("pointer.png")  '0
        packer.fnAdd("main.png")  '1
        packer.fnAdd("buttonUp.png")  '2
        packer.fnAdd("buttonDown.png")  '3
        packer.fnAdd("buttons\btnScreenShot1.png")  '4
        packer.fnAdd("buttons\btnScreenShot2.png")  '5
        packer.fnAdd("buttons\btnScreenShot3.png")  '6
        packer.fnAdd("buttons\btnStart1.png")  '7
        packer.fnAdd("buttons\btnStart2.png")  '8
        packer.fnAdd("buttons\btnStart3.png")  '9
       
        packer.fnAdd("fonts\usual.ttf")  '10
        packer.fnAdd("fonts\digit.ttf")  '11
        packer.fnAdd("fonts\xyz.ttf")  '12
        packer.fnAdd("fonts\bounds.ttf")  '13
       
        packer.fnAdd("buttonUpSmall.png")  '14
        packer.fnAdd("buttonDownSmall.png")  '15
       
        packer.fnAdd("logo.png") '16
       
        packer.fnAdd("viewKrug.png") '17
       
        packer.fnAdd("particles\serdce.png") '18
        packer.fnAdd("particles\pentagon.png") '19
        packer.fnAdd("particles\star.png") '20
        packer.fnAdd("particles\star2.png") '21
               
        packer.fnPack(packFile)

               
End Function


G.A.D 24.12.2009 01:22

Ответ: подскажите пожалуйста хороший упаковщик
 
Спасибо,Жека!но не понял(
А как по научному называеться процесс архивирования файла в пак файл?
Архивация или Шифрование?
П.с если кто-то знает стятьи или книги по описанию процесса ,если не трудно киньте либо в тему либо в ЛС

impersonalis 24.12.2009 02:00

Ответ: подскажите пожалуйста хороший упаковщик
 
Кодирование.
Кодирование может выполнтяться с целью - архивации (повышения энтропии сообщения), шифрования, повышения помехоустойчивости (уменьшение энтропии).
В твоём случае - архивация. Если ещё и с паролем - шифрование.

Жека 24.12.2009 06:18

Ответ: подскажите пожалуйста хороший упаковщик
 
Цитата:

Сообщение от G.A.D (Сообщение 130839)
Спасибо,Жека!но не понял(

А что именно ты не понял? Я понятнее могу, если спросишь что именно ты не уяснил. ;)


Часовой пояс GMT +4, время: 22:45.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Перевод: zCarot