Перейти к содержимому

Фотография

Вскрываем визуалки


  • Авторизуйтесь для ответа в теме
Сообщений в теме: 27

#1 dsp8195

dsp8195
  • Старожилы
  • PipPipPip
  • Отаку

  • Cообщений: 449
0
Обычный

Отправлено 28 Май 2007 - 12:41

Насколько мне известно, до нас доходят либо версии, "адаптированные" для США, либо пиратские рипы (что, в принципе, одно и тоже). Разумеется, русского языка в них не наблюдается.

Потому я и работал над программой AnimED, чтобы стало возможным самостоятельно перевести тексты и графику в меню и задниках (это, собственно, и есть "аниме-моддинг в чистом виде". Сомневаюсь, что у нас кто-то захочет переозвучить или перерисовать персонажей, ибо это испортит стиль и атмосферу).

Вполне возможно, что кто-то уже сделал утилиты для вскрытия (у "Триады" они точно были, т.к. я встречал переведённую графику в их релизах).

Но, сделать нечто подобное самостоятельно, да ещё и получить бесценную экспу в кодинге...

Поэтому, кто сказал, что моддинг необходим только хитам вроде The Elder Scrolls IV? И "маленькие" игры заслуживают внимания (особенно если в них подчас заложено столько юмора и жизнерадостности, сколько нет ни в какой GTA).


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

Поскольку сейчас объём реверз-инженируемого кода более не органичивается одними только архивами визуалок, рекомендую вести дискуссию по вскрываемым форматам именно здесь. Тем более, что есть повод. ;)

Сообщение отредактировал WinKi-тян: 02 Февраль 2008 - 18:18

  • 0

#2 u-jinn

u-jinn
  • Старожилы
  • PipPipPipPipPipPip
  • missing element

  • Cообщений: 2 436
72
Няшка

Отправлено 29 Май 2007 - 21:47

Эмм.. Если поставить прогу, будет русский перевод? Или он не входит в архив?
  • 0

#3 JaveLiner

JaveLiner
  • Старожилы
  • PipPipPipPipPip
  • くそ食らえ

  • Cообщений: 1 503
0
Обычный

Отправлено 29 Май 2007 - 21:55

Что-то мне подсказывает, что это дохлый номер.
  • 0

#4 dsp8195

dsp8195
  • Старожилы
  • PipPipPip
  • Отаку

  • Cообщений: 449
0
Обычный

Отправлено 02 Февраль 2008 - 18:23

Serke, несколько минут назад я получил исходники кода анпакера графики в формате GGP, который наповерку оказался шифрованным по ксор-ключу PNG.

//It's compressed, but not that difficult. Just a masked PNG.
//The structure as follows: (don't care about the member names!)

typedef unsigned long UInt32; // 32-bit unsigned integer
typedef unsigned short UInt16; // 16-bit unsigned integer

struct GGP {
	char sig[8] = "GGPFAIKE"; // master string
	UInt32 depth; // 0:use image's value / 32:ARGB / 24:RGB
	char xor[8]; // sub string
	UInt32 offset, length;
	UInt32 regionOffset, regionLength;
	char ggxRegion[regionLength];
	char data[length];  // masked PNG image
};

struct GGxRegion {
	UInt16 destLeft, destTop; // destination position
	UInt16 left, top, width, height; // source bounds
};

//The data can be unmasked using xor-ing (GGP.sig xor GGP.xor) (confusing!)
//so an unoptimized code would be:

for(i = 0; i < length; i++)
		data[i] ^= sig[i % 8] ^ xor[i % 8];

//ggxRegion is used for overlay images of the message window and the like.

  • 0

#5 Solanacean

Solanacean
  • Активные участники
  • PipPip
  • Soulless & fractured

  • Cообщений: 111
0
Обычный

Отправлено 19 Февраль 2008 - 17:58

Поскольку депресняк пока не думает отступать, а время идет, решил кинуть код анпакера GGD в таком виде, в каком он есть. Он полностью работоспособен, не хватает разве что комментариев и кода проверки GGD-файлов по идентификатору.

