1. Заголовок или название темы должно быть информативным ! 2. Все тексты фрагментов программ должны помещаться в теги [code] ... [/code] или [code=pas] ... [/code]. 3. Прежде чем задавать вопрос, см. "FAQ" и используйте ПОИСК ! 4.НЕ используйте форум для личного общения! 5. Самое главное - это раздел теоретический, т.е. никаких задач и программ (за исключением небольших фрагментов) - для этого есть отдельный раздел!
я хотел бы знать как в цикле фиксировать нажатие кнопки не останавливая при этом цикл ... т.е. например в теле цикла х имзеняется по форуле x:=x+1; ... нажал что нада а цикл всё идёт и ёдет ... но уже x:=x+2; ... вот так вот ...
Вот каркас (так как написание процедур обработки прерываний - достаточно опасная вещь, я не буду писать ничего кроме "каркаса" программы с коментариями ):
uses Dos, Crt; var Int09Save : Pointer; {$F+} procedure KbdHandler; interrupt; begin {Если пришли сюда, то была нажата клавиша. Здесь определяется нажатие на клавишу и ее скэн-код записывается в какую-либо глобальную переменную, после чего вызывается "настоящее" прерывание 9Н} end; {$F-} begin GetIntVec($09,Int09Save); { Запоминание настоящего вектора прерывания } SetIntVec($09,Addr(KbdHandler)); { и подмена его своей процедурой обработки}
{здесь расположен тот цикл, в течении которого нужно отслеживать нажатия на клавиши}
SetIntVec($09,Int09Save); { Возврат настоящего вектора прерывания } end.
P.S. А для чего это нужно, более конкретно можно описать? Возможно есть другой, более безопасный способ...
procedure KbdHandler; interrupt; begin {Если пришли сюда, то была нажата клавиша. Здесь определяется нажатие на клавишу и ее скэн-код записывается в какую-либо глобальную переменную, после чего вызывается "настоящее" прерывание 9Н} end;
Дополню: 1) скэн-код и флаг нажатия-отпускания можно получить из порта $60 (как значение элемента псевдомассива Port, e. g. x := Port[$60]). Младшие 7 бит полученного значения будут разны скэн-коду, а старший 7-й бит равен 0, если клавиша нажата и 1 - если отпущена; 2) вызывать "настоящий" обработчик Int 9 не всегда имеет смысл - например, в том случае, когда мы сами хотим организовать буферизацию событий клавиатуры (в этом случае необходимо перед выходом из обработчика сбрасывать контроллер прерываний: Port[$20] := $20).
Цитата
P.S. А для чего это нужно, более конкретно можно описать? Возможно есть другой, более безопасный способ...
Да, это важно. Во многих случаях можно обойтись без подобных "махинаций" c IRQ1, используя, например, службы BIOS.
а зачем такие трудности? Может быть тело цикла выполняется за довольно малое время, и достаточно обойтись
If Keypressed then begin c:=ord(readkey); {выполняем что нужно} end;
смысл думаю ясен... И цикл не останавливается и никаких TSR и никаких обработчиков. Но это при условии, что тело цикла выполняется достаточно быстро... (то есть если он выполняется за час, то это не приемлимо )
--------------------
Помогая друг другу, мы справимся с любыми трудностями! "Не опускать крылья!" (С)
Зачастую этот вопрос возникает, когда важно знать не то, нажималась ли какая-то клавиша перед выполнением очередной итерации цикла, а то, нажата ли она именно сейчас, или нет. Например, это важно в играх. Кроме того, через Keypressed нельзя отследить Ctrl, Shift, Alt etc. Я раньше все хотел написать какую-нить игрушку на ТР, и всякий раз упирался в клавиатуру. В конце концов я таки написал свой корявый обработчик Int09... после чего уперся в другие проблемы. <_< ...и они меня обломали.
народ я то хотел змейку намутить ... типа не прерывая цикл менять напрвление движения ... я смотрю так это заморочки большие мож как то с другой стороны подойти к этому делу ?
if keypressed then begin key := readkey; if (key = #0) then key := readkey; end;
А потом в зависимости от key изменяй координаты ...
--------------------
Двадцать пятый час в сутках может появиться всего лишь из-за небольшой ошибки в программе. Чтобы не воспользоваться сумасшедшими возможностями, нужно быть идиотом.
так как написание процедур обработки прерываний - достаточно опасная вещ
А почему опасная ? :p2:
--------------------
Хочу в репу !
Cмотри,а то ведь получишь! Админ. Не получит - его фиг догонишь! Админ №2. P.S Вы еще третьего админа притащите сюда :D ваш аффтар :D Звали? :D (админ № не помню какой) ха больше нифига не напишете афтар Уверен? (Moderator) А еще можно ? (супмодер) Хватит его мучать ! Избили уж... (админ) Не хватит. я тоже напишу (тоже Админ)
suriv Малейшая ошибка - и вектор прерывания "засылается в космос" - то есть неведомо куда, результат может быть самым плачевным, вплоть до потери информации на харде...
program MuXaZ_zmeika; uses crt,graph; label 1,2,3,4,5; var rx1,rx2,ry2,ry1,i,i1,i2,i3,i4,i5,i6,i7,gd,gm:integer; st,st1,st2,st3:string; sx:array[0..50] of integer; sy:array[0..50] of integer; key:char; begin rx1:=0; rx2:=640; ry1:=0; ry2:=480; writeln('BBeDuTe DJIuHHy 3Meu (1-50)'); readln(i7); writeln('BBeDuTe DJIuHHy CKopPocTb 3Meu (1-32)'); readln(i6); Gd:=Detect; InitGraph(Gd, Gm, 'e:\bp\bgi'); If GraphResult <> grOk Then Halt(1); i1:=20; i2:=20; for i:= 1 to 20 do begin sx[i]:=1; sy[i]:=1; end;
i:=0; while i<240 do begin if keypressed then begin key:=readkey; if key=#52 then i3:=1; if key=#50 then i3:=2; if key=#54 then i3:=3; if key=#56 then i3:=4; if (key=#43) or (key=#27) then i3:=9 end;
if i1>rx2 then i1:=rx1; if i2>ry2 then i2:=ry1; if i1<rx1 then i1:=rx2; if i2<ry1 then i2:=ry2;
if i3=1 then i1:=i1-5; if i3=2 then i2:=i2+5; if i3=3 then i1:=i1+5; if i3=4 then i2:=i2-5; if i3=9 then goto 1; delay(trunc(32000/i6)); setcolor(green);
line(i1,i2,i1+5,i2+5); line(i1+5,i2,i1,i2+5); i4:=i7+1; while i4>1 do begin sx[i4]:=sx[i4-1]; sy[i4]:=sy[i4-1]; i4:=i4-1; end; sx[1]:=i1; sy[1]:=i2; setcolor(black); line(sx[i7+1],sy[i7+1],sx[i7+1]+5,sy[i7+1]+5); line(sx[i7+1]+5,sy[i7+1],sx[i7+1],sy[i7+1]+5); setcolor(white); end;
1:outtextxy(20,460,'THE END'); readkey; end.
вот я собССно чё намутил кому интересно ... можно выбирать скорость длинну и граници поля ...
if keypressed then begin key := readkey; if (key = #0) then key := readkey; end;
Расширенные коды BIOS всё же стоит обрабатывать отдельно от ASCII, в противном случае мы, например, получим дополнительное управление клавишами H, K, M, P (что, впрочем, можно рассматривать как "undocumented feature")
if KeyPressed then case ReadKey of { обработка ASCII } ... #0: case ReadKey of { обработка расширенных кодов } ... end; end;
вот в догонку кому еще интересно ... всё выглядит как нормальная змейка толко пака без собирания фруктов и терь она сама в себя врезается и транспортикуется при врезании в стену ... короче почти полноценная змея!
program MuXaZ_zmeika; uses crt,graph; label 1,2,3,4,5; var dl,dl1,start,xx,sp,yy,rx1,rx2,ry2,ry1,i,i1,i2,i3,i4,i5,i6,i7,gd,gm:integer; st,st1,st2,st3:string; sx:array[0..880] of integer; sy:array[0..880] of integer;
i:=7; setcolor(8); while i<=318 do begin i:=i+12; line(i,20,i,234); end; i:=7; setcolor(8); while i<=233 do begin i:=i+12; line(20,i,318,i); end;
i1:=20; i2:=20; for i:= 1 to 50 do begin sx[i]:=1; sy[i]:=1; end; randomize; xx:=trunc((1590-random(1490))/5); yy:=trunc((1170-random(1070))/5); bar(xx,yy,xx+5,yy+5); {knopki} i:=0; i3:=2; readkey; while i<240 do begin if keypressed then begin key:=readkey; if key=#52 then i3:=1; if key=#50 then i3:=2; if key=#54 then begin i3:=3; end; if key=#56 then begin i3:=4; end; if (key=#43) or (key=#27) then i3:=9; if key=#42 then i7:=i7+1; if key=#47 then i6:=i6+1; if key=#45 then i6:=i6-1; end;
{dvigenie} if i3=1 then i1:=i1-12; if i3=2 then i2:=i2+12; if i3=3 then i1:=i1+12; if i3=4 then i2:=i2-12; if i3=9 then goto 1;
{proverka udara}
for i:= 1 to i7 do begin if (i1=sx[i]) and (i2=sy[i]) then goto 1; end;
{zargranica} if i1+10>rx2 then i1:=rx1; if i2+10>ry2 then i2:=ry1; if i1<rx1 then i1:=rx2-10; if i2<ry1 then i2:=ry2-10;
{skorost`} if i6<>dl then begin str(sp,st1); setcolor(black); outtextxy(300,255,st1); str(i6,st1); setcolor(11); outtextxy(300,255,st1); sp:=i6; end; if i6>0 then delay(trunc(52000/i6)) else begin i6:=1; delay(trunc(52000/i6)); end; setcolor(green); {zmeya} line(i1,i2,i1+10,i2); line(i1+10,i2,i1+10,i2+10); line(i1+10,i2+10,i1,i2+10); line(i1,i2+10,i1,i2); {dlinna} if i7<>dl then begin str(dl,st1); setcolor(black); outtextxy(180,255,st1); str(i7,st1); setcolor(11); outtextxy(180,255,st1); dl:=i7; end;
{massiv zmei} i4:=i7+1; while i4>1 do begin sx[i4]:=sx[i4-1]; sy[i4]:=sy[i4-1]; i4:=i4-1; end; sx[1]:=i1; sy[1]:=i2; setcolor(black); {zatiranie zmei} line(sx[i7+1],sy[i7+1],sx[i7+1]+10,sy[i7+1]); line(sx[i7+1]+10,sy[i7+1],sx[i7+1]+10,sy[i7+1]+10); line(sx[i7+1]+10,sy[i7+1]+10,sx[i7+1],sy[i7+1]+10); line(sx[i7+1],sy[i7+1]+10,sx[i7+1],sy[i7+1]); setcolor(green);