PDA

Просмотр полной версии : Редактирование карты Rex



rasmer
20.09.2014, 16:24
Парни, кому не в западло, ближе к телу. По приведенному эффекту из AgonyMD меня интересует как сжать скроллер.давай сначала определимся, что значит 'сжать'?

ZX_NOVOSIB
18.11.2014, 17:18
Товарищи кодеры, помогите разобраться! Решил я значит подредактировать карты обоих левелов в REX, чтобы можно было свободно гулять по комнатам. Но прежде чем начать, хотелось бы понять, как сделать возможным возврат в нулевую комнату? Ведь в игре 0 - это запрет перехода.

char справился с этой проблемой. Он дал какой-то код, но как мне применить этот код к кодовым блокам рекса? Как этим кодом пропатчить те блоки, которые мне нужно? (хочу править русифицированую версию)

Вот несколько цитат с темы про правку карты рекса:


ладно, вот freeway, с нулевой комнатой, до конца вживую не проверял ;)



#d0a4 db #f8 ; [ret z] -> [ret m]
#d0b5 db #f8
#d13c db #f8
#d19f db #fa ; [jp z,..] -> [jp m,..]

#B133 db #ff,#01,#ff,#ff ;00
#B139 db #ff,#0F,#02,#00 ;01
#B13F db #01,#03,#ff,#ff ;02
#B145 db #0f,#04,#ff,#02 ;03
#B14B db #10,#05,#ff,#03 ;04
#B151 db #ff,#06,#ff,#04 ;05
#B157 db #ff,#07,#ff,#05 ;06
#B15D db #08,#14,#ff,#06 ;07
#B163 db #09,#18,#07,#ff ;08
#B169 db #ff,#19,#08,#0A ;09
#B16F db #ff,#09,#ff,#0B ;0a
#B175 db #13,#0a,#ff,#0C ;0b
#B17B db #12,#0b,#10,#0D ;0c
#B181 db #11,#0c,#0f,#ff ;0d
#B187 db #1E,#1a,#ff,#ff ;0e
#B18D db #0d,#10,#03,#01 ;0f
#B193 db #0c,#ff,#04,#0f ;10
#B199 db #1a,#12,#0d,#ff ;11
#B19F db #1b,#13,#0c,#11 ;12
#B1A5 db #1C,#ff,#0b,#12 ;13
#B1AB db #18,#15,#ff,#07 ;14
#B1B1 db #16,#ff,#ff,#14 ;15
#B1B7 db #17,#ff,#15,#18 ;16
#B1BD db #ff,#ff,#16,#19 ;17
#B1C3 db #19,#16,#14,#08 ;18
#B1C9 db #ff,#17,#18,#09 ;19
#B1CF db #1f,#1b,#11,#0E ;1a
#B1D5 db #20,#1c,#12,#1A ;1b
#B1DB db #21,#1D,#13,#1B ;1c
#B1E1 db #22,#ff,#ff,#1c ;1d
#B1E7 db #ff,#1F,#0e,#ff ;1e
#B1ED db #63,#20,#1a,#1e ;1f
#B1F3 db #ff,#21,#1b,#1F ;20
#B1F9 db #ff,#22,#1c,#20 ;21
#B1FF db #ff,#ff,#1d,#21 ;22



И как char'у удалось сделать возможным возврат на стартовый экран? )

теперь закрытый проход =#FF,а не 0

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

rasmer
18.11.2014, 17:50
либо запрет на вход меняй на любой другой неюзаный, либо нулевой экран перенумеруй....

ZX_NOVOSIB
18.11.2014, 18:07
rasmer, как поменять запрет на вход с #00 на #FF?
Как перенумеровать нулевой экран? Я нифига не понимаю ))

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

rasmer
18.11.2014, 18:18
ну раз тебе char выложил, то и попроси его применить...
ты здесь спросил как сделать возможным возврат, я тебе объяснил... а как и где менять - это сам ковыряй код игры... почитай капульцевича "как написать игру на асме" и инфоркомовский справочник по машкодам, я думаю через полгода-год найдёшь ответ в них... :)

Alex Rider
19.11.2014, 00:05
почитай капульцевича "как написать игру на асме"
А что там про взлом игр?

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

char
19.11.2014, 13:00
Товарищи кодеры, помогите разобраться! Решил я значит подредактировать карты обоих левелов в REX, чтобы можно было свободно гулять по комнатам. Но прежде чем начать, хотелось бы понять, как сделать возможным возврат в нулевую комнату? Ведь в игре 0 - это запрет перехода.

char справился с этой проблемой. Он дал какой-то код, но как мне применить этот код к кодовым блокам рекса? Как этим кодом пропатчить те блоки, которые мне нужно? (хочу править русифицированую версию)

Вот несколько цитат с темы про правку карты рекса:






хорошо, набросал патчилку на бейсике, проверяй:
можно патчить что-угодно, в операторах data указывая стартовый адрес, пробел, и дальше - последовательность байт для poke (1 байт = 2 символа в шестнадцатеричном)



10 goto 30
20 rem h= HexToDec(h$)
21 let h=0:let p=1:for L=len h$ to 1 step -1:let k=code h$(L)-48
23 if k>10 then let k=k-7:if k>15 then let k=k-32:if k<0 or k>15 then print "error!":stop
25 let h=k*p+h:let p=p*16:next L: return
30 read a$:if len a$>0 then print inverse 1;" #";a$:let h$=a$(to 4):gosub 20: let adr=h:let a$=a$(6 to):for i=1 to len a$/2:let h$=a$(i*2-1 to i*2):gosub 20:poke adr+i-1,h:print adr+i-1;" ";h:next i:goto 30

1000 data "d0a4 f8"
1010 data "d0b5 f8"
1020 data "d13c f8"
1030 data "d19f fa"
1040 data "B133 ff01ffff"
1050 data "B139 ff0F0200"
1060 data "B13F 0103ffff"
...
1999 data ""

denpopov
19.11.2014, 13:07
пора открывать тендер "Поможем Новосибу!":)

