Chief-NET

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » Chief-NET » Базовый хакинг » Помогите новичку с переводом


Помогите новичку с переводом

Сообщений 101 страница 120 из 152

101

...Значит нужно добавлять не 2, а 3. И это было бы разумнее с точки зрения эффективности алгоритма сжатия. Сам посуди, какой смысл сжимать 2 байта двумя же байтами? Никакого. С точки зрения эффективности лучше всего за 0 принять длину в три байта. На ГБА, кстати, как раз и прибавляется 3.

Правильно, это мой пронос, там нужно 3 прибавлять.

102

Обнаружил вот такой отрывок кода в памяти приставки:
AA 55 55 AA AA 55 55 AA AA 55 55 AA AA 55 55 AA

В роме же эта последовательность сжата следующим образом:
AA 55 55 AA 94 7E

То есть здесь скопировали не один байт, как в разобранных выше примерах, а 4 байта.

1001 0100 0111 1110

С байтом 94 всё понятно, он действительно указывает на байт AA, а вот глядя на последние 5 бит становится уже не понятно:
11110=30
Прибавив 3, получаем 33.

Т.е. процесс копирования мне нужно повторить 33 раза (вместо положенных 3-х раз) =) Возможно немного неверно предположение, что последние 5 бит - это биты, отвечающие за кол-во циклов копирования..
И, исходя из того, что тут копируется сразу 4 байта, где-то здесь должно быть указание на кол-во копируемых байтов.

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

пока[b] [/i]последующий бит равен предыдущему[/i] [b]начало
          считаю кол-во одинаковых байт, увеличивая счётчик на 1.
конец цикла
если кол-во одинаковых байт больше 3 то
          сжимаю данные
иначе
          записываю их без изменения
конец условия

Можно попробовать реализовать проверку ещё и на наличие одинаковых байт через определённый интервал, но что-то я не понимаю как это реализовать...

p.s. Здесь начинает посещать мысль о том, что легче распаковать и запаковать все нужные данные вручную.. Причём распаковка - это просто копирование байт из памяти эмулятора.

Отредактировано Ace Lightning (2011-05-20 23:49:07)

103

Обнаружил вот такой отрывок кода в памяти приставки:
AA 55 55 AA AA 55 55 AA AA 55 55 AA AA 55 55 AA

В роме же эта последовательность сжата следующим образом:
AA 55 55 AA 94 7E

То есть здесь скопировали не один байт, как в разобранных выше примерах, а 4 байта.

1001 0100 0111 1110

С байтом 94 всё понятно, он действительно указывает на байт AA, а вот глядя на последние 5 бит становится уже не понятно:
11110=30
Прибавив 3, получаем 33.

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

Рассмотрим этот пример:
AA 55 55 AA AA 55 55 AA AA 55 55 AA AA 55 55 AA
AA 55 55 AA 94 7E

94 указывает на AA, и начиная с него копируем 33 байта.

Вот смотри как это происходит, подчёркнутый байт - это откуда копируем, жирный байт - это куда копируем.

Копируется первый байт:
AA 55 55 AA AA
Потом второй:
AA 55 55 AA AA 55
Потом третий:
AA 55 55 AA AA 55 55
Потом четвёртый:
AA 55 55 AA AA 55 55 AA
Потом пятый:
AA 55 55 AA AA 55 55 AA AA
Потом шестой:
AA 55 55 AA AA 55 55 AA AA 55
и так всего 33 раза.

И неважно, что начиная с пятого байта у нас началось самокопирование. Кстати благодаря такому самокопированию в рамках LZ отлично реализуется и RLE. Пример:
Допустим у нас ссылка на последний из уже распакованных байтов, а скопировать нужно пять байт, тогда копирование будет выглядеть так:
Копируется первый байт:
11 22 33 44 44
Потом второй:
11 22 33 44 44 44
Потом третий:
11 22 33 44 44 44 44
И наконец четвёртый:
11 22 33 44 44 44 44 44

Разумеется самокопированием LZ не ограничивается. Обычно просто копируется определённый участок байтов из ранее распакованных. Рассмотрим пример. Допустим у нас есть уже такая последовательность байт:
11 22 33 44 55 66 77 88 99 AA BB CC DD
Ссылка идёт на байт 22, а скопировать нужно 5 байт. Тогда процесс копирования будет выглядеть так:
Копируется первый байт:
11 22 33 44 55 66 77 88 99 AA BB CC DD 22
Потом второй:
11 22 33 44 55 66 77 88 99 AA BB CC DD 22 33
Потом третий:
11 22 33 44 55 66 77 88 99 AA BB CC DD 22 33 44
Потом четвёртый:
11 22 33 44 55 66 77 88 99 AA BB CC DD 22 33 44 55
И наконец пятый:
11 22 33 44 55 66 77 88 99 AA BB CC DD 22 33 44 55 66