#include <stdio.h>
#include <windows.h>

int ExtractGGD( HANDLE hFile, BYTE *pDst, DWORD Size );
int BufferizedRead( HANDLE hFile, BYTE *lpBuf, DWORD NumOfBytesToRead, BOOL IsInit );

int main( int argc, char **argv)
{
	struct t_GGDHeader {
		BYTE id[4];
		WORD width;
		WORD height;
	} GGDHeader;

	char szoutf[ MAX_PATH ];
	HANDLE hFile, hOutf;
	DWORD BytesRead, BytesWritten, DataLen;
	BYTE *pGGDData;

	printf( "IKURA GGD images extractor 0.01\n" );
	printf( "Extraction code is a courtesy of IKURA;-)\n" );

	if( argc > 1 )
	{ 
		hFile = CreateFile( argv[1], GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
							FILE_ATTRIBUTE_NORMAL, NULL );

		if( hFile != INVALID_HANDLE_VALUE )
		{
			ReadFile( hFile, &GGDHeader, sizeof( GGDHeader ), &BytesRead, NULL );
			DataLen = ( ( ( GGDHeader.width * 3 + 3 ) >> 2 ) << 2 ) * GGDHeader.height;
			pGGDData = (BYTE *)malloc( DataLen );
			ExtractGGD( hFile, pGGDData, DataLen );
			wsprintf( szoutf, "%s%s", argv[1], ".unpacked" );
			hOutf = CreateFile( szoutf, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS,
								FILE_ATTRIBUTE_NORMAL, NULL ); 
			WriteFile( hOutf, pGGDData, DataLen, &BytesWritten, NULL );
			free( pGGDData );
			CloseHandle( hOutf );
			CloseHandle( hFile );
		}
		else
			printf( "Cannot open file %s\n", argv[1] );
	}
	else
		printf( "Usage: unpack_ggd filename<.ggd>\n" );

	return 0;
}

//////////////////////////////////////////////////////////////////////////////
// Глобальные переменные, используемые ф-ей BufferizedRead //

struct t_cyc_buf {
	BYTE array1[0x800];
	BYTE array2[0x800];
} cyc_buf;

DWORD DataBlockLen;
BYTE *pDataBlockCurrByte;
BOOL IsLastBlock;

int ExtractGGD( HANDLE hFile, BYTE *pDst, DWORD Size )
{
	BYTE *pDstEnd, *pSrc;
	BYTE ctrlb;
	BYTE buf[8];
	int i;  
  
	BufferizedRead( NULL, NULL, 0, TRUE ); // инициализация глобальных переменных используемых ф-ей BufferizedRead()
	pDstEnd = Size + pDst;
		
	while( pDst < pDstEnd ) 
	{
		if( BufferizedRead( hFile, &ctrlb, 1, FALSE ) == -1 )
			return 1;
		switch( ctrlb )
		{

			case 0:

				if( BufferizedRead( hFile, buf, 1, FALSE ) == -1 )
					return 1;

				buf[1] = *( pDst - 3 );
				buf[2] = *( pDst - 2 );
				buf[3] = *( pDst - 1 );

				for( i = 0; i < buf[0]; i++ )
				{
					*pDst++ = buf[1];
					*pDst++ = buf[2];
					*pDst++ = buf[3];
				}
				break;

			case 1:

				if( BufferizedRead( hFile, buf, 2, FALSE ) == -1 )
					return 1;
				pSrc = pDst - ( buf[1] * 3 );
				for( i = 0; i < buf[0] * 3; i++ )
					*pDst++ = *pSrc++;
				break;

			case 2:

				if( BufferizedRead( hFile, buf, 3, FALSE ) == -1 ) 
					return 1;
				pSrc = pDst - MAKEWORD( buf[1], buf[2] ) * 3;
				for( i = 0; i < buf[0] * 3; i++ )
					*pDst++ = *pSrc++;
				break;

			case 3:

				if( BufferizedRead( hFile, buf, 1, FALSE ) == -1 )
					return 1;
				pSrc = pDst - ( buf[0] * 3 );
				*pDst++ = *pSrc++;
				*pDst++ = *pSrc++;
				*pDst++ = *pSrc;
				break;

			case 4:

				if( BufferizedRead( hFile, buf, 2, FALSE ) == -1 )
					return 1;
				pSrc = pDst - MAKEWORD( buf[0], buf[1] ) * 3;
				*pDst++ = *pSrc++;
				*pDst++ = *pSrc++;
				*pDst++ = *pSrc;
				break;

			default:

				for( i = 0; i < ctrlb - 4; i++ )
				{
					if( BufferizedRead( hFile, buf, 3, FALSE ) == -1 )
						return 1;
					*pDst++ = buf[0];
					*pDst++ = buf[1];
					*pDst++ = buf[2];
				}
				break;
		}
	}
	return 1;
}