ZX_NOVOSIB
19.11.2014, 16:04
хорошо, набросал патчилку на бейсике, проверяй:
можно патчить что-угодно, в операторах data указывая стартовый адрес, пробел, и дальше - последовательность байт для poke (1 байт = 2 символа в шестнадцатеричном)
Спасибо! Код бейсика у тебя на высшем уровне :v2_thumb:

Когда я задавал вопрос, про то как ты изменил запрет на вход, то я неправильно выразился. Я затупил и поэтому не разглядел, что измена запрета входа с 00 на ff это: poke 53412,248/ 53429,248/ 53564,248/ 53663,250. Именно про это я и спрашивал. Я не имел ввиду как ты вышел на эти адреса, понятно, что для этого надо как минимум, фигурально выражаясь, "полгода читать капульцевича" )))

Так бывает, что человек спрашивает одно, а ему отвечают другое, ибо никто не допускает даже мысли, что человек, задавая вопрос, элементарно затупил, или упустил что-то из виду.

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

---------- Post added at 19:04 ---------- Previous post was at 18:57 ----------

И по горячим следам у меня еще один вопрос. Как юзать патчилку на бейсике - это понятно. Загружаем патчилку, загружаем блок, запускаем патчилку, она патчит. А как юзать патчилку на асме, которую ты выкладывал? Я правильно понял, что нужно открыть редактор ассемблера, вбить туда код (а скопипастить как-нибудь можно?), потом это всё надо скомпилровать в машинный код, а дальше уже юзать этот код как бейсик-патчилку? Или я что-то напутал?

char
19.11.2014, 16:51
на асме примерно так:



org #4000 ;16384
;
PATCH
ld hl,P_DATA
patchlp
ld e,(hl)
inc hl
ld d,(hl)
inc hl
ld a,e
or d
ret z ;de=#0000=exit
ld c,(hl)
inc hl
ld b,#00
ldir
jr patchlp
;
P_DATA
dw #d0a4
db 1,#f8
dw #d0b5
db 1,#f8
dw #d13c
db 1,#f8
dw #d19f
db 1,#fa
dw #B133
db 4,#ff,#01,#ff,#ff
dw #B139
db 4,#ff,#0F,#02,#00
dw #B13F
db 4,#01,#03,#ff,#ff
dw #B145
db 4,#0f,#04,#ff,#02
;...
dw #0000 ;finish
;
P_LEN equ $-PATCH ; for save "mypatch" code 16384,P_LEN

ZX_NOVOSIB
22.11.2014, 00:49
Переделку обоих левелов рекса я закончил. Впринципе уже можно написать загрузчик на бейсике с покесами и всё.. Но хочется еще что-нибудь замутить )) Посему два вопроса:

1. Как сравнить два крупных файла (которые одновременно в память спекка не помещаются) на предмет выявления отличий? На предмет выявления адресов отличающихся ячеек. (Адреса нужны именно в спековском формате, поэтому WinHex не пойдет)

На ум приходит только такой адский способ: юзаем бейсик128: загружаем файл1, сохраняем его на кремниевый диск (SAVE!). Загружаем файл2, тоже сохраняем его. Считываем 1-ую ячейку из находящегося в памяти файл2, запоминаем значение. Загружаем из памяти файл1, считываем его первую ячейку, сравниваем значения. И т.д.

2. Можно ли сделать так, чтобы в финале рекс1, после показа кода, не начиналась заново игра, а управление возращалось бы бейсику? (Вроде после загрузки кодового блока для бейсика еще остается место, сужу по русифицированной версии, в строку редактирования не вернутся, идет сброс, а вот сама программа выполняется.)

И тот же вопрос относительно демо-рекса, чтобы по окончании демо бы управление возвращалось бы в бейсик. В аттаче снапшоты, 1-ый рекс и демо, почти финал. В 1-ом только прыгнуть, в демо рекс сваливается в яму, возраждается, идет надпись про то кто писал музыку и потом всё заново.

drbars
22.11.2014, 01:53
[QUOTE=ZX_NOVOSIB;755711]Переделку обоих левелов рекса я закончил. Впринципе уже можно написать загрузчик на бейсике с покесами и всё.. Но хочется еще что-нибудь замутить )) Посему два вопроса:

1. Как сравнить два крупных файла (которые одновременно в память спекка не помещаются) на предмет выявления отличий? На предмет выявления адресов отличающихся ячеек.

http://s020.radikal.ru/i700/1411/2e/e94e9b21a8a5.png (http://www.radikal.ru)

Не?:D

Destr
22.11.2014, 03:27
Total Commander - руль!
А чтобы адреса были в "спековском" формате - можно "приклеить" (тем-же Тоталом) в начало каждого файла по куску произвольных данных (имитация ПЗУ).
Тогда при сравнении адреса будут соответствовать реальным.

ZX_NOVOSIB
22.11.2014, 15:59
Спасибо! Правда я уже сам допёр. Сравнивать можно и винхексом )) И предварительно можно приклеить в начало 16357-байтный кусок! Сравнение нужно было вот для чего:

Я по наивности думал, что бейсик загрузчик сможет вносить покесы в сжатый хрустом блок, ибо в таком случае для бейсик загрузчика-трейнера остается много места. Однако сравнение двух архивов хруста показало, что они чересчур сильно отличаются. Хотя в исходном файле изменен всего 1 байт, но хруст пакует их абсолютно по разному :)

Придется писать короткий загрузчик, и то, есть подозрение, что нифига не получится. Ибо в руссифицированно-дикофицированном варианте с вирта для каждой части свой загрузчик-трейнер, видимо для бейсик загрузчика не хватило места. Надо поэкспериментировать..

А насчет возврата управления бейсику, это реально? Вроде бы код 201 должен возвращать в бейсик, только куда его вставить? :v2_conf2:

rasmer
22.11.2014, 16:10
чтобы вернуться в бейсик надо посмотреть - а не похерены ли бейсиковские переменные, и на всякий случай при запуске сохранить все регистры, а перед выходом - восстановить...

