Новости:

01.01.2017: Релиз испанской версии Naruto - Ninja Council (GBA)
02.12.2016: Добавлена документация по Kruptar 7
09.10.2015: Обновление перевода игры Battletoads (NES) [версия 1.3]
22.01.2015: Kruptar Open Source
18.10.2014: Релиз обновлённой русской версии Castlevania - Dawn of Sorrow (GBA) от Owls Group
01.05.2014: Релиз русской версии Taiyou no Yuusha Firebird (NES)
24.06.2012: Добавлена доработанная документация и инструкция
26.05.2012: Обновление ORITON [версия 2.050]
11.05.2012: Обновление ORITON [версия 2.048]
11.03.2012: Обновление Kruptar 7 [версия 7.1.1.17]
29.01.2012: Обновление LZ77Restructor 2 [версия 1.02]
01.01.2012: Релиз русской версии Drill Dozer (GBA)

Подробнее на страничке новостей.
Ознакомьтесь с правилами нашего форума.

Главное меню

Kruptar

Автор Alex, 20 февраля 2009, 14:02:55

« назад - далее »

0 Пользователи и 3 гостей просматривают эту тему.

inside

Цитата: Hatsuyuki от 11 ноября 2011, 00:05:45Извините, вы длину строки обсуждаете?
Хочу сделать подсчет ширины (в пикселях) результирующей строки чтобы не проверять каждый раз запуская ром.

Строка -> Заменяем символы по таблице -> Список байтов -> Цикл по байтам -> Найти для каждого байта из массива ширин размер -> Суммируем -> ??? -> Профит

(:

Сложнее все это в интерфейс впихнуть, это окошкодергание ааахххх, WinAPI и то проще, так что не скоро разберусь даже с этим :(
I wanna be a romhacker

Hatsuyuki

ценителей троллинга
Вообще говоря, в типографике это называется "длиной строки" (line length) и измеряется в миллиметрах (пикселях, пунктах).



Цитата: http://slovari.yandex.ru/%D0%B8%D0%BD%D1%82%D0%B5%D1%80%D0%BB%D0%B8%D0%BD%D1%8C%D1%8F%D0%B6/%D0%98%D0%B7%D0%B4%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D1%81%D0%BA%D0%B8%D0%B9%20%D1%81%D0%BB%D0%BE%D0%B2%D0%B0%D1%80%D1%8C/%D0%9A%D0%B5%D0%B3%D0%BB%D1%8C%20%28%D0%BA%D0%B5%D0%B3%D0%B5%D0%BB%D1%8C%29/К шрифтовому оформлению доп. и вспом. текста объемом более 2000 знаков в изданиях группы А СанПиН предъявляют требования, установленные для осн. текста этих изданий. При К. шрифта в них более 10 п. необходимо, чтобы минимальная длина строки была не менее 3 3/4 кв. (68 мм).

Длину строки определяют, измеряя линейкой одну полноформатную строку на каждой из 10 контролируемых страниц. Отклонение длины строки от установленного санитарными правилами допускается не более чем на 10%.

Англоязычные источники (пока) не привожу %)
А мне, кстати, можно исходники Круптара? Сейчас как проведу аудит кода! Вот только Кнута дочитаю 8)
Otium sine litteris mors est et hominis vivi sepultura.

Джинни

В программировании длиной строки называют количество символов в ней.

TrickZter

Цитата: Hatsuyuki от 11 ноября 2011, 03:37:07Вообще говоря, в типографике это называется "длиной строки" (line length) и измеряется в миллиметрах (пикселях, пунктах).
Казалось бы, причём тут типография?  :D

В программировании это называется шириной строки, про длину тебе Джин уже сказал.
Вот кусок справки из Delphi в качестве доказательства (а то ж не поверишь):


Hatsuyuki

Речь идёт о графическом представлении текста, поэтому уместно использовать термины типографики ::)

Где определена-то "ширина строки"? В справке VCL?

В более-менее теоретизированных работах по программированию вообще графикой не заморачиваются. Прикладуха проклятая :P
Otium sine litteris mors est et hominis vivi sepultura.

TrickZter

Цитата: Hatsuyuki от 11 ноября 2011, 19:05:37
Речь идёт о графическом представлении текста, поэтому уместно использовать термины типографики ::)
С типографическими терминами иди в другие разделы форума. В программировании (а мы сейчас обсуждаем именно его) это называется шириной. Длиной же называется количество символов в строке.
Цитата: Hatsuyuki от 11 ноября 2011, 19:05:37Где определена-то "ширина строки"? В справке VCL?
В любой нормальной документации по программированию, в том числе и в VCL справке.