int BufferizedRead( HANDLE hFile, BYTE *lpBuf, DWORD NumOfBytesToRead, BOOL IsInit )
{
	int i;
	void *pTemp;
	DWORD BytesRead;
	
	if( IsInit )
	{
		pDataBlockCurrByte = NULL;
		DataBlockLen = 0;
		IsLastBlock = FALSE;

		return 0;
	}
	if( pDataBlockCurrByte == NULL )
	{
		ReadFile( hFile, cyc_buf.array1, 0x1000, &DataBlockLen, NULL );
		if( DataBlockLen < 0 )
			return -1;
		pDataBlockCurrByte = cyc_buf.array1;
		if( DataBlockLen < 0x1000 )
			IsLastBlock = TRUE;
	} 
	if( (DataBlockLen <= 0) || (DataBlockLen < NumOfBytesToRead) )
		return -1;
	for( i = 0; i < NumOfBytesToRead; i++ )
	{
		lpBuf[ i ] = *pDataBlockCurrByte++;
		DataBlockLen--;
		if( pDataBlockCurrByte > &cyc_buf.array2[0x7FF] )
			pDataBlockCurrByte = cyc_buf.array1;
	}
	if( (DataBlockLen >= 0x800) || IsLastBlock )
		return NumOfBytesToRead;

	pTemp = cyc_buf.array1;
	
	if( pDataBlockCurrByte < cyc_buf.array2 )
		pTemp = cyc_buf.array2;
	
	ReadFile( hFile, pTemp, 0x800, &BytesRead, NULL ); 

	if( BytesRead >= 0 )
	{
		if( BytesRead < 0x800 )
			IsLastBlock = TRUE;

		DataBlockLen += BytesRead;
		return NumOfBytesToRead;
	}

	IsLastBlock = TRUE;
	return NumOfBytesToRead;
}

Идентификатор id в GGDHeader это строка (НЕ оканчивающаяся нулем) зашифрованная по методу NOT (или XOR 0xFF, если так больше нравится). Может иметь значения 'FULL', 'HIGH', '256G' и возможно, какие-то еще.

Если будешь писать конвертер графики, выложу соответствующую информацию.

Функция буферизованого чтения (BufferizedRead) вытащена исключительно из любви к искусству. Тебе она, по большому гамбургскому счету, нафиг не нужна - проще прочитать один раз весь файл в память, а затем 'скармливать' его функции распаковки по кусочкам, как это делает анпакер GG2.

Вопросы сюда. >__<

EDIT: слегка подправил код.

Сообщение отредактировал Serke: 19 Февраль 2008 - 18:13

  • 0

#6 dsp8195

dsp8195
  • Старожилы
  • PipPipPip
  • Отаку

  • Cообщений: 449
0
Обычный

Отправлено 19 Февраль 2008 - 19:47

Спасибо! -_-

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

FULL - видимо, 24-битные.
HIGH - 16-и.
256G - 256-цветные с палитрой.

Сообщение отредактировал WinKi-тян: 19 Февраль 2008 - 19:52

  • 0

#7 Solanacean

Solanacean
  • Активные участники
  • PipPip
  • Soulless & fractured

  • Cообщений: 111
0
Обычный