ZX_NOVOSIB
22.11.2014, 16:30
чтобы вернуться в бейсик надо посмотреть - а не похерены ли бейсиковские переменные, и на всякий случай при запуске сохранить все регистры, а перед выходом - восстановить...короче это чересчур трудоемко? Значит от идеи "загрузка после демо первой части" и "второй по окончании первой" видимо придется отказаться.

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

..может можно как-то 128-ую память заюзать?

rasmer
22.11.2014, 17:03
что сложного - то? сначала всё запушил, потом запопил всё :) если переменные бейсика трутся, то сохранил лдиром, потом также наместо перекинул тем же лдиром.

про call #3d13 слышал?

ZX_NOVOSIB
23.11.2014, 00:59
rasmer, про call #3d13 я не слышал ) Я вообще ничего не слышал, ибо пока не читал Капульцевича )

Подскажите, как вычислить верхнюю границу бейсик программы? Т.е. допустим кодовый блок начинается с адреса ххх, как узнать, наезжает бейсик на этот адрес или еще нет? В книге "ZX Spectrum Диалекты бейсика" пишут:


Например, нас может заинтересовать длина написанной бей-
сик-программы. Выберем из системных переменных PROG
(23635/36) и VARS (23627/28) адреса начала бейсик-программы
и начала области бейсик-переменных и вычтем одно из другого:

print (реек 23635+256*реек 23636)-(реек 23627+256*реек 23628)

Пробовал в спектакуляторе, пишет какую-то ерунду со знаком минуса :(

SAM style
23.11.2014, 01:07
Пробовал в спектакуляторе, пишет какую-то ерунду со знаком минуса :(Потому что наоборот надо. PROG - это начало бейсик-программы, VARS - начало области переменных, которая идёт за бейсиком. А вообще, поставь CLEAR xxx-1 и с адреса xxx можешь ложить код. Если бейсику не хватит отрезанного пространства - он ругнётся.

ZX_NOVOSIB
23.11.2014, 01:21
Потому что наоборот надо. PROG - это начало бейсик-программы, VARS - начало области переменных, которая идёт за бейсиком.Поменял местами, стало писать какие-то двух-трехзначные числа, в зависимости от того сколько строк/операторов. Вроде это работает! Когда добавляешь строки или операторы, то число увеличивается. Удаляешь - уменьшается. Когда цифры обрамляешь в VAL "", тоже уменьшается. Число, которое выдает эта прога, это длина в байтах? Если да, то к какому адресу её нужно прибавлять, чтобы вычислить верхнюю границу бейсик-проги?
А вообще, поставь CLEAR xxx-1 и с адреса xxx можешь ложить код. Если бейсику не хватит отрезанного пространства - он ругнётся.
Это не совсем удобно. В моем случае адрес начала кода известен и его не изменить. А делать CLEAR xxx-1 после каждой введенной строки, слишком муторно, лучше способ из книги как-то допонять/допилить.

ZX_NOVOSIB
23.11.2014, 17:28
Ну вы блин даёте )) Раз уж на то пошло, то прилипите эти посты в конец этой темы (http://zx-pk.ru/showthread.php?t=24237).

---------- Post added at 20:28 ---------- Previous post was at 20:20 ----------

Если это невозможно, то перенесите хотя бы в другой раздел, в "Для начинающих", или в "Программирование".

goodboy
23.11.2014, 18:56
делать CLEAR xxx-1 после каждой введенной строки, слишком муторно
одного раза достаточно.
если не хватит места то он ругнётся и строка не вставится в программу.
начинающему ещё можно заюзать пакер от Сендецкого, он позволяет после распаковки изменить три ячейки на выбор.

ZX_NOVOSIB
23.11.2014, 20:07
одного раза достаточно.
если не хватит места то он ругнётся и строка не вставится в программу.В теории это всё так. Щас специально сделал низкий RAMTOR и пробовал повбивать строки. Да, новую строку в конец программы бейсик в какой-то момент не дает вбить, пишет ошибку. Но можно вставить строку в начало, можно вставить оператор в существующую строку и тогда всё зависает к чертям собачим )) Стрелки по строкам передвигаются, больше никакие кнопки не работают. Так что в теории это всё так, но на практике не всё так идеально. Будем считать, что метод тыка - единственный надежный метод.


начинающему ещё можно заюзать пакер от Сендецкого, он позволяет после распаковки изменить три ячейки на выбор.http://speccy.info/ASCLZPAC - этот? А где его скачать?

denpopov
23.11.2014, 20:12
http://speccy.info/ASCLZPAC - этот? А где его скачать?

полистай тему, я выкладывал.
http://zx-pk.ru/showthread.php?t=22153
а лучше учись Exomizer'y.

ZX_NOVOSIB
23.11.2014, 21:46
нашёл, скачал.. Но не осилил ) Это явно не хрум/хруст, там всё понятно и наглядно. Видимо автор делал исключительно для себя, и ему всё было понятно, ведь он автор.

denpopov
24.11.2014, 05:36
Это явно не хрум/хруст, там всё понятно и наглядно. Видимо автор делал исключительно для себя, и ему всё было понятно, ведь он автор.

тогда - Вон из профессии) LZSSPACK прост как.. я не знаю что.

ZX_NOVOSIB
27.11.2014, 23:59
Пишу тут загрузчик на бейсике. В общем 5 картинок сжал упаковщиком экранов, потом загрузил их последовательно в память, друг над дружкой, потом весь этот блок сохранил. Потом это блок сжал хрустом. Начал всё это тестировать из под бейсика, и выяснилось, что такая конструкция не хочет работать в 128-ом режиме. Работает либо через usr 0, либо в 48-ом. Пробовал и разные экранные паковщики и разные адреса, всякие возможные комбинации - нифига не помогает, при чем всё крашится каждый раз по разному и в спекуляторе и в унриале. Неужели придется делать 48 ONLY? Или от хруста отказаться? Без него всё вроде работает.

В аттаче пример. Грузится архив, он распаковывается и автостартует с адреса первой картинки (в данном случае 46000) В 48 всё работает, в 128 - каждый раз разный глюк.

SAM style
28.11.2014, 00:07
В аттаче пример. Грузится архив, он распаковывается и автостартует с адреса первой картинки (в данном случае 46000) В 48 всё работает, в 128 - каждый раз разный глюк.
CLEAR. Где у тебя CLEAR? Работаешь с кодом из бейсика - ставь стек ниже кода!
1 CLEAR 32412

