Версия для печати темы
CTPAX-X _ Программы _ No-CD для Hand of Fate CD-ROM
Автор: Siberian GRemlin Aug 2 2007, 10:48
Вообщем, решил поиграть во вторую Кирандию, но нормально так и не смог. VDMSound в оконном режиме не работает, а в DOSBox приходится вбивать каждый раз, чтобы он смонтировал образ в свой виртуальный CD-ROM, может конечно это и можно как-то автоматизировать, но эта падлюка после монтирования пытается работать с образом как с основным диском и игра говорит, что нету свободного места на винте и завершает работу. Вообщем, проще отучить от диска игру, чем изучать все премудрости других программ. Но что-то у меня не получается. Если интересно, вот файлик: http://slil.ru/24694340
Ресурсы игра берёт из папки [CD-ROM] :\HOF_CD\, естественно её надо приучить брать файлы из своей папки (папки с игрой) или из любой папки в папке с игрой. И не выводить дурацкое собщение "A CD-ROM device driver is required to run Hand of Fate CD.", а вместо этого нормально запускаться и работать.
Автор: -=CHE@TER=- Aug 3 2007, 09:21
Так как у меня игры нет, то проверить не могу.
Попробуй изменить в файле HOFCD.EXE байт по смещению 0000EE29 с $75 на $EB.
При этом у тебя в каталоге вместе с этим файлом должен находиться каталог "HOF_CD" с диска.
Если что-то не получится - тогда выложи готовый конфиг-файл - "HOF.CFG", а то мне ещё его проверку пришлось обходить в одном месте. Теперь пишет "Unknow graphic mode." и я не могу понять - то ли это я криво проверку на CD обошёл, то ли это косяк из-за отсутствия конфигурационного файла.
Получится или нет - обязательно отпиши тут.
Автор: Siberian GRemlin Aug 4 2007, 11:27
Диск не просит. Говорит, что не найдена звуковуха или настройки от неё, а дальше вроде грузится, но чёрный экран.
HOF.CFG
Автор: -=CHE@TER=- Aug 4 2007, 12:50
Возможно стоит скопировать всё содержимое каталога "HOF_CD" к "HOFCD.EXE" (отученному от CD) файлу, а не отдельно (т.е. в один каталог), потому что у меня программа перестала ругаться на звуковуху и просто зависла после запуска, когда я поместил в каталог к "HOFCD.EXE" пустышки (0 байт) следующих файлов ("подсмотрел", что программа ищет):
MT32MPU.ADV
SBDIG.ADV
ALFX.DRV
GOLDFONT.FNT
INTRODRV.PAK
INTROGEN.PAK
Посмотри, в каком каталоге находятся эти файлы и попробуй сунуть туда же HOFCD.EXE + HOF.CFG и все остальные, которые находятся вместе с этими двумя (возможно, с них стоит убрать "Только чтение", если файлы с CD).
Пиши, получится или нет.
Автор: Siberian GRemlin Aug 6 2007, 04:32
Работает! =)
Но, вот оказалось, что HODCD.EXE это главное меню игры, которое потом запускает саму игру, лежащую в файлах MAINDOS.EXE и MAINWIN.EXE, которые тоже просят диск. Но если запустить не через HOFCD.EXE, а через MAIN, то автоматически сначала заупстится HOFCD.EXE
Вот эти два файла:
HOFHDD.rar
Автор: -=CHE@TER=- Aug 6 2007, 09:00
Siberian GRemlin!
Вот, проверяй:
Имя_файла
Смещение: старый_байт новый_байт
MAINDOS.EXE
000181CD: 75 EB
MAINWIN.EXE
000181CA: 75 EB
Отпишись - получится или нет.
Если получится, то я, возможно, универсальный noCD сделаю.
Автор: Siberian GRemlin Aug 7 2007, 06:36
Всё работает. Спасибо! Я хочу разместить No-CD у себя на сайте в виде кряка, поэтому предлагаю решить его вопрос сообща.
CODE
program ProjectHoFNoCD;
{$APPTYPE CONSOLE}
{$H-}
uses
SysUtils,
Windows,
Classes;
const
rus:byte=$EB;
function TestExe:Boolean;
var
MSTR: TMemoryStream;
begin
if fileexists(ExtractFilePath(ParamStr(0))+'HOFCD.EXE') then begin
MSTR:=TMemoryStream.Create;
Mstr.LoadFromFile(ExtractFilePath(ParamStr(0))+'HOFCD.EXE');
if Mstr.Size=199284 then result:=true
else result:=false;
Mstr.Free;
//
if fileexists(ExtractFilePath(ParamStr(0))+'MAINDOS.EXE') then begin
MSTR:=TMemoryStream.Create;
Mstr.LoadFromFile(ExtractFilePath(ParamStr(0))+'MAINDOS.EXE');
if Mstr.Size=283328 then result:=true
else result:=false;
Mstr.Free;
//
if fileexists(ExtractFilePath(ParamStr(0))+'MAINWIN.EXE') then begin
MSTR:=TMemoryStream.Create;
Mstr.LoadFromFile(ExtractFilePath(ParamStr(0))+'MAINWIN.EXE');
if Mstr.Size=280000 then result:=true
else result:=false;
Mstr.Free;
end else result:=false;
//
end else result:=false;
//
end else result:=false;
end;
procedure Patch(Logo: byte);
var
MSTR: TFileStream;
begin
MSTR:=TFileStream.Create(ExtractFilePath(ParamStr(0))+'HOFCD.EXE',fmOpenWrite,fmShareDenyWrite);
Mstr.Position:=$EE29;
Mstr.WriteBuffer(Logo,1);
Mstr.Free;
MSTR:=TFileStream.Create(ExtractFilePath(ParamStr(0))+'MAINDOS.EXE',fmOpenWrite,fmShareDenyWrite);
Mstr.Position:=$181CD;
Mstr.WriteBuffer(Logo,1);
Mstr.Free;
MSTR:=TFileStream.Create(ExtractFilePath(ParamStr(0))+'MAINWIN.EXE',fmOpenWrite,fmShareDenyWrite);
Mstr.Position:=$181CA;
Mstr.WriteBuffer(Logo,1);
Mstr.Free;
end;
begin
Write(' Hand of Fate No-CD');
Write(' Hack by -=CHE@TER=-');
Write(' Patch by Siberian GRemlin');
Write(' WWW.CTPAX-X.ORG');
Write(& #39;____________________________________________________________________________
____');
if TestExe then begin
patch(rus);
WriteLn('All files patched successfuly.');
WriteLn('Please copy all files exept executables from [CD-ROM]:\HOF_CD to game folder.');
end else begin
WriteLn('Some files of HOFCD.EXE, MAINDOS.EXE, MAINWIN.EXE not found or corrupted!');
WriteLn('Please reinstall game!');
end;
Readln;
end.
Автор: -=CHE@TER=- Aug 7 2007, 11:11
Siberian GRemlin!
Предлагаю такой noCD - как их делаю я - универсальный:
CODE
Program KYR2NOCD;
{$APPTYPE CONSOLE}
{$WARNINGS OFF}
Uses SysUtils;
Const
StTitle = 'Kyrandia II: Hand of Fate (CD version)';
FlPatch: Array[1..3] Of String[11] = ('HOFCD.EXE', 'MAINDOS.EXE', 'MAINWIN.EXE');
Var
FTime, FAttr: Cardinal;
Buff, FName: String;
CP, I: LongInt;
Fl: File;
Function Boyer(S, Q: String): Integer;
Var
N, M, I, J, K: Integer;
D: Array[0..255] Of Byte;
Begin
N:=Length(S);
M:=Length(Q);
FillChar(D, 256, M);
For I:=1 To M-1 Do D[Ord(Q[I])]:=M-I;
I:=M;
Repeat
J:=M;
K:=I;
While ((J<>0) And ((Q[J]=S[K]) Or (Q[J]=#$FF))) Do
Begin
K:=K-1;
J:=J-1;
End;
I:=I + D[Ord(S[I])]
Until ((J = 0) Or (I>N));
If J = 0 Then Boyer:=K{+1} Else Boyer:=-1;
End;
Begin
WriteLn(StTitle + ' Universal noCD');
WriteLn('(c) CTPAX-X Team 2007');
WriteLn('Downloaded from: http://www.CTPAX-X.org');
WriteLn;
For I:=1 To 3 Do
If Not FileExists(FlPatch[I]) Then Break;
If I = 4 Then
Begin
For I:=1 To 3 Do
Begin
FName:=FlPatch[I];
FTime:=FileAge(FName);
FAttr:=FileGetAttr(FName);
FileSetAttr(FName, faArchive);
AssignFile(Fl, FName);
Reset(Fl, 1);
SetLength(Buff, FileSize(Fl));
BlockRead(Fl, Buff[1], FileSize(Fl));
CloseFile(Fl);
FileSetAttr(FName, FAttr);
CP:=Boyer(Buff, #$90#$0E#$E8#$FF#$FF#$83#$C4#$0A#$0B#$C0#$75);
WriteLn(FName, ':');
If CP<>-1 Then
Begin
ReNameFile(FName, 'OLD_' + FName);
AssignFile(Fl, FName);
ReWrite(Fl, 1);
BlockWrite(Fl, Buff[1], Length(Buff));
Seek(Fl, CP+10);
CP:=$EB;
BlockWrite(Fl, CP, 1);
CloseFile(Fl);
FileSetDate(FName, FTime);
FileSetAttr(FName, FAttr);
WriteLn('File patched.');
End
Else
WriteLn('Not a "' + StTitle + '" file or already patched.');
WriteLn;
SetLength(Buff, 0);
End;
WriteLn('Note: don''t forget to copy all files except executables from');
WriteLn('[CD-ROM]:\HOF_CD\ to your game folder or game will not work.');
End
Else
WriteLn('Can''t find "' + FlPatch[I] + '" file.');
WriteLn;
Write('PRESS [ENTER] TO EXIT');
ReadLn;
End.
Плюсы таких Universal noCD:
1) Не привязаны жёстко к какому-либо смещению. Т.е. в случае если есть какие-то переиздания игры, где что-то чуток изменили и твоё смещение для проверки съехало вперёд/назад - то игра всё-равно будет патчиться. Или, например, у тебя вирус .EXE файл покосил - антивирус его восстановил, но некорректно, а дистрибутива игры у тебя нет - в таких случаях патч тоже будет работать.
2) Анализируется код, который будет патчиться - т.е. два раза один и тот же .EXE файл не пропатчится - т.к. ищется всегда кусок кода, который встречается ОДИН раз во всех исполняемых файлах.
3) Твой noCD занимает 41472 байта - мой 23040 байт (оба файла пожаты UPX 3.00) (*улыбается*)
Если замечаний нет - выкладываю на сайт.
Автор: Siberian GRemlin Aug 10 2007, 15:08
Слушай, я вот забыл, вместо Readln можно же сделать if keypressed или что-то типа того, но куда лучше будет - последний раз ещё в школе это использовал, уже не помню =)
Автор: -=CHE@TER=- Aug 10 2007, 16:25
QUOTE(Siberian GRemlin @ Aug 10 2007, 03:08 PM)
Слушай, я вот забыл, вместо Readln можно же сделать if keypressed или что-то типа того, но куда лучше будет - последний раз ещё в школе это использовал, уже не помню =)
KeyPressed/ReadKey есть только в модуле CRT под DOS. В Delphi ни этого модуля, ни этих команд нет. Кто-то, где-то делал враппер для WinAPI консоли под CRT, но, ИМХО, тут это лишнее.
Опять-таки:
QUOTE(-=CHE@TER=- @ Aug 7 2007, 11:11 AM)
Если замечаний нет - выкладываю на сайт.
Так что, жду отзывов - выкладывать или нет.
Автор: Siberian GRemlin Aug 12 2007, 01:47
Выкладывай