Отправлено 11 Март 2008 - 04:42

WinKi, ты когда-нибудь с NScripter'ом работал? У меня проблема - экзешник из скачанного архива с последней версией NScripter'а отказывается работать с игрой на базе более старой версии движка, выдавая в качестве объяснения какой-то мунспик =). Собственно, меня интересует, нужно ли каким-то образом обрабатывать взятые "из коробки" экзешники движков онскриптера и энскриптера напильником для каждой конкретной игры.

P.S. NScripter "внутри" просто кошмарен. Код настолько уродлив, что им можно детей пугать...

Сообщение отредактировал Serke: 11 Март 2008 - 04:44

  • 0

#8 dsp8195

dsp8195
  • Старожилы
  • PipPipPip
  • Отаку

  • Cообщений: 449
0
Обычный

Отправлено 11 Март 2008 - 08:43

nScripter устарел (и пользоваться им не стоит, даже переключив язык системы для не-Unicode программ на японский - код там действительно ужасен).

OnScripter - иной разговор. Доводить EXE до нужной кондиции, как правило, не требуется (только русский он, зараза, всё равно не держит - для этого был придуман POnScripter (скину ссылку на мой экземпляр исходников в личку - они, кхм, неофициальные) ).

Однако, об этом уже говорили на Gemot'е: существует так называемый "прародитель" - Scripter3 (или как там его). В общем, не совместим он с асм-подобным языком nScripter'а. ;);
  • 0

#9 Solanacean

Solanacean
  • Активные участники
  • PipPip
  • Soulless & fractured

  • Cообщений: 111
0
Обычный

Отправлено 11 Март 2008 - 18:22

WinKi, наверное, мне нужно было объяснить мою задачу. Я ищу способ хакнуть движок NScripter'а так, чтобы он воспринимал однобайтовые символы и производил text wrapping, также пытаюсь заставить его работать с шрифтом, символы в котором переменной, не фиксированной ширины. Отсутствие поддержки русского языка меня волнует в последнюю очередь.

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

[url="http://www.baka-tsuki.net/project/index.php?title=Talk:Umineko_no_Naku_Koro_ni" target="_blank" rel="nofollow">http://www.baka-tsuki.net/project/index.ph...no_Naku_Koro_ni[/url]

Поскольку Umineko no Naku Koro ni у меня пока нет, я сперва решил "потренироваться" на экзешнике Higurashi no Naku Koro ni, потом сообразил, что поскольку Umineko использует NScripter более новой версии, имеет смысл ковырять экзешник самой последней версии движка. Проблема в том, что экзешник последней версии почему-то отказывается работать с Higurashi, ругаясь на какое-то место в скрипте.

код там действительно ужасен

Я имел в виду бинарный код самого движка, не скриптовый язык =).

И еще такой вопрос... В коде движка есть обработка управляющего символа '#', который, как я понимаю, задает цвет текста. Код цвета задается в шестнадцатиричной форме сразу после этого символа (напр. так: #fffff). Движок преобразует этот код из символьной в бинарную форму, затем производит над полученным числом странные манипуляции. Например, такие (color_code - полученный из скрипта код цвета):

dword_5DC3F0 = color_code / 65536;

v89 = color_code & 0x8000FFFF;
if ( v89 < 0 )
	v89 = ( ( v89 - 1 ) | 0xFFFF0000 ) + 1;

v90 = v89 / 256;
v91 = v89 & 0x800000FF;
dword_5DC3E8 = v90;

if ( v91 < 0 )
	v91 = ( ( v91 - 1 ) | 0xFFFFFF00 ) + 1;
dword_5DC3E0 = v91;

v1 = some_array[ 256 * dword_5DC3F0 ];
v2 = some_array[ 256 * v90 ];
v3 = some_array[ 256 * v91 ];

Есть идея, что это может означать? =) Конкретно интересует, что из себя представляют глобальные переменные dword_XXXXXX и что из себя представляет массив some_array.
  • 0

#10 dsp8195

dsp8195
  • Старожилы
  • PipPipPip
  • Отаку

  • Cообщений: 449