ZX_NOVOSIB
28.11.2014, 00:17
Про CLEAR я в курсе )) В данном случае CLEAR 32412 не помогает. И CLEAR 45999 тоже. Поэтому их и нет в примере.

goodboy
28.11.2014, 00:21
В 48 всё работает, в 128 - каждый раз разный глюк.
у тебя распаковщик находится в буфере принтера (с 23296), а 128ой бейсик этого не-любит, у него там переменные и код отслеживающий текущую страницу).
затирая его ты тем самым нарушаешь работу интерпретатора.

ZX_NOVOSIB
28.11.2014, 00:33
goodboy, распаковщик хруста в буфере? Из-за этого вся байда? А какой адрес лучше подойдет? 16384 с черными атрибутами сойдет?

Кстати, а распаковщики картинок в буфер принтера не лезут?

SAM style
28.11.2014, 00:39
5 картинок сжал упаковщиком экранов, потом загрузил их последовательно в память, друг над дружкой, потом весь этот блок сохранил. Потом это блок сжал хрустом
К слову, упаковывать упакованные картинки - то ещё развлечение. Если и будет выигрыш, то очень небольшой.

goodboy
28.11.2014, 00:41
А какой адрес лучше подойдет? 16384 с черными атрибутами сойдет?
лучше 22528, красивей будет выглядеть

ZX_NOVOSIB
28.11.2014, 01:00
К слову, упаковывать упакованные картинки - то ещё развлечение. Если и будет выигрыш, то очень небольшой.
Ну в моем случае ужалось с 18347 до 13587, т.е. процентов на 25, неплохо )

Я перепробовал кучу паковщиков картинок, чтобы при распаковывании картинка быстро выводилась на экран и чтобы размер при этом был поменьше. Остановился на MAXSOFT SCREEN PACKER v1.6, там в настройках нужно выбрать депакер FAST.LIN. Может что-то и получше есть, незнаю, но обычно либо картинка сильно ужимается, но потом долго рисуется, либо рисуется быстро, но ужимается очень мало. MSP с режимом FAST.LIN - золотая середина.

---------- Post added at 04:00 ---------- Previous post was at 03:58 ----------


лучше 22528, красивей будет выглядеть
цветные квадратики сверху экрана это красивей? Или это типа шутка была? :)

ZX_NOVOSIB
28.11.2014, 16:36
Работаешь с кодом из бейсика - ставь стек ниже кода!
1 CLEAR 32412Кстати иногда CLEAR не нужен, а иногда даже вреден. Ибо он обнуляет переменные. Можно сократить бейсик программу если вместо цифр использовать переменные, а переменные эти задавать не из программы, а "из командной строки", это позволит еще выиграть свободного места. Но эти заданные переменные обнуляются операторами RUN и CLEAR. Впрочем всё это актуально исключительно для бейсика :)

ZX_NOVOSIB
29.11.2014, 23:52
у тебя распаковщик находится в буфере принтера (с 23296), а 128ой бейсик этого не-любит, у него там переменные и код отслеживающий текущую страницу).
затирая его ты тем самым нарушаешь работу интерпретатора.
А если после распаковки блока, происходит auto jump на точку входа игры, и возвращение в бейсик не происходит, то можно разместить распаковщик этого блока в буфере принтера?

SAM style
30.11.2014, 00:27
А если после распаковки блока, происходит auto jump на точку входа игры, и возвращение в бейсик не происходит, то можно разместить распаковщик этого блока в буфере принтера?
Выключить прерывания - и можно, но потом не включать IM0/IM1 с 128м бейсиком.
Лучше нарисовать кодовый загрузчик, который сам включит basic48, тогда буфер не будет использоваться.

goodboy
30.11.2014, 00:33
Лучше нарисовать кодовый загрузчик, который сам включит basic48, тогда буфер не будет использоваться.
проще отключить один бит в переменной FLAGS

ZX_NOVOSIB
30.11.2014, 00:57
Выключить прерывания - и можно, но потом не включать IM0/IM1 с 128м бейсиком.
Лучше нарисовать кодовый загрузчик, который сам включит basic48, тогда буфер не будет использоваться.Короче без кодового загрузчика, включающего basic48, в буфер принтера нельзя ложить депакер? Почему? Ведь к бейсику возврата не будет. Я думал если возврат в бейсик не планируется, то пофиг, что что-то там у бейсика попортится. Я ошибался?

---------- Post added at 03:57 ---------- Previous post was at 03:55 ----------


проще отключить один бит в переменной FLAGSэто можно сделать из под бейсика?

SAM style
30.11.2014, 01:16
Я думал если возврат в бейсик не планируется, то пофиг, что что-то там у бейсика попортится. Я ошибался?Есть ещё такая штука, как прерывания. в режимах 0 и 1 каждые 20мс выполняется код по адресу 56. Если в данный момент включен бейсик128, то эта п/п полезет в буфер. И в 128, и в 48 бейсике она меняет переменные, плюс IY должен быть 23610.

goodboy
30.11.2014, 01:32
Если в данный момент включен бейсик128, то эта п/п полезет в буфер.
res 4,(iy+1) как раз и отключает эти лазанья

SAM style
30.11.2014, 02:03
res 4,(iy+1) как раз и отключает эти лазаньяСбросил в отладчике. По-моему, ему пофиг. Сбросил через POKE в 128м бейсике. Тоже никаких изменений.

0038:PUSH HL
LD HL,0048
PUSH HL
LD HL,5B00
PUSH HL
LD HL,0038
PUSH HL
JP 5B00
0048:POP HL
RET

goodboy
30.11.2014, 11:08
Сбросил в отладчике. По-моему, ему пофиг. Сбросил через POKE в 128м бейсике. Тоже никаких изменений.
это справедливо для редактора, в запущенной программе подключено 48ое ПЗУ

ZX_NOVOSIB
01.12.2014, 19:46
Кажется я перехитрил сам себя.
Загрузчик с трейнером на бейсике нифига не работает.