Джинни

Цитата: Hatsuyuki от 12 ноября 2011, 03:05:37Речь идёт о графическом представлении текста, поэтому уместно использовать термины типографики Строит глазки
Есть у тебя string length - количество символов в строке. И string width - ширина области в пикселях, которую занимает строка. Так что какие тут могут быть термины типографики?

Alex

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

TrickZter

Цитата: Alex от 13 ноября 2011, 21:31:39А почему нельзя реализовать выдирание текста тупо по поинтерам? Каждый раз писать плагин, где стоп-байт участвует в кодах игры, - занятие весьма сомнительное...
Что значит "тупо по поинтерам"? Как по-твоему круптар узнает, что строка закончилась? Если конец строки можно однозначно отличить от исполняемого кода, то круптар и так выдерет всё как надо. Если отличить невозможно, то без спецсредств (плагина или специальной проги) не обойтись.

Цитата: Alex от 13 ноября 2011, 21:31:39Каждый раз писать плагин, где стоп-байт участвует в кодах игры, - занятие весьма сомнительное...
Где ты этот "каждый раз" видел? Круптар умеет выдирать текст из 99.9% игр без всяких дополнительных плагинов.

Anton

Цитата: TriсkZter от 13 ноября 2011, 22:32:05Где ты этот "каждый раз" видел?

Из тех проектов, что делал для меня Алекс - это Zelda Ocarina (N64) и Zelda Twilight Princess (GC/Wii).

Вот в твайлайт принцесс, например:
код пиктограммы кнопки,: 1A050000
(стопбайт - 00)

ну и почти во всех кодах "00" есть:
1A0600003702=<$Count_05>
1A06FF000000=<$White>
1A06FF000001=<$Red>
1A06FF000002=<$Green>
1A06FF000003=<$Blue>
1A06FF000004=<$Yellow>
1A06FF000006=<$Purple>
1A06FF000007=<$Silver>

В "Окарине" (стопбайт = 02):
0E02=[fade:02] (один из параметров времени отображения плашки с текстом, если не ошибаюсь)
1302=[icon_3] - пиктограмма одного из предметов при его получении.
1E02=[score_2] - количество очков в одной из мини-игр

Phantom Hourglass (NDS) (стопбайт: 0000):
1A0008FF00000000={Tag 168}
1A0008FF00000100={Tag 169}
(и таких кодов штук 200)



Alex

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

ЦитироватьЧто значит "тупо по поинтерам"? Как по-твоему круптар узнает, что строка закончилась? Если конец строки можно однозначно отличить от исполняемого кода, то круптар и так выдерет всё как надо. Если отличить невозможно, то без спецсредств (плагина или специальной проги) не обойтись.

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

TrickZter

Цитата: Anton от 13 ноября 2011, 23:30:55
В "Окарине" (стопбайт = 02):
0E02=[fade:02] (один из параметров времени отображения плашки с текстом, если не ошибаюсь)
1302=[icon_3] - пиктограмма одного из предметов при его получении.
1E02=[score_2] - количество очков в одной из мини-игр
И из-за такой ерунды вы писали плагины?  *facepalm* Это никакой не исполняемый код, а обычные спецсимволы. С ними круптар и так умеет корректно работать, надо просто перечислить их в таблице:

0E02=[fade:02]
1302=[icon_3]
1E02=[score_2]

Если так сделать, он не будет считать их стоп-байтами.

В других играх так же можно обойтись составлением нормальной таблицы.
Примерно так:
1A06=<Сolor>
FF000004=<$Yellow>
FF000006=<$Purple>
FF000007=<$Silver>
Если их 200 штук, значит нужно перечислить все 200 - сложного в этом ничего нет.

Цитата: Alex от 14 ноября 2011, 00:56:50Так поинтеры для того и нужны, чтобы указывать длину строки. Вот по этой длине текст и выдирать. Считываем первый поинтер и последующий - получаем длину строки, ну и пошло-поехало :)
Поинтеры нужны для определения начала строки, определять конец по ним зачастую невозможно.
Во-первых, на одну и ту же строку может ссылаться несколько поинтеров.
Во-вторых, между строк может располагаться исполняемый код (а не то, что вы тут написали), на который тоже есть свои поинтеры.
В-третьих, как ты узнаешь где кончается последняя строка?

Джинни