0
Обычный

Отправлено 11 Март 2008 - 19:38

Я ищу способ хакнуть движок NScripter'а так, чтобы он воспринимал однобайтовые символы и производил text wrapping, также пытаюсь заставить его работать с шрифтом, символы в котором переменной, не фиксированной ширины.

Документацию POnScripter'а прочитай... :);; Всё вышеперечисленное + смена TypeFace шрифта на лету!

Я имел в виду бинарный код самого движка, не скриптовый язык =).

...это и имелось ввиду. >_<

Есть идея, что это может означать? =) Конкретно интересует, что из себя представляют глобальные переменные dword_XXXXXX и что из себя представляет массив some_array.


dword_5DC3F0 = color_code / 65536;
//Тоже самое, что (R+G+B) div 3. Получается пиксель в оттенках серого.

v89 = color_code & 0x8000FFFF;
// Убивает каналы A и R (присваивает им нули), а в v89 получается G и B. Код, мягко говоря, извращённый.

if ( v89 < 0 )
// меньше нуля? хм... всё верно - цвет может записываться и как отрицательное число (TColor в Delphi)
	v89 = ( ( v89 - 1 ) | 0xFFFF0000 ) + 1; // вот это я вообще не понял... негатив A R ... только в чём смысл? O_o

v90 = v89 / 256; // Ну, тут ясно -- получение оттенка серого из G и B
v91 = v89 & 0x800000FF; // получается серый пиксель (т.е. канал B, просто отделённый от изображения)
dword_5DC3E8 = v90; // это даже комментировать не стоит

if ( v91 < 0 )
//и это
	v91 = ( ( v91 - 1 ) | 0xFFFFFF00 ) + 1; // по идее, получается 0
dword_5DC3E0 = v91;

v1 = some_array[ 256 * dword_5DC3F0 ];
v2 = some_array[ 256 * v90 ];
v3 = some_array[ 256 * v91 ];

// Кхм.... такого дикого и абсолютно бесполезного преобразования цветов я ещё не видел... если честно, не могу вкурить, зачем ЭТО нужно... :-P

Проблема в том, что экзешник последней версии почему-то отказывается работать с Higurashi, ругаясь на какое-то место в скрипте.

Не повезло. Эта игра использует модифицированную версию движка (просто моё предположение, но скорее всего так оно и есть).

Сообщение отредактировал WinKi-тян: 11 Март 2008 - 19:51

  • 0

#11 Solanacean

Solanacean
  • Активные участники
  • PipPip
  • Soulless & fractured

  • Cообщений: 111
0
Обычный

Отправлено 11 Март 2008 - 20:21

WinKi, ты надо мной издеваешься что-ли? :) . Я не сомневаюсь в том, что опенсорсный ONScripter и его ветки поддерживают весь набор трутайп шрифтов, юникод и прочее. Проблема в том, что он не поддерживает ряд графических эффектов последних версий NScripter'а, а значит перевести на него игры, использующие этот набор (вроде вышеупомянутой Umineko...) нельзя. Неужели ты думаешь, что я от нечего делать ковыряюсь в этой помойке? ;)

...это и имелось ввиду. >_<

Т.е. ты тоже дизасмил экзешник NScripter'а? :D

За комментарии к листингу - большое спасибо :) .

Сообщение отредактировал Serke: 11 Март 2008 - 20:26

  • 0

#12 dsp8195

dsp8195
  • Старожилы
  • PipPipPip
  • Отаку

  • Cообщений: 449
0
Обычный

Отправлено 11 Март 2008 - 20:43

он не поддерживает ряд графических эффектов последних версий NScripter'а, а значит перевести на него игры, использующие этот набор (вроде вышеупомянутой Umineko...) нельзя.

Нельзя так нельзя. Надо было сказать сразу. :)

Сообщение отредактировал WinKi-тян: 11 Март 2008 - 20:57

  • 0

#13 Solanacean

Solanacean
  • Активные участники
  • PipPip
  • Soulless & fractured

  • Cообщений: 111