Идея была такой: грузим блок с картинками, выбираем часть, выбираем читы, после этого грузим блок с игрой. Делаем CLEAR, чтобы сработал депакер, который помещен еще чуть ниже всей конструкции. Блок распаковываем, он распаковывается на две части, основной несжатый блок, и снизу его прилеплен маленький сжатый. В несжатый блок записываем выбранные в трейнере читы, потом маленький блок распаковывается и автостартует. Такая схема высвобождает несколько килобайт для бейсик-загрузчика.

Первая тестовая сборка (1190 байт бейсика и переменных) дала следущий результат:
48-ой бейсик ближе к финалу не мог вернутся из одной из подпрограмм, писал, что мол наткнулся на RETURN, а куда возвращаться не знает. Хотя в эту подпрограмму он попал именно по GO SUB. Девичья память. 128-ой бейсик ведет себя уже по другому. Он, повстречав RETURN, не ругается, а просто игнорирует его, перепрыгивает и переходит к следущей строке. Но это всё ерунда, всё это можно победить-перехитрить.

Не перехитрить лишь вот что: перед финальной распаковкой-автозапуском нужно сделать CLEAR 24599. Бейсик это делать не хочет, пишет Ramtor no good. А если не сделать CLEAR, то блок распаковывается и игра стартует, но зависает или глючит. Короче х.з. что теперь делать. Сделать без трейнера что-ли? И то х.з. влезет ли хотя бы выбор части и показ картинок))

Eagle
01.12.2014, 19:57
ZX_NOVOSIB, а в кодах патчер сделать никак нельзя чтоли?

ZX_NOVOSIB
01.12.2014, 20:07
в трейнере происходил выбор читов. Грубо говоря 0 - нет чита, 1- есть чит. По некоторым причинам запоминание выбора происходило в переменных. Перед первым CLEAR переменные запоминались посредством POKE. Ибо CLEAR обнуляет все переменные. Потом посредством PEEK смотрелись значения и если где-то было 1, то делались соответствующие покесы (таймер, жизнь, защита или ускорение).

Если делать в кодах, то делать в кодах надо всё, абсолютно всё )) Я умею только на бейсике.

Alex Rider
01.12.2014, 20:10
48-ой бейсик ближе к финалу не мог вернутся из одной из подпрограмм, писал, что мол наткнулся на RETURN, а куда возвращаться не знает. Хотя в эту подпрограмму он попал именно по GO SUB. Девичья память. 128-ой бейсик ведет себя уже по другому. Он, повстречав RETURN, не ругается, а просто игнорирует его, перепрыгивает и переходит к следущей строке.
Что как бы намекает, что портится стек возвратов, который должен выставляться CLEAR'ом в безопасное место.

Не перехитрить лишь вот что: перед финальной распаковкой-автозапуском нужно сделать CLEAR 24599.
Перед распаковкой загрузи отдельную BASIC-программу из одной строчки CLEAR VAL "24599": RANDOMIZE USR VAL "XXX"

Alex Rider
01.12.2014, 20:10
48-ой бейсик ближе к финалу не мог вернутся из одной из подпрограмм, писал, что мол наткнулся на RETURN, а куда возвращаться не знает. Хотя в эту подпрограмму он попал именно по GO SUB. Девичья память. 128-ой бейсик ведет себя уже по другому. Он, повстречав RETURN, не ругается, а просто игнорирует его, перепрыгивает и переходит к следущей строке.
Что как бы намекает, что портится стек возвратов, который должен выставляться CLEAR'ом в безопасное место.

Не перехитрить лишь вот что: перед финальной распаковкой-автозапуском нужно сделать CLEAR 24599.
Перед распаковкой загрузи отдельную BASIC-программу из одной строчки CLEAR VAL "24599": RANDOMIZE USR VAL "XXX"

ZX_NOVOSIB
01.12.2014, 20:38
Перед распаковкой загрузи отдельную BASIC-программу из одной строчки CLEAR VAL "24599": RANDOMIZE USR VAL "XXX"Это решение само собой подразумевается. Но получается 4 бейсик программы (трейнер с картинками, загрузчики для 1,2 и демо) и 4 кодовых блока. Это что-то с чем-то )) Не хотелось бы отходить от схемы "1 игра - 1 бейсик загрузчик+несколько кодовых блоков".

---------- Post added at 23:38 ---------- Previous post was at 23:27 ----------

Если была бы в бейсике функция "отгрузить текущую программу, начиная с такой-то строки", то можно было бы в самом начале отгрузить в RAM короткую программулину, а потом в конце её загрузить. Правда получилось бы 128 ONLY, но это пофиг.

Eagle
01.12.2014, 20:43
Если делать в кодах, то делать в кодах надо всё, абсолютно всё )) Я умею только на бейсике.
Не надо там всего делать, все красивости делаешь в васике, который подготавливает нужный код, а далее все красивости можно стирать и грузить остальное. Когда-то я так делал.