Цитата: Alex от 14 ноября 2011, 08:56:50Так поинтеры для того и нужны, чтобы указывать длину строки
Пойнтеры нужны для того, чтобы указывать на то, где строка находится. Длину строки обычно не указывают, а если указывают, то отдельным значением рядом со строкой или рядом с пойнтером.
Цитата: Alex от 14 ноября 2011, 08:56:50Вот по этой длине текст и выдирать. Считываем первый поинтер и последующий - получаем длину строки, ну и пошло-поехало Улыбка
Пойнтеры очень часто не идут по порядку. Редко можно вычислить длину строки таким образом.

Добавлено позже после небольших раздумий:

Цитата: TriсkZter от 14 ноября 2011, 15:10:51С ними круптар и так умеет корректно работать, надо просто перечислить их в таблице:

0E02=[fade:02]
1302=[icon_3]
1E02=[score_2]

Если так сделать, он не будет считать их стоп-байтами.

В других играх так же можно обойтись составлением нормальной таблицы.
Примерно так:
1A06=<Сolor>
FF000004=<$Yellow>
FF000006=<$Purple>
FF000007=<$Silver>
Когда стандартные плагины круптара встречают стопбайт, считывание останавливается, даже если этот байт находится в одном из контрольных кодов.
Вы не можете написать универсальный плагин, который будет понимать, где надо останавливаться, а где не надо, потому что таблица не передаётся плагину как параметр. А если бы передавалась, нужно было бы каждый код проверять при извлечении. В круптаре извлечение идёт отдельно, быстрым циклом плагина, а декодирование по таблице - отдельно, внутри программы.

TrickZter

Цитата: Джинни от 14 ноября 2011, 08:44:26В круптаре извлечение идёт отдельно, быстрым циклом плагина, а декодирование по таблице - отдельно, внутри программы.
Понятно, значит такая фишка не прокатит.  *F_DISAPPOINTED*

Я в своих программах делаю иначе: полностью гружу файл в оперативку, после чего декодирую код в текст. Конец строки ищет сама декодирующая функция.

Джинни

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

TrickZter

Цитата: Джинни от 14 ноября 2011, 09:03:13Просто плагины в круптаре предназначены именно для извлечения/декомпрессии строк, чтобы потом их можно было декодировать любой таблицей в самой программе.
Понятно. А можно сделать плагин с настраиваемым списком исключений? Чтобы он пропускал стоп-байты, которые являются частью комбинаций, входящих в чёрный список? Такой плагин на корню решил бы проблему.

Джинни

Можно написать плагин, который будет загружать параметры из отдельного файла настроек.

HoRRoR_X

Джинни, можешь рассказать, как правильно парсить kdt-файл в проекте Kruptar 7 с учётом ранних версий?
Пишу кое-какой инструментарий в качестве диплома, хочу добавить возможности экспорта/импорта. :)

Джинни

8 байт: подпись; // 'KRUPTAR7'
x байт: имя исходного рома;  // строка в особом формате
x байт: имя изменяемого рома; // строка в особом формате
4 байта:
     Значение первых двух бит:
     (0: ANSI кодировка windows по умолчанию;
      1: кодировка UTF-16;
      2: кодировка SHIFT_JIS;
      3: настоящая кодировка указана в следующих 16 битах значения);
Если бит номер 24 значения равен 1, то:
4 байта: флаги проекта; // описание флагов позже

Иначе:
флаги = 0

4 байта: количество таблиц;

Цикл считывания таблиц:
{
x байт: имя таблицы; // строка в особом формате (в кодировке UTF-8, если в комментарии к архиву DOS_FNames = false)
Загрузка таблицы;
}

4 байта: количество групп;