0
Обычный

Отправлено 11 Март 2008 - 21:26

Нет графических эффектов? Каких интересно? Чего-то вроде "oldmovie" или "sunblick"?

Не знаю. Игры у меня пока нет.

Если их отстутствие не испортит игру, то закомментировать проблемные участки скрипта и вперёд!

"Это не наш метод" ©. Можно вообще дать страждущим скрипт (в виде текстового файла), выдранный набор картинок и указания, где какой mp3 файл включать в винампе =). Ключевое слово здесь - экспириенс и он должен быть если не аутентичным, то хотя бы максимально приближаться к таковому. Мои пять центов.

А если нужны как воздух - обращаться прямо к Peter'у. Мы с Mion'ом добавили поддержку locale.utf, может и тебе повезёт.

Сомневаюсь. Затраты времени на поддержку локали и эмуляцию (или, скорее, симуляцию) граф. эффектов несравнимы.

или сделать копи-паст декомпилированного кода

Копи-паст сделать не получится, но идея мне нравится. Попробую.

Кстати, в ONScripter'е мне категорически не нравится то, что он использует для проигрывания OGG и MP3 библиотеку sdl_mixer. Не радует ни качество звука, ни лаги в проигрывании пожатого аудио, выражающиеся в появлении щелчков и потрескиваний.
  • 0

#14 dsp8195

dsp8195
  • Старожилы
  • PipPipPip
  • Отаку

  • Cообщений: 449
0
Обычный

Отправлено 11 Март 2008 - 21:42

Кстати, в ONScripter'е мне категорически не нравится то, что он использует для проигрывания OGG и MP3 библиотеку sdl_mixer. Не радует ни качество звука, ни лаги в проигрывании пожатого аудио, выражающиеся в появлении щелчков и потрескиваний.

Вот и повод опробовать BASS. ;)
  • 0

#15 Solanacean

Solanacean
  • Активные участники
  • PipPip
  • Soulless & fractured

  • Cообщений: 111
0
Обычный

Отправлено 11 Март 2008 - 22:05

WinKi, я нашел еще более крутую библиотеку - [url="http://en.wikipedia.org/wiki/FMOD" target="_blank" rel="nofollow">FMOD[/url]. Очень внушительный поддерживаемых платформ, очень внушительный список поддерживаемых форматов и библиотеку используют очень внушительные компании, такие как Blizzard. Цена тоже очень и очень внушительна, но для некоммерческого использования библиотека бесплатна. По отзывам тех, кто пользовался и BASS и FMOD, последняя гораздо лучше первой. И качество звука великолепно и скорость работы выше всяческих похвал.
  • 0

#16 Solanacean

Solanacean
  • Активные участники
  • PipPip
  • Soulless & fractured

  • Cообщений: 111
0
Обычный

Отправлено 13 Март 2008 - 05:48

Какая жалость, что OllyDbg не поддерживает удаленную отладку через TCP/IP - фичу, при ковырянии новелл и вообще любых графических аппликаций, совершенно незаменимую. Отладчик IDA Pro ее поддерживает, но он a) тормозной и б) неудобный (ИМХО) и наконец, в) в "японифицированных" виндах не отображаются регистры. ;)

WinKi, ты на уровне WinAPI, или вернее, GDI32 API, с графикой работал?

Сообщение отредактировал Serke: 13 Март 2008 - 05:53

  • 0

#17 dsp8195

dsp8195
  • Старожилы
  • PipPipPip
  • Отаку

  • Cообщений: 449
0
Обычный

Отправлено 13 Март 2008 - 21:06

WinKi, ты на уровне WinAPI, или вернее, GDI32 API, с графикой работал?

Нет пока... -_- Насчёт регистров... шрифт в самом отладчике поменять пытался? Или (изврат конечно, и вряд ли бы сработало, но) запускать отладчик на японизированной винде через AppLocale?

Сообщение отредактировал WinKi-тян: 13 Март 2008 - 21:08

  • 0

#18 Solanacean