Alex Rider
01.12.2014, 21:07
Не хотелось бы отходить от схемы "1 игра - 1 бейсик загрузчик+несколько кодовых блоков".
Тогда ассемблер :)
Смотри. Все просто. Качаешь вот это:
Sublime Text 3 (http://c758482.r82.cf2.rackcdn.com/Sublime%20Text%20Build%203065.zip)
SjAsm plus (http://sourceforge.net/projects/sjasmplus/files/latest/download)
Настраиваешь Sublime Text как написано в этой (http://zx-pk.ru/showthread.php?t=21731) теме.
Открываешь Sublime Text, создаешь в нем новый файл и сохраняешь под именем rst8.a80. Пишешь в нем такой код:


DEVICE ZXSPECTRUM48

ORG #8000
Start:
rst #08
db #08
End:

EMPTYTRD "rst8.trd"
SAVETRD "rst8.trd", "rst8.C", Start, End - Start


Выбираешь меню Z80Asm\Build. Получаешь файл rst8.trd рядом с rst8.a80. Открываешь его в эмуляторе, пишешь такой boot.B:


10 CLEAR 32767: RANDOMIZE USR 15619: REM: LOAD "rst8" CODE
20 RANDOMIZE USR 32768

Запускаешь командой RUN. Получаешь 9 STOP Statement. Ты писал STOP? Нет. Откуда сообщение? Это твоя первая программа на ассемблере его вывела. Как настроишь все - дальше будем писать патчер в кодах.

---------- Post added at 21:07 ---------- Previous post was at 20:52 ----------

Если с Sublime Text все выглядит сложно, то тот же код можно написать в блокноте Windows, положить его рядом с SjAsm plus и выполнить в cmd.exe команду


sjasmplus.exe rst8.a80

Получишь опять же rst8.trd

ZX_NOVOSIB
02.12.2014, 21:02
Тогда ассемблер :)
Смотри. Все просто. Качаешь вот это:
Sublime Text 3 (http://c758482.r82.cf2.rackcdn.com/Sublime%20Text%20Build%203065.zip)
SjAsm plus (http://sourceforge.net/projects/sjasmplus/files/latest/download)
Настраиваешь Sublime Text как написано в этой (http://zx-pk.ru/showthread.php?t=21731) теме.
Скачал, но как настроить я не понял, в той теме особо ничего не сказано про настройку.
Открываешь Sublime Text, создаешь в нем новый файл и сохраняешь под именем rst8.a80. Пишешь в нем такой код:


DEVICE ZXSPECTRUM48

ORG #8000
Start:
rst #08
db #08
End:

EMPTYTRD "rst8.trd"
SAVETRD "rst8.trd", "rst8.C", Start, End - Start


Выбираешь меню Z80Asm\Build.Файл создать могу, но только методом копипасты из твоего поста. Потому как полнейшие непонятки со всякими там пробелами, отступами, табами. От руки повторить твой код не могу. Где искать "меню Z80Asm\Bulid" тоже не ясно.

Если с Sublime Text все выглядит сложно, то тот же код можно написать в блокноте Windows, положить его рядом с SjAsm plus и выполнить в cmd.exe команду


sjasmplus.exe rst8.a80

Получишь опять же rst8.trdВот это сработало! (получился трд с кодовым блоком) Но опять-таки только копипастой, ибо не могу понять где в коде пробелы, где табы, где ентеры, где вообще что )))

Как настроишь все - дальше будем писать патчер в кодах.Спасибо конечно за помощь, но я даже не представляю как должен выглядеть этот патчер. Что ты подразумеваешь под патчером? Что он будет делать? В аттаче трд с моим загрузчиком рекса, можно посмотреть что он делает. (Если грузить не из под boot'a, а напрямую, то можно даже выбрать вторую часть и она запустится, можно выбрать управление, но при старте будет сюрприз )) boot почему-то оказывает какое-то влияние, хотя не должен.) Если патчер в кодах должен будет делать всё то, что делает мой бейсик, то мы запаримся писать такой патчер )) Если он должен делать что-то меньшее, то тогда бейсик останется большим, а большой бейсик не даст ничего запустить..

ZX_NOVOSIB
02.12.2014, 22:05
Не надо там всего делать, все красивости делаешь в васике, который подготавливает нужный код, а далее все красивости можно стирать и грузить остальное. Когда-то я так делал.Если честно, то я не понял о чем речь. Можешь привести простой пример? Вот я выложил свой загрузчик. Там есть "красивости", типа выбор нужной части, вызов нужных картинок, выбор читов под суровым взглядом рекса. И как потом стереть все эти красивости и грузить остальное? Что остальное?

Eagle
02.12.2014, 22:11
патчер в кодах должен будет делать всё то, что делает мой бейсик
Вовсе не обязательно, меню с выбором чего пачтить оставить в бейсике, а в кодах достаточно только самих изменённых байт и их копирование в нужные ячейки.
Что бы исключить из патчера не нужное — из бейсика править лишь несколько байт, которые например содержат "call addr", где addr адрес части патчера.
Но самое красивое решение будет полностью все на ассемблере сделать.

ZX_NOVOSIB
02.12.2014, 22:38
Но самое красивое решение будет полностью все на ассемблере сделать.Кто бы спорил ))

Вовсе не обязательно, меню с выбором чего пачтить оставить в бейсике, а в кодах достаточно только самих изменённых байт и их копирование в нужные ячейки.
Что бы исключить из патчера не нужное — из бейсика править лишь несколько байт, которые например содержат "call addr", где addr адрес части патчера.Даже простейшее меню с выбором части и выбором "чего патчить" не влезет. CLEAR 24599 - суровая штука, она не оставляет места ни для чего. А из-за обращений к тр-досу, места остается еще меньше.

Eagle
02.12.2014, 22:49
Даже простейшее меню с выбором части и выбором "чего патчить" не влезет.
Меню картинкой нарисовать, опрос кнопок тоже в ассемблер перевести.
Когда нечто подобное делал, то из ассемблера вызывал только загрузку с кассеты, тогда у меня дисковода ещё не было.

Alex Rider
02.12.2014, 23:01
Скачал, но как настроить я не понял, в той теме особо ничего не сказано про настройку.
Уже делаю нормальный пак софта для начала ассемблерного творчества.

Потому как полнейшие непонятки со всякими там пробелами, отступами, табами. От руки повторить твой код не могу.
Ассемблер не отличает Tab, один или несколько пробелов. Ему важно чтобы в нужном месте были разделители. Строки с двоеточиями (Start:, например) - это так называемые метки (http://zxpress.ru/book_articles.php?id=1024) (см. раздел "Структура ассемблерной строки") должны начинаться с первого символа строки, остальное (команды, директивы) - хотя бы после одного пробела, лучше одного Tab'а для красоты.

Где искать "меню Z80Asm\Bulid" тоже не ясно.
Оно появляется когда ставишь плагин из темы, что писал выше. Ща сформирую набор софта и инструкцию куда положить чтобы появилось.

Что ты подразумеваешь под патчером? Что он будет делать?
Да, в общем-то, перепишем с тобой весь этот Бэйсик-загрузчик на ассемблер, сделаем целиком кодовый загрузчик. Заодно и поднатореешь в кодах, будешь потом сам менять игры как хочешь.

Если патчер в кодах должен будет делать всё то, что делает мой бейсик, то мы запаримся писать такой патчер ))
Ага :) Не все сразу. Зато научимся писать их какие хочешь. Или это не цель для тебя?