Цикл считывания групп:
{
x байт: имя группы; // строка в особом формате (в кодировке UTF-8, если в комментарии к архиву DOSFNames = false)
     загрузка txt файла группы в память;
x байт: имя плагина; // строка в особом формате
4 байта: если не ноль, то:
{
  4 байта: максимальный размер слова;
  4 байта: номер таблицы;
  4 байта: (0: little endian; иначе: big endian);
  4 байта: начало отсчёта для кодов таблицы словаря;
  4 байта: размер кода таблицы словаря;
  4 байта: длина строки;
  x байт: строка с первыми байтами, с которых будет начинаться код таблицы словаря;
}

4 байта: количество диапазонов для вставки текста;
массив диапазонов:
{
  4 байта: начальный адрес;
  4 байта: количество байт;
}

4 байта: количество списков;
Цикл считывания списков:
{
  x байт: имя списка; // уникодовая строка в особом формате
  4 байта: номер таблицы для декодирования текста;
  4 байта: номер таблицы для кодирования текста;
  4 байта: номер группы словаря;
  4 байта: последняя выбранная строка для отображения в программе;
  4 байта: ptStringLength;
  4 байта: ptReference;
  4 байта: ptPointerSize;
  4 байта: ptAlignment (для выравнивания строк при вставке);
  4 байта: ptCharSize (1: обычная строка: 2: уникодо-подобная);
  4 байта: ptInterval;
  4 байта: ptShiftLeft (для сдвига значений пойнтеров);
  4 байта:
  Если бит 31 равен нулю, то:
  {
    бит 0: endian (little/big);
    4 байта: ptAutoPtrStart (0: ничего; 1: ptReference равен адресу каждого из пойнтеров);
    4 байта: ptSplittedPtrs (0: ничего; 1: байты пойнтера находятся в разных местах);
    4 байта: ptAutoStart (0: ничего; 1: ptReference равен адресу таблицы пойнтеров);
  }
  Иначе:
  {
   бит 0: endian (little/big);
   бит 1: ptAutoPtrStart;
   бит 2: ptSplittedPtrs;
   бит 3: ptAutoStart;
   бит 4: ptPtrToPtr (указатель на указатель);
   бит 5: ptSeekSame (поиск одинаковых строк при вставке);
   бит 6: ptNotInSource (строка не извлекается);
   бит 7: загрузка дополнительных значений для вставки;
   {
    4 байта: ptDestReference;
    4 байта: ptDestPointerSize;
    4 байта: ptDestStringLength;
    4 байта: ptDestAlignment;
    4 байта: ptDestCharSize;
    4 байта: ptDestAutoPtrStart;
    4 байта:
    {
     бит 0: ptDestSplittedPtrs;
     бит 1: ptDestSnesLoRom;
    }
   }
   бит 8: ptSnesLoRom;
  }
 
  4 байта: количество "околопойнтерных переменных";
  4 байта: количество байт перед пойнтером;
  4 байта: количество занимаемых байт после пойнтера;
  4 байта: количество занимаемых байт перед пойнтером;
  Цикл чтения информации о переменных:
  {
   x байт: имя переменной; // строка в особом формате
   4 байта: (0: после пойнтера; 1: перед пойнтером)
   4 байта: тип переменной (0: Byte; 1: Word; 2: ShortInt; 3: SmallInt; 4: LongInt);
   4 байта: флаги (бит 0: endian (little/big); бит 1: переменная содержит длину строки);   
  }

  4 байта: количество пойнтеров в списке
  Цикл считывания пойнтеров и строк:
  {
   4 байта: значение пойнтера
   4 байта: pnPtrPos
   4 байта: pnReference
   4 байта:
   {
    бит 0: pnFixed (0: ничего; 1: пойнтер не изменяется)
    Если бит 31 равен 1:
    {
     4 байта: pnDestPtrPos
     4 байта: pnDestReference
    }
    Иначе:
    {
     pnDestPtrPos = pnPtrPos
     pnDestReference = pnReference
    }
   }
   4 байта: номер таблицы для декодирования строки
   4 байта: номер таблицы для кодирования строки
   4 байта: длина блока значений переменных
   x байт: значения "околопойнтерных переменных"

   4 байта: количество строковых элементов в текстовом файле
   Загрузка оригинальной строки (строк) из рома с помощью плагина;
   Загрузка изменённой строки (строк) из буфера с текстом.
  }
} // конец считывания списка
} // конец считывания группы
------------------------------------------------------

Описание строки в особом формате:
1 байт:
если равен единице, то:

4 байта: длина строки
x байт: строка

иначе:
x байт: строка включая первый байт до нуля
------------------------------------------------------

Описание уникодовой строки в особом формате:
2 байта:
если равно единице, то:

4 байта: длина строки
x байт: строка в формате UTF-8

иначе:
x байт: строка включая первые два байт в формате UTF-16 до нуля
------------------------------------------------------

Флаги проекта
бит 0: не показывать в тексте первый в списке CRLF-код
бит 1: не учитывать код окончания строки при создании таблицы словаря

JurasskPark

Почему никто не использует тэг код?

Джинни

Это не код.

HoRRoR_X

Спасибо большое! :)

Джинни


JurasskPark

Цитата: Джинни от 27 февраля 2012, 11:53:24Это не код.
Зато листать меньше и скопировать текст удобнее.  :P

Oraculum

Цитата: JurasskPark от 27 февраля 2012, 18:43:46Зато листать меньше и скопировать текст удобнее.  :P
Неудобно, хочется как-то на весь экран это растянуть.