Solanacean
  • Активные участники
  • PipPip
  • Soulless & fractured

  • Cообщений: 111
0
Обычный

Отправлено 14 Март 2008 - 21:55

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

Еще возникло несколько вопросов. Во-первых, ф-ей setwindow задается в том числе и размер шрифта. Вопрос: в каких единицах он задается? В коде NScripter'а есть такой участок:

if ( WriteVertical == TRUE )
  {
	//...
  }
  else
  {
	font_cx = 3 * font_width / 2;
	font_cy = 3 * font_height;
  }
  hFont = CreateFontA( font_cy, font_cx, cOrientation, cOrientation, v19, 0, 0, 0, SHIFTJIS_CHARSET, 0, 0, 0, 1, &pszFaceName );

font_cy и font_cx - размеры шрифта в логических единицах (logical units).
font_width и font_height - параметры, переданные команде setwindow.
Как видно из вышеприведенного листинга, реальный размер шрифта отличается от заданного ф-ей setwindow.

Есть подозрение, что выводимые на экран символы шрифта размера width = font_cx, height = font_cy рендерятся движком в квадратную битмапку размерностью width = font_width, height = font_height (посимвольно), затем каждый символ копируется на экран API-функцией BitBlt (растровая операция SRCCOPY). Ты не мог бы взглянуть в исходники ONScripter'а и подтвердить/опровергнуть это?

И еще один вопрос: что представляет из себя поставляемый с бинарниками онскриптера шрифт default.ttf? Он вообще фиксированной или переменной ширины? =)

UPD: Можешь объяснить принцип работы ф-и locate? (той, которая "changes the position of characters without changing the position of the text window") Она только на строку, следующую непосредственно за ней оказывает эффект или вообще на весь выводимый текст?

Вообще, хотелось бы заиметь хоть какой-нибудь мануал по командам/функциям ONScripter'а. Смог найти только перечень с кратким описанием на сайте Haeleth. Кстати, и этот перечень неплохо было бы иметь в виде CHM-файла или хотя бы HTMLок...

Сообщение отредактировал Serke: 15 Март 2008 - 05:16

  • 0

#19 апкиш

апкиш
  • Старожилы
  • PipPipPipPipPipPip
  • фуфрыстая нека

  • Cообщений: 2 846
1
Обычный

Отправлено 15 Март 2008 - 06:26

товарищи!! я это хотеть!!!!!
знаю ассемблер, есть опыт вскрытия коммерческих продуктов на предмет регистрации.
вскрывал при помощи оллидебагера и softice'а
люблю хигурашу.
просто скажите что откуда качать и что нужно выдрать из этого скаченного, я с радостью попытаюсь это сделать
  • 0

#20 Solanacean

Solanacean
  • Активные участники
  • PipPip
  • Soulless & fractured

  • Cообщений: 111
0
Обычный

Отправлено 16 Март 2008 - 03:19

Тут, в общем, опыт вскрытия ПО мало пригодится, нужны опыт реверсинга, опыт работы с IDA Pro (как дизассемблером, так и отладчиком) и знание GDI32 API...

Речь, кстати, идет не о хигураши, а о новой игре от создателей Higurashi (студии 07 Expansion) - Umineko no Naku Koro ni. Игры у меня на данный момент нет, пока она идет ко мне по почте, я набиваю руку, ковыряя Higurashi no Naku Koro ni (она на базе того же движка, что и Umineko..., только более старой версии). Higurashi..., иначе как в обучающих целях, ковырять нет смысла, так как ее скрипт совместим с последними версиями ONScripter'а - опенсорсного аналога популярного движка NScripter, на котором бегают все игры от 07 Expansion (и куча других игр). А вот скрипт Umineko... содержит ряд команд, отсутствующих в ONScripter'е, поэтому выхода два: "учить" NScripter работать с английским текстом или "научить" ONScripter этим новым командам. Мне ближе первый вариант :)

Сообщение отредактировал Serke: 16 Март 2008 - 03:24

  • 0




Количество пользователей, читающих эту тему: 0

0 пользователей, 0 гостей, 0 анонимных