Alex Rider
02.12.2014, 23:31
Итого.
1. Нам еще пригодится для работы эмулятор Unreal Spectrum (http://dlcorp.nedopc.com/viewtopic.php?f=27&t=1345), ибо у него хороший отладчик. Распакуй скачанный архив (инсталляции нет), переименую в нем файл unreal-p4.exe в unreal.exe и положи рядом с ним (замени, если надо) unreal.ini из вложения.
2. В папке установки Sublime Text 3 есть папка Data\Packages. В нее надо распаковать приложенный архив (так, чтобы там стало 2 папки - User z80asm) и - в Sumlime Text появится пункт меню z80asm. Внутри папки z80asm есть файлы run.bat и build.bat - в первом меняешь путь к unreal.exe на свой, во втором - к sjasmplus.exe. Тогда по командае z80asm\Build у тебя будет компилиться проект, по команде z80asm\Run будет подниматься эмулятор с собранным trd-образом.

Alex Rider
03.12.2014, 00:08
Кстати, вот тебе для затравки еще один пример. С boot.B надо сделать те же манипуляции, что и с rst8.a80. Работают кнопки 1-4 и пробел. И не безумно оно сложно :) И размер тебя порадует, хотя при отказе от Basic'а на него в 99% плевать.


DEVICE ZXSPECTRUM128

cls = #0d6b
chan_open = #1601
print_string = #203c
LAST_K = #5c08

org #8000
Start:
call cls
ld a,#02
call chan_open
call print_menu
res 5,(iy + #01)
loop: halt
bit 5,(iy + #01)
jr z,loop
res 5,(iy + #01)
ld a,(LAST_K)
cp " "
jr z,exit
sub "1"
jr c,loop
ld hl,item_1 + 1
jr z,switch
ld hl,item_2 + 1
dec a
jr z,switch
ld hl,item_3 + 1
dec a
jr z,switch
ld hl,item_4 + 1
dec a
jr nz,loop
switch:
inc a
xor (hl)
ld (hl),a
ld a,#16
rst #10
xor a
rst #10
rst #10
call print_menu
jr loop

print_menu:
ld de,menu_text
ld bc,end_menu_text - menu_text
jp print_string

exit:
rst #08
db #08


menu_text:
item_1:
db #14, #01, "Item 1", #0d
item_2:
db #14, #00, "Item 2", #0d
item_3:
db #14, #00, "Item 3", #0d
item_4:
db #14, #00, "Item 4", #0d
end_menu_text:
End:

EMPTYTRD "menu.trd"
SAVETRD "menu.trd", "menu.C", Start, End - Start


PS. У тебя в загрузчике используется RUN "что-то там"CODE. Не делай так. TR-DOS состоит из багов с небольшим вкраплением работоспособного кода, код команды RUN для кодового блока не попал в счастливую безбажную область. Если скомпилишь мой пример и запустишь его из BASIC по-человечески и через RUN "menu" CODE в TR-DOS и нажмешь пробел, почувствуешь разницу :)

goodboy
03.12.2014, 11:36
В папке установки Sublime Text 3 есть папка Data\Packages. В нее надо распаковать приложенный архив и - в Sumlime Text появится пункт меню z80asm.
спасибо за совет, а то в ReadMe написано "Copy the `z80asm` directory to the Sublime Text `Packages` directory. Installation is complete."

Alex Rider
03.12.2014, 12:23
спасибо за совет
Ты тока эта... Аккуратнее с моим аттачем - там не совсем то, что в теме про плагин обсуждалось. В частности, там перепаханы run.bat и compile.bat для работы с проектами, кастомными bat-файлами проектов и просто с .a80-файлом. Это все нигде не документировано, так что от греха лучше юзать плагин из темы.

goodboy
03.12.2014, 14:44
Аккуратнее с моим аттачем
даже не-смотрел.
изначально запутался с размещением плагина
/Data/Packages/
/Packages

ZX_NOVOSIB
05.12.2014, 00:55
Уже делаю нормальный пак софта для начала ассемблерного творчества.Пак софта делать надо, безотносительно меня и моей лени :) Для всех. Чтобы была одна папка, которую можно было бы распаковать в корень диска С, и чтобы сразу всё это работало, без всякой кутерьмы с перетаскиванием папок и изменением путей! Чтобы "даже ААА смог".

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

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


Итого.
1. Нам еще пригодится для работы эмулятор Unreal Spectrum (http://dlcorp.nedopc.com/viewtopic.php?f=27&t=1345), ибо у него хороший отладчик. Распакуй скачанный архив (инсталляции нет), переименую в нем файл unreal-p4.exe в unreal.exe и положи рядом с ним (замени, если надо) unreal.ini из вложения.с этим ини-файлом унреал не запускается, пишет, что версия не та, надо изменить версию с 38.1 на 38.2. И зачем он вообще нужен этот ини? Я к своему ини привык )) Если в нем что-то важное, то лучше скажи, что именно изменить, я в своём изменю.


2. В папке установки Sublime Text 3 есть папка Data\Packages. В нее надо распаковать приложенный архив (так, чтобы там стало 2 папки - User z80asm) и - в Sumlime Text появится пункт меню z80asm. Внутри папки z80asm есть файлы run.bat и build.bat - в первом меняешь путь к unreal.exe на свой, во втором - к sjasmplus.exe. Тогда по командае z80asm\Build у тебя будет компилиться проект, по команде z80asm\Run будет подниматься эмулятор с собранным trd-образом.Проект компилится, и это главное. Но унреал с собранным трд не поднимается, Sublime пишет:
[Finished in 0.0s with exit code 4294967295]
[cmd: ['C:\\ZX\\asm\\Sublime Text Build 3065\\Data\\Packages/z80asm/run.bat', 'opros2.a80', '']]
[dir: C:\ZX\asm\us0.38.2]
[path: c:\Program Files\NVIDIA Corporation\PhysX\Common;C:\WINDOWS\system32;C:\WI NDOWS;C:\WINDOWS\System32\Wbem]
Впринципе пофиг, можно в проводнике по образу два раза щелкнуть.


PS. У тебя в загрузчике используется RUN "что-то там"CODE. Не делай так. TR-DOS состоит из багов с небольшим вкраплением работоспособного кода, код команды RUN для кодового блока не попал в счастливую безбажную область. Если скомпилишь мой пример и запустишь его из BASIC по-человечески и через RUN "menu" CODE в TR-DOS и нажмешь пробел, почувствуешь разницу :)
Про ран в тр-досе я в курсе. Если после рана кодового блока не планируется возврат к бейсику (а у меня именно так), то можно наверно и ран применять, экономия места типа. Разве нет? )