Отредактировано TrickZter (2011-05-21 10:46:25)

104

А вот написать запаковщик я пока затрудняюсь, т.к. чисто визуально-то видно что можно сжать представленную выше последовательность, но как это определить программно, я сказать затрудняюсь.

Нужно проводить поиск максимально длинного идентичного отрезка, если таковой не найден или найден, но длина его меньше 3-х, то записать 1 байт в незапакованном виде. И дальше проводить поиск для другого байта. Ты не на делфях, случаем, программиш? Могу дать код похожей функции.

105

Понятно, эх.. вот сессию сдам и доделаю программу.
Программирую я на Visual Basic, т.к. не знаю где лучше писать программы и выбрал там, где попроще))

106

Ну, хз, по-моему ничего проще делфей нету :)

Вот так выглядит моя функция запаковки GBAшного LZ77:

Код:
Function BINtoLZ(Src,Res: PArr; Size: Longword; Mode:byte):LongWord;
Var
  ResP,SrcP,Back,MaskP,MaskN: Longword;
  Max,Cur,MaxB:Word;
Begin
  SetLength(Res^,6);
  Res^[0]:=$10;
  Res^[1]:=Size and $FF;
  Res^[2]:=(Size shr 8) and $FF;
  Res^[3]:=(Size shr 16) and $FF;
  Res^[4]:=0;
  Res^[5]:=SRC^[0];
  MaskP:=4; //Позиция маски
  ResP:=6;  //Позиция в результирующем массиве
  SrcP:=1;  //Позиция в исходном массиве
  MaskN:=7; //Позиция в маске
  Repeat
    If MaskN=0 then begin  //Смена маски
      MaskP:=ResP;
      Inc(ResP);
      SetLength(Res^,ResP);
      MaskN:=8;
    End;
    Back:=Mode+1;
    Max:=0; //Максимальный размер копируемых данных
    MaxB:=0;
    While (Back<=$1000) and (Back<=SrcP) and (Max < $F+3) and (SrcP+Max<Size) do Begin //Поиск самого длинного повторяющегося отрезка
      Cur:=0; //Текущий размер
      While (Src^[SrcP+Cur]=Src^[SrcP-Back+Cur]) and (SrcP+Cur<Size) and (Cur<$F+3) do Inc(Cur);
      If (Cur>=3) and (Cur>Max) then begin
        Max:=Cur;
        MaxB:=Back;
      End;
      Inc(Back);
    End;
    If Max=0 then begin //Если подходящий отрезок не найден
      SetLength(Res^,ResP+1);
      Res^[ResP]:=Src^[SrcP];
      Dec(MaskN);
      Inc(ResP);
      Inc(SrcP);
    End
      Else begin //Если найден
        SetLength(Res^,ResP+2);
        Res^[ResP]:=((Max-3) shl 4)+((MaxB-1) shr 8);
        Res^[ResP+1]:=(MaxB-1) and $FF;
        Inc(ResP,2);
        Inc(SrcP,Max);
        Dec(MaskN);
        Inc(Res^[MaskP],1 shl MaskN);
      end;
  Until SrcP>=Size;
  Result:=ResP;
End;

Src - это исходный (не пожатый) массив байтов, Res - массив, в который вносятся сжимаемые данные. А сама функция возвращает размер пожатых данных.

Отредактировано TrickZter (2011-05-21 10:58:03)

107

мм.. класс, что ещё сказать))
Мне можно, в принципе, перебраться и на Делфи (т.к. в университете писали на Turbo Pascal, а его синтасис чем-то похож). Только он хорошо работает в Windows 7? и какую лучше версию ставить? ))

И кстати: вот название алгоритма LZ это понятно, а что значат цифры 77?

Отредактировано Ace Lightning (2011-05-21 11:14:19)

108

мм.. класс, что ещё сказать))
Мне можно, в принципе, перебраться и на Делфи (т.к. в университете писали на Turbo Pascal, а его синтасис чем-то похож). Только он хорошо работает в Windows 7? и какую лучше версию ставить? ))

Разумеется похож, Делфи - это прямой потомок паскаля :) Самой популярной версией делфи до сих пор является Borland Delphi 7. Сам я сижу под Windows 7 x64, проблем с делфями нет.

И кстати: вот название алгоритма LZ это понятно, а что значат цифры 77?

LZ разный бывает, а LZ77 - одна из его разновидностей. Почитать подробнее можно в википедии:
http://ru.wikipedia.org/wiki/LZ77
Но даже тот же самый LZ77 в разных играх и на разных платформах может реализовываться по-разному. Например, у тебя тоже LZ77, только организован он немного иначе: другой порядок бит во флаговом байте, другие биты используется для смещения и длины, смещение считается иначе.

109

