Разработка и ромхакинг > Ромхакинг
[SMD] Dune: The Battle for Arrakis
serj320:
--- Цитата: topos84 от 14 Августа 2011, 00:54:14 ---А остальные идеи - это по поводу? Новые юниты заместо старых? Ну это наверно лишь в отношении изменения характеристик дальности и урона стрельбы (плюс, может быть, новые спрайты заместо старых)? А скорость перезарядки можно менять?
--- Конец цитаты ---
Дальность, урон, скорость перезарядки вроде в DuneUnitEditor менять можно, а новых спрайтов валом
--- Цитата: Segaman от 11 Августа 2011, 10:52:05 ---давайт еставим титульник как есть.
нинадо его переводить. :)
--- Конец цитаты ---
пока норм не появится :)
P.S.
Такими темпами хак выйдет...
хз когда он выйдет :)
Ti_:
--- Цитата: topos84 от 14 Августа 2011, 00:54:14 ---Ну про идеи, собственно говоря, говорить наверно пока рано, если код - темный лес.
--- Конец цитаты ---
Не так понял, вообще-то сейчас уже изученного достаточно чтобы делать очень много каких наворотов (получше чем в dunehackv7); а начинать не хочется именного из-за того что разобрано не всё (хотя бы больше половины надо).
Lipetsk:
Итак, все ресурсы, включая спрайты юнитов, извлечены из рома. Графика в основном сжатая.
Чтобы её изменять и вставлять в ром нужен нормальный запаковщик.
Анпакер Марата сжимает не все архивы.
Нужно сделать новый желательно с поддержкой массового анпака.
Покопавшись на форуме "Шедевра", нашёл исходники упаковки/распаковки:
--- Цитата ---В туториалке используется дважды упакованная карта тайлов. Сначала используется "свой" алгоритм, а потом общий.
После двух распаковок у тебя должен получиться набор "экранов".
--- Конец цитаты ---
--- Цитата ---Распаковка "обычная".
--- Конец цитаты ---
--- Код: --- .386
.model flat
public unpack
public mod_name
.data
modstring db "Dune: The Battle for Arrakis",0
.data?
out_buf dd ?
in_buf dd ?
opt dd ?
read_len dd ?
.code
_start@12:
mov al,1
ret 12
;int unpack(char* pIn, char* pOut, int option, int* rLen);
unpack proc
pop eax
pop in_buf
pop out_buf
pop opt
pop read_len
push eax
push ebx
push ebp
push esi
push edi
mov ebx,in_buf
mov edi,out_buf
main_loop:
xor ecx,ecx
xor edx,edx
mov cl,byte ptr [ebx]
inc ebx
cmp cl,0
jns cl_positive
test cl,40h
jz sixth_bit_clear
cmp cl,-2
je cl_eq_FE
cmp cl,-1
je cl_eq_FF
and cl,3Fh
mov dx,word ptr [ebx]
add ebx,2
add cx,3
mov esi,out_buf
add esi,edx
jmp loc_0_C96
cl_eq_FF:
mov cx,word ptr [ebx]
mov dx,word ptr [ebx+2]
add ebx,4
mov esi,out_buf
add esi,edx
jmp loc_0_C96
cl_positive:
mov dh,cl
mov dl,byte ptr [ebx]
and dx,0FFFh
inc ebx
shr cx,4
add cx,3
mov esi,edi
sub esi,edx
loc_0_C96:
rep movsb
jmp main_loop
sixth_bit_clear:
cmp cl,80h
je exit_sub
and cl,3Fh
mov esi,ebx
add ebx,ecx
jmp loc_0_C96
cl_eq_FE:
mov cx,word ptr [ebx]
mov al,byte ptr [ebx+2]
add ebx,3
rep stosb
jmp main_loop
exit_sub:
sub ebx,in_buf
mov ebp,read_len
mov [ebp],ebx
mov eax,edi
sub eax,out_buf
pop edi
pop esi
pop ebp
pop ebx
ret
unpack endp
mod_name proc
mov eax,offset modstring
ret
mod_name endp
end _start@12
--- Конец кода ---
--- Цитата ---Распаковка для туториала
--- Конец цитаты ---
--- Код: --- .386
.model flat
public unpack
public mod_name
.data
modstring db "Dune Tutorial Text",0
.data?
out_buf dd ?
in_buf dd ?
opt dd ?
read_len dd ?
out_buf2 dd ?
in_buf2 dd ?
opt2 dd ?
read_len2 dd ?
buf_temp dd 20000h dup(?)
.code
_start@12:
mov al,1
ret 12
;int unpack(char* pIn, char* pOut, int option, int* rLen);
unpack proc
pop eax
pop in_buf
pop out_buf
pop opt
pop read_len
push eax
push ebx
push ebp
push esi
push edi
;---------------------------------------
push read_len
push 0
push offset buf_temp
push in_buf
call preprocess
;---------------------------------------
mov esi,offset buf_temp
mov edi,out_buf
xor eax,eax
lodsw
begin:
cmp ax,-1
jz exit
xchg ah,al
mov bx,ax
mmain_loop:
xor ecx,ecx
mov cl,[esi]
inc esi
cmp cl,80h
jz cl_eq_80
jns cl_gt_80
sub bx,2
lodsw
rep stosw
jmp next_screen
cl_gt_80:
and cl,7Fh
sub bx,cx
sub bx,cx
rep movsw
jmp next_screen
cl_eq_80:
xor eax,eax
lodsb
shl ax,1
mov cx,ax
push esi
mov esi,edi
sub esi,8C0h
rep movsb
pop esi
dec bx
next_screen:
dec bx
jnz mmain_loop
lodsw
cmp ax,-1
jnz begin
exit:
mov eax,edi
sub eax,out_buf
pop edi
pop esi
pop ebp
pop ebx
ret
unpack endp
;int preprocess(char* pIn, char* pOut, int option, int* rLen);
preprocess proc
pop eax
pop in_buf2
pop out_buf2
pop opt2
pop read_len2
push eax
push ebx
push ebp
push esi
push edi
mov ebx,in_buf2
mov edi,out_buf2
main_loop:
xor ecx,ecx
xor edx,edx
mov cl,byte ptr [ebx]
inc ebx
cmp cl,0
jns cl_positive
test cl,40h
jz sixth_bit_clear
cmp cl,-2
je cl_eq_FE
cmp cl,-1
je cl_eq_FF
and cl,3Fh
mov dx,word ptr [ebx]
add ebx,2
add cx,3
mov esi,out_buf2
add esi,edx
jmp loc_0_C96
cl_eq_FF:
mov cx,word ptr [ebx]
mov dx,word ptr [ebx+2]
add ebx,4
mov esi,out_buf2
add esi,edx
jmp loc_0_C96
cl_positive:
mov dh,cl
mov dl,byte ptr [ebx]
and dx,0FFFh
inc ebx
shr cx,4
add cx,3
mov esi,edi
sub esi,edx
loc_0_C96:
rep movsb
jmp main_loop
sixth_bit_clear:
cmp cl,80h
je exit_sub
and cl,3Fh
mov esi,ebx
add ebx,ecx
jmp loc_0_C96
cl_eq_FE:
mov cx,word ptr [ebx]
mov al,byte ptr [ebx+2]
add ebx,3
rep stosb
jmp main_loop
exit_sub:
sub ebx,in_buf
mov ebp,read_len2
mov [ebp],ebx
mov eax,edi
sub eax,out_buf2
pop edi
pop esi
pop ebp
pop ebx
ret
preprocess endp
mod_name proc
mov eax,offset modstring
ret
mod_name endp
end _start@12
--- Конец кода ---
--- Цитата ---А это чисто посмеяцца. Упаковка "обычная".
--- Конец цитаты ---
--- Код: ---//---------------------------------------------------------------------------
#include <vcl\vcl.h>
#pragma hdrstop
//---------------------------------------------------------------------------
char nun[0x3F];
int obytes;
int out;
//---------------------------------------------------------------------------
int WINAPI DllEntryPoint(HINSTANCE, DWORD, LPVOID)
{
return true;
}
//---------------------------------------------------------------------------
char* __stdcall __export mod_name()
{
return "Dune: The Battle for Arrakis";
}
//---------------------------------------------------------------------------
void Flush(char* pO)
{
if(!obytes) return;
pO[out] = obytes | 0x80;
out++;
for(int j = 0; j < obytes; j++)
pO[out + j] = nun[j];
out += obytes;
obytes = 0;
}
//---------------------------------------------------------------------------
int __stdcall __export pack(char* pIn, char* pOut, int option, int* rLen)
{
int in = 0;
int n;
int n2;
int maxN;
int maxN2;
int maxIn;
int in2;
obytes = 0;
out = 0;
while(in < option)
{
maxN = 0;
maxN2 = 0;
maxIn = 0;
for(in2 = 0; in2 < in; in2++)
{
for(n = 0; pIn[in2 + n] == pIn[in + n] && in + n < option; n++);
if(in - in2 < 0x1000 && n < 0xB) n2 = n - 2;
else if(n < 0x43) n2 = n - 3;
else n2 = n - 5;
if(n2 > maxN2) { maxN2 = n2; maxN = n; maxIn = in2; }
}
for(n = 1; pIn[in + n - 1] == pIn[in + n] && in + n - 1 < option; n++);
n2 = n - 4;
if(n2 > maxN2) { maxN2 = n2; maxN = n; maxIn = in; }
if(maxN2 >= 0 && maxN > 2)
{
if(in == maxIn)
{
Flush(pOut);
pOut[out] = 0xFE;
*(WORD*)(pOut + out + 1) = maxN;
pOut[out + 3] = pIn[in];
out += 4;
in += maxN;
}
else if(in - maxIn < 0x1000 && maxN < 0xB)
{
Flush(pOut);
pOut[out] = (maxN - 3) << 4 | (in - maxIn) >> 8;
pOut[out + 1] = (BYTE)(in - maxIn);
out += 2;
in += maxN;
}
else if(maxN < 0x43)
{
Flush(pOut);
pOut[out] = 0xC0 | (maxN - 3);
*(WORD*)(pOut + out + 1) = maxIn;
out += 3;
in += maxN;
}
else
{
Flush(pOut);
pOut[out] = 0xFF;
*(WORD*)(pOut + out + 1) = maxN;
*(WORD*)(pOut + out + 3) = maxIn;
out += 5;
in += maxN;
}
}
else
{
nun[obytes] = pIn[in];
obytes++;
if(obytes == 0x3F) Flush(pOut);
in++;
}
}
Flush(pOut);
pOut[out] = 0x80;
out++;
*rLen = option;
return out;
}
//---------------------------------------------------------------------------
--- Конец кода ---
--- Цитата ---Упаковка для туториала. Файл первый.
--- Конец цитаты ---
--- Код: ---//---------------------------------------------------------------------------
#include <vcl\vcl.h>
#pragma hdrstop
USEUNIT("p_dttext2.cpp"); // Тут должно быть имя второго файла
//---------------------------------------------------------------------------
int i;
int n;
int n2;
int in;
int out;
int size;
WORD* locIn;
char* locOut;
WORD nun[0x7F];
int owords;
int final(char* pIn, char* pOut, int option, int* rLen);
//---------------------------------------------------------------------------
int WINAPI DllEntryPoint(HINSTANCE, DWORD, LPVOID)
{
return true;
}
//---------------------------------------------------------------------------
char* __stdcall __export mod_name()
{
return "Dune Tutorial Text";
}
//---------------------------------------------------------------------------
void Flush()
{
if(!owords) return;
locOut[out] = owords | 0x80;
out++;
for(int j = 0; j < owords; j++)
*(WORD*)(locOut + out + j * 2) = nun[j];
out += owords * 2;
owords = 0;
}
//---------------------------------------------------------------------------
int __stdcall __export pack(char* pIn, char* pOut, int option, int* rLen)
{
out = 0;
owords = 0;
locIn = (WORD*)pIn;
locOut = new char[0x10000];
for(i = 0; i < option / 0x8C0; i++)
{
size = out;
out += 2;
in = 0;
while(in < 0x460)
{
n2 = 0;
for(n = 1; (locIn[in + n - 1] == locIn[in + n]) && ((in + n) < 0x460); n++);
if(i) for(n2 = 0; locIn[in + n2] == locIn[in + n2 - 0x460] && in + n2 < 0x460; n2++);
if(n > 1 || n2 > 1)
{
if(n > 0x7F) n = 0x7F;
if(n2 > 0xFF) n2 = 0xFF;
if(n > n2)
{
Flush();
locOut[out] = n;
*(WORD*)(locOut + out + 1) = locIn[in];
out += 3;
in += n;
}
else
{
Flush();
locOut[out] = 0x80;
locOut[out + 1] = n2;
out += 2;
in += n2;
}
}
else
{
nun[owords] = locIn[in];
owords++;
if(owords == 0x7F) Flush();
in++;
}
}
Flush();
locIn += 0x460;
*(WORD*)(locOut + size) = (WORD)(out - size - 2) << 8 | (WORD)(out - size - 2) >> 8;
}
*(WORD*)(locOut + out) = -1;
out += 2;
out = final(locOut, pOut, out, rLen);
*rLen = option;
delete[] locOut;
return out;
}
//---------------------------------------------------------------------------
--- Конец кода ---
--- Цитата ---Файл второй (у меня назывался p_dttext2.cpp).
--- Конец цитаты ---
--- Код: ---//---------------------------------------------------------------------------
#include <vcl\vcl.h>
#pragma hdrstop
//---------------------------------------------------------------------------
char nun2[0x3F];
int obytes;
int out2;
//---------------------------------------------------------------------------
void Flush(char* pO)
{
if(!obytes) return;
pO[out2] = obytes | 0x80;
out2++;
for(int j = 0; j < obytes; j++)
pO[out2 + j] = nun2[j];
out2 += obytes;
obytes = 0;
}
//---------------------------------------------------------------------------
int final(char* pIn, char* pOut, int option, int* rLen)
{
int in = 0;
int n;
int n2;
int maxN;
int maxN2;
int maxIn;
int in2;
obytes = 0;
out2 = 0;
while(in < option)
{
maxN = 0;
maxN2 = 0;
maxIn = 0;
for(in2 = 0; in2 < in; in2++)
{
for(n = 0; pIn[in2 + n] == pIn[in + n] && in + n < option; n++);
if(in - in2 < 0x1000 && n < 0xB) n2 = n - 2;
else if(n < 0x43) n2 = n - 3;
else n2 = n - 5;
if(n2 > maxN2) { maxN2 = n2; maxN = n; maxIn = in2; }
}
for(n = 1; pIn[in + n - 1] == pIn[in + n] && in + n - 1 < option; n++);
n2 = n - 4;
if(n2 > maxN2) { maxN2 = n2; maxN = n; maxIn = in; }
if(maxN2 >= 0 && maxN > 2)
{
if(in == maxIn)
{
Flush(pOut);
pOut[out2] = 0xFE;
*(WORD*)(pOut + out2 + 1) = maxN;
pOut[out2 + 3] = pIn[in];
out2 += 4;
in += maxN;
}
else if(in - maxIn < 0x1000 && maxN < 0xB)
{
Flush(pOut);
pOut[out2] = (maxN - 3) << 4 | (in - maxIn) >> 8;
pOut[out2 + 1] = (BYTE)(in - maxIn);
out2 += 2;
in += maxN;
}
else if(maxN < 0x43)
{
Flush(pOut);
pOut[out2] = 0xC0 | (maxN - 3);
*(WORD*)(pOut + out2 + 1) = maxIn;
out2 += 3;
in += maxN;
}
else
{
Flush(pOut);
pOut[out2] = 0xFF;
*(WORD*)(pOut + out2 + 1) = maxN;
*(WORD*)(pOut + out2 + 3) = maxIn;
out2 += 5;
in += maxN;
}
}
else
{
nun2[obytes] = pIn[in];
obytes++;
if(obytes == 0x3F) Flush(pOut);
in++;
}
}
Flush(pOut);
pOut[out2] = 0x80;
out2++;
*rLen = option;
return out2;
}
//---------------------------------------------------------------------------
--- Конец кода ---
--- Цитата ---Компилилось все это в виде дээлэльки-плагина к моей проге. Тебе это нафик не надо, переделаешь в экзешники.
Если, конечно, поймешь хоть что-нибудь в этой писанине. Особенно в сишной.
--- Конец цитаты ---
Есть желающие сделать полноценную прогу?
ghola:
Всем привет!
Скажите, а сложно добавить в игру новый юнит? И возможно ли это сейчас?
serj320:
--- Цитата: ghola от 16 Августа 2011, 16:05:19 ---Всем привет!
Скажите, а сложно добавить в игру новый юнит? И возможно ли это сейчас?
--- Конец цитаты ---
В принципе возможно, но это недостаточно легко.
И лень всем :D (ну, может кроме Lipetsk'а )
TrickZter:
А какой смысл делать хак именно сегавской версии? :? На комповской можно сделать куда более полноценных хак.
serj320:
--- Цитата: TrickZter от 16 Августа 2011, 21:17:15 ---А какой смысл делать хак именно сегавской версии? :? На комповской можно сделать куда более полноценных хак.
--- Конец цитаты ---
http://www.cncseries.ru/forums/lofiversion/index.php/t6099.html здесь посмотри. тебе понравится ;)
Добавлено позже:
в спойлере неплохой спрайт танка
Добавлено позже:
здесь делают свою дюну
http://www.cncseries.ru/forums/index.php?act=ST&f=97&t=6099&st=0#entry219614
это тоже форум по этому же проэкту
http://www.cncseries.ru/forums/lofiversion/index.php/t6099-0.html
Добавлено позже:
нашел изображение на тему дюны
а возможно эти иконки в дюну вставить?
Vivi the Black Mage:
serj320, только переведя в соответствующий тип графики. А так нехиленько смотрится.
serj320:
Vivi the Black Mage это я знаю (битность тоесть кол-во цветов)
ghola:
serj320, главное, что возможно!
Вот бы ещё информацию получить, какие-то проги что ли.
Интересно, есть проекты Дюны, где воюют дома из дюны2, дюны2000 и эмперор :lol:
TrickZter, просто у меня мечта такая))
serj320:
--- Цитата: ghola от 16 Августа 2011, 23:31:45 ---Интересно, есть проекты Дюны, где воюют дома из дюны2, дюны2000 и эмперор :lol:
--- Конец цитаты ---
есть! я ссылку выкладывал в посте #1906
Jinaya:
Скажите, будет ли версия хака Дюны с миссиями за Сардуакаров, но без атаки врагов группами. Слишком осложняется игра. Хотя с исправленной ошибкой с атаками групп играть интересно.
ghola:
--- Цитата: serj320 от 16 Августа 2011, 23:33:54 ---есть! я ссылку выкладывал в посте #1906
--- Конец цитаты ---
Там три ссылки на одну тему о "симуляторе червя"... в целом, не важно.
Есть скриншоты этой игры?
Хотел узнать, как относитесь к тому, что бы в игре было больше домов, каждый со своим цветом и особенностями?
Lipetsk:
--- Цитата: Jinaya от 17 Августа 2011, 11:03:50 ---Скажите, будет ли версия хака Дюны с миссиями за Сардуакаров, но без атаки врагов группами. Слишком осложняется игра. Хотя с исправленной ошибкой с атаками групп играть интересно.
--- Конец цитаты ---
Так в хаке частично починены TEAMS (командный AI). То есть работает не всегда. Я ещё хотел патч поставить, который бы активизировал этот алгоритм чаще. Но пока не решил, т.к может повлиять на баланс. Если будут какие-либо изменения (а они будут) то только в сторону усложнения.
--- Цитата: ghola от 17 Августа 2011, 11:49:44 ---Хотел узнать, как относитесь к тому, что бы в игре было больше домов, каждый со своим цветом и особенностями?
--- Конец цитаты ---
А вы как думаете?
serj320:
ghola весь смысл в том что по этим ссылкам много чего интересного для развития проэкта найти
P.S.
Мне этот "симулятор червя" ненужен
ghola:
Lipetsk, ну, например, что скажете про такую идею.
Дому Моритани (союзники Д. Коррино) решил нарисовать герб в виде японского дракона, держащегося за две звезды, и, с катаной в лапе, пронизывающей планету с кольцами.
Из особенных юнитов выступают самураи, которые обучены ценой своей жизни защищать здания от посягательств захватчиков и саботажников. Следовательно, их можно сажать в здание, при каждой попытке проникнуть, враги будут гибнуть вместе с одним самураем.
Segaman:
респект за идею :D, но сие невыполнимо во всех планах. дюна не на гейм-мейкере сделана
serj320:
ghola дело в том что ром имеет весьма ограниченый размер, а новый дом это множество дополнительной информации.
Ti_:
--- Цитата: Segaman от 17 Августа 2011, 16:53:41 ---респект за идею :D, но сие невыполнимо во всех планах. дюна не на гейм-мейкере сделана
--- Конец цитаты ---
Нашли тут код взрыва спайсовый пипки:
--- Код: ---ROM:0001ACB6 move.w #5,-(sp) ; radius
ROM:0001ACBA move.w d3,-(sp)
ROM:0001ACBC jsr sub_1ACC8
ROM:0001ACC2 addq.l #4,sp
ROM:0001ACC4 move.l (sp)+,d3
ROM:0001ACC6 rts
ROM:0001ACC6 ; End of function extra_hit
ROM:0001ACC6
ROM:0001ACC8
ROM:0001ACC8 ; =============== S U B R O U T I N E =======================================
ROM:0001ACC8
ROM:0001ACC8
ROM:0001ACC8 sub_1ACC8: ; ...
ROM:0001ACC8 movem.l d3-d7/a2-a5,-(sp)
--- Конец кода ---
--- Код: ---ROM:0001AD44 move.w #1,(sp) ; 1 (create spice)
ROM:0001AD48 move.w d5,-(sp) ; where create
ROM:0001AD4A jsr spice_del_or_cr
--- Конец кода ---
Может попробуешь переписать его в редактор для генерации карт?
1ACC8 - определяет блоки где создавать спайс.
jsr spice_del_or_cr (1A51С) - для каждого блока запускает создание спайса.
Как-то вот так от центра строится.
Добавлено позже:
--- Цитата: serj320 от 17 Августа 2011, 17:14:12 ---ghola дело в том что ром имеет весьма ограниченый размер, а новый дом это множество дополнительной информации.
--- Конец цитаты ---
Размер рома не особо ограничен. Можно напихать хоть 1000 уровней.
Для дома нужна только память ram, да и то не слишком много (да и можно просто заменить мерценаров).
А вот в палитрах ограничение есть, например только 4 палитры доступно.
Поэтому больше 4 разных цветов для юнитов и мигалок одновременно не сделать.
А основная сложность добавления нового дома в модификации кода и устранении всяких багов. Делали фрименов но не доделали) Что-то ИИ глючить начинал.
А с юнитами еще сложнее. Заменить - реально. А добавлять лучше не начинать даже (придется перебирать весь код). Кроме того под новый юнит все равно места в видеопамяти не будет.
ghola:
--- Цитата: Segaman от 17 Августа 2011, 16:53:41 ---респект за идею :D, но сие невыполнимо во всех планах. дюна не на гейм-мейкере сделана
--- Конец цитаты ---
Вот спасибо! Эта идея из другого проекта, но основывается он на дизайне Дюны 2.
А в ромхаке думал добавить отряды пехоты численностью 5, 7 и 9, а раз шипко сложно, то ну и чёрт с ними))
Навигация
Перейти к полной версии