Rindex
05.12.2014, 01:34
с этим ини-файлом унреал не запускается, пишет, что версия не та, надо изменить версию с 38.1 на 38.2. И зачем он вообще нужен этот ини? Я к своему ини привык )) Если в нем что-то важное, то лучше скажи, что именно изменить, я в своём изменю.

Там надо много чего изменять чтобы всё работало нормально, плюс в ini-файл 0.38.2 добавлено кое-чего. Так что с каждым новым выходом Унрила, я беру программу WinMerge (http://winmerge.org/) (бесплатная) и правлю файл нового Унрила.

Alex Rider
05.12.2014, 11:39
Пак софта делать надо, безотносительно меня и моей лени Для всех.
С паком есть 2 проблемы:
1. Входящие в него продукты (Sublime Text, Unreal) обновляются, за паком надо следить.
2. У каждого свои предпочтения как по продуктам (эмуляторы, редакторы), так и по их опциям. Рекомендуемую "золотую середину" найти трудно.

с этим ини-файлом унреал не запускается, пишет, что версия не та, надо изменить версию с 38.1 на 38.2. И зачем он вообще нужен этот ини? Я к своему ини привык )) Если в нем что-то важное, то лучше скажи, что именно изменить, я в своём изменю.
Да ничего менять не надо. Это было на случай, если Unreal'ом ты не пользуешься вообще. И да, я слоупок, так и не перешел на 0.38.2 (я вообще ни строчки кода с июля не написал :( ). Пользуй свой.

Проект компилится, и это главное. Но унреал с собранным трд не поднимается
По такому output'у непонятно что случилось. Такое ощущение, что все-таки путь не находится. Попробуй в run.bat в плагине z80asm закомментировать первую строчку @echo off и запости более подробный output после этого.

Впринципе пофиг, можно в проводнике по образу два раза щелкнуть.
Надоест при частых правках.

Про ран в тр-досе я в курсе. Если после рана кодового блока не планируется возврат к бейсику (а у меня именно так), то можно наверно и ран применять, экономия места типа. Разве нет? )
Можно если нет возврата в BASIC и нет повторного входа в TR-DOS из кода (сохранение/загрузка состояния, например). Ибо код после RUN "xxx"CODE исполняется без выхода из TR-DOS, и при повторном входе могут быть всякие сюрпризы.

ZX_NOVOSIB
05.12.2014, 16:07
С паком есть 2 проблемы:
1. Входящие в него продукты (Sublime Text, Unreal) обновляются, за паком надо следить.
2. У каждого свои предпочтения как по продуктам (эмуляторы, редакторы), так и по их опциям. Рекомендуемую "золотую середину" найти трудно.Можно следить, а можно и не следить, если пак рабочий будет, то этого уже достаточно, а то что он окажется составлен не из самых свежих версий - это ернуда. Другими словами: лучше уж не свежий пак, чем полное его отсутствие. )) Кому надо - сам обновит нужный элемент.

Предпочтения действительно у каждого свои. Но пак должен быть предназначен в первую очередь для начинающих, и для вспоминающих, а эти две категории буду рады любому варианту, лишь бы он был удобней чем GENS и работал сразу, безо всяких танцев с бубном. А те, у кого разные предпочтения, те люди уже прошареные, они и так во всём разбираются, им никаких паков вообще не надо.


Да ничего менять не надо. Это было на случай, если Unreal'ом ты не пользуешься вообще. И да, я слоупок, так и не перешел на 0.38.2 (я вообще ни строчки кода с июля не написал :( ). Пользуй свой.38.1 вроде трд косячные сохраняет.. больше 640 кб. А 38.2 вроде нормально.


По такому output'у непонятно что случилось. Такое ощущение, что все-таки путь не находится. Попробуй в run.bat в плагине z80asm закомментировать первую строчку @echo off и запости более подробный output после этого.Закомментил эту первую строчку, но output остался таким же коротким )) Экспериментируя, сохранил проект с расширением trd (вместо подобающего а80). Нажимаю RUN и вот тут Sublime Text очень даже отлично запускает унреал, а значит путь к нему он прекрасно находит. Другое дело, что унреал ругается, что ему вместо трд подсунули какую-то гадость, но спрашивает, продолжить ли эмуляцию.

Rindex
05.12.2014, 17:00
38.1 вроде трд косячные сохраняет.. больше 640 кб. А 38.2 вроде нормально.

Вот держи. У меня так настроено - http://sderni.ru/252854

Alex Rider
05.12.2014, 18:53
Закомментил эту первую строчку, но output остался таким же коротким )) Экспериментируя, сохранил проект с расширением trd (вместо подобающего а80). Нажимаю RUN и вот тут Sublime Text очень даже отлично запускает унреал, а значит путь к нему он прекрасно находит. Другое дело, что унреал ругается, что ему вместо трд подсунули какую-то гадость, но спрашивает, продолжить ли эмуляцию.
Прикольненько... У тебя Sublime вызывает Run.bat с одинарными кавычками для аргументов ('.../run.bat', 'opros2.a80', ''), а у меня с двойными. А run.bat при попытке получить имя файла a80 получает его не как opros2, а как 'opros2, соответственно, все валится. Почему так, пока не знаю. Покопаю позже.

Alex Rider
05.12.2014, 23:11
Покопаю позже.
Сегодня ниасилил.