Разумеется похож, Делфи - это прямой потомок паскаля :) Самой популярной версией делфи до сих пор является Borland Delphi 7. Сам я сижу под Windows 7 x64, проблем с делфями нет.

Хм, может и в самом деле пересесть на Делфи. В университете постоянно приходится работать с паскалем, да ещё первокурсникам каждый год задачи решаю. Подумаю... во всяком случае это будет не раньше, чем у меня закончатся экзамены :)

110

Джин подсказывает, что правильно этот алгоритм называется LZSS, хотя в документации по тем же GBA и NDS этот алгоритм ошибочно обзывают LZ77 (это другой тип LZ).

Добавлено:

он не очень другой, LZSS - это улучшенная версия LZ77 :)
отличается LZ77 от LZSS тем, что в первом даже однобайтовые куски кодируются несколькими байтами :)

Отредактировано TrickZter (2011-05-22 09:17:34)

111

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

112

Вот ещё что хотел спросить: для распаковщика входными данными является путь к рому, начало блока графика и конец блока графики. Правильно ли это?

А как ты конец нашёл? Проще всего реализовать программу, если в качестве входных данных дать: 1) имя файла, 2) координату начала запакованных данных, 3) размер данных, которые хотим получить на выходе.
Если не задать размер, то алгоритм позволяет "распаковывать" всё подряд - хоть до конца рома, и на выходе ты получишь распакованную картинку плюс СОТНИ хлама, следующие за ней.

или можно как-то программно определять алгоритм сжатия и не задавать начального и конечного значений блоков графики?

С точки зрения реализации гораздо проще указать программе все данные самому. Хотя используя различные методы программу можно научить находить что-то похожее на пожатые ресурсы, но гарантий никаких нет, ведь практически любую последовательность байтов можно попытаться так или иначе "распаковать" и получить на выходе бесполезный мусор.

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

Отредактировано TrickZter (2011-05-23 04:25:36)

113

А как ты конец нашёл?

Конец я нашёл просто посмотрев в эмуляторе код тайла, который нужно распаковать последним и нашёл его в роме. :)

А размер данных мне как узнать? Просто умножить кол-во тайлов на кол-во байт, которыми записаны тайлы?

114

А размер данных мне как узнать?

Умножить количество тайлов на размер тайла в байтах. Если графика в формате 8BPP (на один пиксель приходится 8 бит или 1 байт), то размер одного тайла будет 8x8=64 байта, если 4BPP (на один пиксель приходится 4 бита или половина байта), то размер тайла будет 8x8/2=32 байта. 2BPP и 1BPP в ГБА играх встречаются крайне редко, но посчитать, думаю, будет несложно :)

Отредактировано TrickZter (2011-05-23 10:53:48)

115

Ну да, я так и предполагал :)

116

Если есть у кого время, помогите перевести предложение, выделенное жирным. А то что-то никак не могу правильно понять весь его смысл:

Dracula:
You have done well, my girl. In fact, you are the first human who has come this far. You have my praise.
Sonia:
You are the Prince of Darkness. Because of you many people have died, many people have suffered.
Dracula:
Oh no, my dear. have merely done what you humans wished for, fulfilling your insatiable desires.
Sonia:
People must fulfill their dreams with their own power. You who have been consumed by the power of evil no longer have the strength to determine your own fate!
Dracula:
Silence! On the contrary, I am just the one to use this power, and I will be the king who rules over the entire world. Give yourself to me, young lady. There may be merit in having your power, in having your presence.
Sonia:
My strength will only be used to protect the world! Lord of Darkness, prepare to suffer for trifling with so many lives!
Dracula:
As you wish, girl. Then it is your fate to kneel before my power!

117

There may be merit in having your power, in having your presence.
Думаю, больше всего тебя смутило слово merit. :) В данном случае его можно перевести как "ценность". То есть Дракула буквально говорит следующее: "Возможно есть ценность иметь твою силу, иметь твоё присутствие".
Если говорить по-русски, то выходит что-то типа: "Возможно ты и твоя сила мне пригодятся". Можно, конечно, написать и как-то иначе, как-нибудь более пафосно.  :)

Отредактировано TrickZter (2011-05-29 17:29:27)

118

Ну смысл этого предложения сначала мне показался в том, что как бы ценность силы Сони именно в том, что она жива. Как бы умерев ни её сила, ни она сама будет уже не нужна.

119

Судя по тексту, он в любом случае не собирается её убивать:
Then it is your fate to kneel before my power!
Хотя, амеры могли так просто выпилить слово "умереть", типа чтобы "уменьшить" уровень насилия :)

Отредактировано TrickZter (2011-05-29 17:47:01)

120

Да, они могут :)
Ладно, буду думать над вариантами. Спасибо за помощь :)


Вы здесь » Chief-NET » Базовый хакинг » Помогите новичку с переводом