Перейти к содержанию

Solanacean

Активные участники
  • Зарегистрирован

  • Посещение

Весь контент Solanacean

  1. Поскольку депресняк пока не думает отступать, а время идет, решил кинуть код анпакера 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: слегка подправил код.
  2. 0. Ico (PS2) 1. The Last Express (PC) 2. Star Control II (PC/3DO) 3. Snatcher (Sega CD) 4. Phantom of Inferno (AnimeDVD) 5. серия Gyakuten Saiban/Phoenix Wright (Nintendo DS) 6. Grim Fandango (PC) 7. Samorost 2 (PC) 8. Anachronox (PC) 9. Xenogears (PS)
  3. 000, на версии от Hirameki. Если найдутся люди, владеющие японским в достаточной мере и готовые взвалить на себя нелегкий труд по переводу, можно будет задуматься о деяпонизации Never7 и Remember11. Честно говоря, положение дел на нашей сцене таково, что реально надеяться можно лишь на западную комьюнити. WinKi, в очередной раз вынужден просить у тебя прощения. Горит мой далеко не красный диплом и вдобавок, навалился жуткий депресняк. К тому же долгое время сидел без интернета вообще. Короче, все сразу, чтобы жизнь медом не казалась... ЗЫ. Кстати, лично я от Ever17 не в восторге. Еще рано делать какие-либо выводы, но почему-то игра меня не зацепила так, как я ожидал. Впрочем, на меня вообще хрен угодишь. Забросил Ever17, взялся за Xenogears, Higurashi no Naku Koro ni и серию Phoenix Wright.
  4. Не смеши. UPX хоть с каким заголовком отрывается ровно за 5 минут. >__< [EDIT: уложился в 3 =)] Если есть желание продолжить веселье, могу анпакером GGD в тебя кинуть. Чтобы была полная укатайка. Держи: int DecryptScriptData( BYTE *pScriptData, int fsize, int kdata ) { int m = 0; int i = 0; int k = 0; int j; char CryptString[] = "crowd script yeah !"; while( i < fsize ) { j = ( m + i ) % kdata; pScriptData[ i ] = DecryptByte( pScriptData[ i ], CryptString[ j ] | ( m & k ) ); if( j == 0 ) { m = CryptString[ ( m + k ) % kdata ]; k++; } i++; } return 1; } BYTE DecryptByte( int encr_byte, int key ) { return ( encr_byte | key ) & ~( encr_byte & key ); } Пояснения: 1. '%' аналогичен паскалевскому mod - взятие остатка от деления. 2. Функции передается pScriptData - указатель на буфер с закодированными данными. Может быть ты это знаешь, но на всякий случай: в Си имя массива есть ни что иное, как указатель на первый элемент этого массива, поэтому, скажем, к 10-му элементу массива somearray можно обращаться так: somearray[9] = somevar; или так: *( somearray + 9 ) = somevar; или даже так: *( &somearray[0] + 9 ) = somevar; В вышеприведенном коде к области памяти с закодированными данными идет обращение как к массиву, несмотря на то, что функции передается указатель на нее. Массивы в Си начинаются с 0. 3. Алгоритм, похоже, симметричный - эта же функция может быть использована для закодирования файла взад =) Есть и плохая для тебя новость... Обрати внимание на третий параметр функции. kdata - составная часть ключа - передается функции в виде константы, а не берется из файла-скрипта или откуда-нибудь еще. Это означает, что универсальный расшифровщик скриптов должен включать в себя брутфорсер для подбора значения kdata.
  5. LOL. Это напомнило мне анекдот: Начальник российской фирмы, принимая англоязычных гостей, описал свой кабинет так: "а стены у меня здесь покрыты самшитом". Переводчица выдала гостям: "And the walls here are covered with some shit." Глазам своим не верю... А ведь меня почти убедили в том, что кроме меня Grandia 2 не нравится никому. =) Бинарник выслал, с исходниками придется немного подождать - еще не подчищал их и не комментил. Что касается пакера GG2 - GGD гораздо проще, рекомендую начать c него. Типа потренироваться на кошках. =) А я тем временем засяду за пакер для CPS-файлов. >__< Скорее всего, нужно установить поддержку азиатских языков (Control Panel -> Regional and Language Options, вкладка Languages, флажок Install files for Eastern Asian Languages), затем выставить японский язык для неюникодных приложений (Control Panel -> Regional and Language Options, вкладка Advanced). Я бы посоветовал установить игру повторно после "японизации" виндов по вышеописанному методу. Если проблема не разрешится, вполне возможно, что образ битый. =( По поводу глюков - WinKi, ты не пиратский ли, случаем, экзешник к демке присобачил? [EDIT: WinKi, закинул следом искодники GG2-анпакера. Жаль, что я не увижу твоего лица когда ты будешь их просматривать и не услышу твоих комментариев в адрес ваятелей движка. =). Где мог, код упростил, так что помидоры кидай в них =). GGD unpacker w/sources coming soon...]
  6. Нравится Melty Blood. Простой, зрелищный файтинг в сеттинге нежно мной обожаемой визуальной новеллы Tsukihime.
  7. Позволю себе на правах человека, хорошо знакомого с жанром (уж простите мне мою наглость), порекомендовать вам и всем здесь присутствующим к обязательному прохождению одну из лучших новелл в линейке Hirameki и одну из лучших новелл вообще - Phantom of Inferno. Я бы мог долго, не скупясь на эпитеты, расхваливать эту вещь, но поскольку лень родилась вперед меня, ограничусь приведением ссылки на уже готовую рецензию со множеством скриншотов, которая поможет вам составить некоторое впечатление об игре: Существует. Так же, как и PC версия Remember11: [url="http://en.wikipedia.org/wiki/Remember_11:_The_Age_of_Infinity" target="_blank" rel="nofollow">http://en.wikipedia.org/wiki/Remember_11:_...Age_of_Infinity Platforms: PS2, Windows. В общем, дамы и господа, вот любезно предоставленная Take ссылка на японоязычную PC версию Never7: [url="http://www.hongfire.com/forum/showthread.php?t=69749" target="_blank" rel="nofollow">http://www.hongfire.com/forum/showthread.php?t=69749[/url] Из-за почтенного возраста ссылки вероятность успешного выкачивания игры находится под вопросом, но как говорится, чем богаты, тем и рады...
  8. Tsugumi-tyan, ну как же нет, когда Take не далее чем позавчера нашел, бороздя просторы Большого Театра интернета, PC-версию Never7 (за что ему огромный и вполне заслуженный респект). Tsugumi-tyan, перевод текста и программирование - вещи абсолютно разные. >__< Предлагаю присоединиться к пока еще не созданной команде пруфридеров/бетатестеров. :( Должен сказать, что в переводе WinKi меня тоже не все устраивает.
  9. Take, я бы очень попросил по-возможности удерживаться от спойлеров. Воображение у меня богатое, визуальных новелл я прочитал множество и что хуже всего, /me опытный детективщик, что вообще не лечится (ДАЖЕ электричеством :( - я пробовал). Этого ^^ оказалось достаточно, чтобы я выстроил целую теорию... И спасибо за линк на Never7. Думаю, нужно выложить его здесь (если ты не против). Для меня с моим какбыинтернетом выкачивание такого объема задача непосильная, но мир, как известно, не без добрых людей. Возможно, кто-то захочет поменяться. WinKi, анпакеры для GGD и GG2 файлов IKURA (Trambulance?) готовы. Код пока еще не причесан (издержки моего подхода к реверсингу/декомпиляции), но вполне работоспособен. Тому, кто возьмется за написание пакера GG2 (лично я скорее соглашусь убиться о склон Фудзиямы) можно потихоньку начинать скидываться на няшный розовый венок с кавайными ленточками. Программисты движка игр серии Infinity против программистов икуры - все равно, что мелкие хулиганы против матерых уголовников. >__<
  10. Раз уж я заработал репутацию зануды, терять мне нечего, буду продолжать занудствовать дальше. WinKi, вот как хочешь, но речь в вышеприведенном предложении идет вовсе не о розе. Ты на словосочетание посмотри - rose above. Глагол rise наиболее часто употребляют с наречием above, это классика. Если бы речь шла о розе, употребили бы предлог, а не наречие, да и вообще, предложение было бы сконструировано иначе, с указанием на то, что остров resembled a rose or something like that. Если ты не против, я хотел бы просмотреть текст перед финальным релизом и составить список замечаний и предложений. Прекрасно понимаю, что при переводе текста такого объема ошибки и косяки неизбежны. Кстати, большое спасибо за наводку на BASS. Кажется, то что нужно. Небольшая по объему, менее требовательна к ресурсам по сравнению с SDL/SDL_Mixer, есть хэдеры для моего любимого Flat Assembler. Попробую встроить ее в "Кану" вместо SDL_Mixer и посмотреть, что из этого выйдет. P.S. Надо же, девушки начали подтягиваться. :D Теперь есть стимул работать. >__<
  11. WinKi, не хочу показаться жутким занудой и умником, но фраза "The man-made island, Insel null, rose above the waves of the water." означает вовсе не "Рукотворный остров, Инсель нуль, роза на волнах." Rose в данном случае есть ни что иное как прошедшая форма глагола rise - возвышаться, подниматься, etc. Текст литературный, "живой", читается легко и приятно, но от таких косяков перед финальным релизом нужно избавляться.
  12. Я бы не стал торопить WinKi с переводом текста. Скорость хороша при ловле блох, в случае же с переводом она должна быть такой, чтобы не страдало качество. Уверен, что WinKi сам это прекрасно понимает. Ну и так, небольшое отступление: в наши с WinKi планы входит создание полноценного инструментария для работы с движком игр серии Infinity (Ever17, Never7 и Remember11). Создание такого инструментария, как нетрудно догадаться, повысит вероятность того, что другие игры серии когда-нибудь будут переведены хотя бы на английский. К сожалению, для написания полностью универсальных инструментов необходимо иметь при себе все игры серии. Будем признательны за любую информацию о том, где и как можно достать перечисленные игры серии Infinity (кроме, разумеется, англоязычной и русЕфЕцированной Ever17). Благодарю за внимание. :)
  13. Не стоит судить о прогрессе по его, прогресса, в немом укоре застывшему индикатору на сайте WinKi. :) Разобраны алгоритмы (рас)паковки и (де)шифрования графических файлов, разобран формат графики, написаны утилиты. Перевод текста, полагаю, также идет полным ходом.

Важная информация

Мы разместили cookie-файлы на ваше устройство, чтобы помочь сделать этот сайт лучше. Вы можете изменить свои настройки cookie-файлов, или продолжить без изменения настроек.

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.