IPB
ЛогинПароль:

> Прочтите прежде чем задавать вопрос!

1. Заголовок темы должен быть информативным. В противном случае тема удаляется ...
2. Все тексты программ должны помещаться в теги [code=pas] ... [/code], либо быть опубликованы на нашем PasteBin в режиме вечного хранения.
3. Прежде чем задавать вопрос, см. "FAQ", если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно такую задачу уже решали!
4. Не предлагайте свои решения на других языках, кроме Паскаля (исключение - только с согласия модератора).
5. НЕ используйте форум для личного общения, все что не относится к обсуждению темы - на PM!
6. Одна тема - один вопрос (задача)
7. Проверяйте программы перед тем, как разместить их на форуме!!!
8. Спрашивайте и отвечайте четко и по существу!!!

 
 Ответить  Открыть новую тему 
> Управление монитором и мышью
сообщение
Сообщение #1





Группа: Пользователи
Сообщений: 4
Пол: Мужской
Реальное имя: Nick

Репутация: -  0  +


По нажатию на левую кнопку мыши все символы переворачиваются вверх ногами. по наведению мыши на символ "Ф", он меняется на "Р".

Буду очень признателен, если хотя бы намекнете, как делать. Устал висеть в гугле уже третие сутки
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #2


Я.
****

Группа: Пользователи
Сообщений: 809
Пол: Мужской
Реальное имя: Саша

Репутация: -  11  +


Либо маразм, либо неполное задание.
Язык хотя бы какой?

Сообщение отредактировано: sheka -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #3





Группа: Пользователи
Сообщений: 4
Пол: Мужской
Реальное имя: Nick

Репутация: -  0  +


Паскаль

Ну и со ставками ассемблера

И может под "переворачиваются вверх ногами" имеется ввиду поворот всего экрана

Сообщение отредактировано: RNic7 -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #4


Гуру
*****

Группа: Пользователи
Сообщений: 1 013
Пол: Мужской
Ада: Разработчик
Embarcadero Delphi: Сторонник
Free Pascal: Разработчик

Репутация: -  627  +


Цитата
И может под "переворачиваются вверх ногами" имеется ввиду поворот всего экрана
Скорее речь о "перепрограммировании знакогенератора", то есть, о задании других матриц, соответствующих каждому символу. Дело в том, что каждый символ представляется в виде массива байт, верхний ряд развертки - это первый байт, второй ряд - это второй байт и так далее. Фактически, если тебе надо перевернуть символы "вверх ногами" - достаточно просто поменять порядок байт в этой таблице на обратный, тогда развертка пойдет "вверх ногами" (то, что раньше было первой строкой - станет последней и наоборот).

Итого, Гугл по сочетанию "программирование знакогенератора" выдает достаточно информации о том, как это делается (тем более на ассемблере). Если не ошибаюсь, то в поиске по этому форуму тоже можно найти кое-что (или я выкладывал это на другой форум, не помню точно, но поискать всегда нужно).
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #5





Группа: Пользователи
Сообщений: 4
Пол: Мужской
Реальное имя: Nick

Репутация: -  0  +


Вот нашел что-то. Только я в ассемблере ноль. Как это в программу на паскале влепить?

Код
.286
  CODE          SEGMENT
                ASSUME     CS:CODE,ES:CODE

prmaus proc far; процедура обработки событий - при нажатии правой кнопки в нужной области символ изменяется на пробел
   ;cx - координата по горизонтали
   ;dx - координата по вертикали    
cli;запрещаем обработку прерываний
push ds; сохраняем регистры
push es
pusha

MOV  AX,0B000H  ;указываем на ячейку, где начинается видеопамять
MOV  ES,AX      ;
mov  di,0       ; es:di - начало видеостраницы
shr  cx,3       ; делим на 8, поскольку координаты в пикселях
shr  dx,3       ; делим на 8
mov ax,dx; заносим в di 80*2*dx+2*cx
mov ah,0
imul    ax,(80*2)
add ax,cx
add ax,cx
mov di,ax
MOV  AL,32      ;символ пробела
MOV  AH,7       ;нормальные атрибуты
movsw   ; в месте es:di ставим пробел
sti;разрешаем обработку прерываний

prmaus endp


xor ax,ax  ;инициализируем текстовый режим отображения
mov     ax, 3
int         10h

xor     ax, ax ; инициализация мышки
int     33h

mov ax,1   ; отображение курсора
int 33h


mov ax,0ch  ;обработка события - нажатие правой кнопки мышки
mov cx, 1000b  
push es
push cs
pop es
lea dx,prmaus;при нажатии - идём в процедуру
int 33h
pop es

@10:
mov         ah, 01h; вводим символы с клавиатуры с эхом в видеопамять
int     21h    ;
cmp al,' '         ; до появления символа пробела
jne     @10

xor         cx,cx      ;cx=0
mov     ax,0ch  
int     33h    ;"останавливаем" мышку
                

mov ax,4c00h;завершаем работу
int 21h
CODE ends
end
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #6


Гуру
*****

Группа: Пользователи
Сообщений: 1 013
Пол: Мужской
Ада: Разработчик
Embarcadero Delphi: Сторонник
Free Pascal: Разработчик

Репутация: -  627  +


Цитата
Вот нашел что-то.
Это "что-то" к заданию твоему не имеет никакого отношения. smile.gif

Вот пример работы с мышой из Паскаля: по нажатию на левую кнопку символ под указателем мыши меняется на пробел. проверял под DosBox-ом (компилятор - Турбо Паскаль 7.0). Для выхода - просто нажать Esc.

uses Crt;

Function msInit : boolean;
var status : Word;
begin
asm
mov ax, $00
int $33
mov status, ax
end;
msInit := (status = $FFFF);
end;

procedure msShow; assembler;
asm
mov ax, $01
int $33
end;
procedure msHide; assembler;
asm
mov ax, $02
int $33
end;

function msBtnPressed (var X, Y : Word) : Byte;
var
btn : Byte;
pX, pY : Word;
begin
asm
mov ax, $03
int $33
mov btn, bl
mov pX, cx
mov pY, dx
end;
X := pX; Y := pY;
msBtnPressed := btn
end;

procedure CallProc (X, Y : Word);
type
vmRec =
record
Ch : Char;
Attr : Byte;
end;
var
vm : array[0 .. 80 * 25 - 1] of vmRec
absolute $B800:$0000;
begin
X := X div 8; Y := Y div 8;
vm[80 * Y + X].Ch := ' ';
end;

var
X, Y : Word;
Finish : Boolean;
begin
if not msInit then Halt(0);

msShow;
Finish := False;
repeat

if msBtnPressed (X, Y) = 1 then { левая кнопка мыши }
begin
msHide;
CallProc(X, Y);
msShow;
end;

if KeyPressed then
begin
Finish := (ReadKey = #27);
while KeyPressed do ReadKey;
end;
until Finish;
msHide;
end.
Также в FAQ-е есть статья, там написано что и как.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #7





Группа: Пользователи
Сообщений: 4
Пол: Мужской
Реальное имя: Nick

Репутация: -  0  +


Цитата(IUnknown @ 21.02.2012 12:48) *

Вот пример работы с мышой из Паскаля:

Также в FAQ-е есть статья, там написано что и как.


Спасибо. Пошел разбираться
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #8


Знаток
****

Группа: Пользователи
Сообщений: 481
Пол: Мужской
Реальное имя: Федосеев Павел

Репутация: -  9  +


Хоть эпоха DOS и ушла, но баловство со знакогенератором привлекло...
На работе на одном из стендов FreeDOS и можно было поэкспериментировать.
Приводить полностью всё не буду - подскажу лишь алгоритм в общем виде.

.................................................
CONST
{Константы для TypePtr процедуры GetCurrentFontInfo, определяющие,
на какую таблицу будет указывать Info.CharTablePtr }
fiFontTable1F = $00; {адрес из INT 1Fh}
fiFontTable43 = $01; {адрес из INT 43h}
fiFontTable8x14 = $02; {адрес фонтов 8x14}
fiFontTable8x8Lo= $03; {адрес фонтов 8x8 коды 00h..7Fh}
fiFontTable8x8Hi= $04; {адрес фонтов 8x8 коды 80h..FFh}
fiFontTable9x14 = $05; {адрес фонтов 9x14}
fiFontTable8x16 = $06; {адрес фонтов 8x16}
fiFontTable9x16 = $07; {адрес фонтов 9x16}
TYPE
{структура для процедуры GetCurrentFontInfo}
TCurrentFontInfo = RECORD
BytePerChar : Word; {число байтов на символ}
CharPerRow : Byte; {число символов в строке-1}
CharTablePtr : Pointer;{указатель на таблицу символов}
END;
{для "грубого" приведения типов}
TPtrConvert = RECORD
case Word of
0:( P : Pointer );
1:( Offs,Segm : Word );
2:( b0,b1,b2,b3 : Byte );
3:( c0,c1,c2,c3 : Char );
END;
TArrByte0 = array [0..0] of Byte;
TArrWord0 = array [0..0] of Word;
VAR
{область памяти BIOS}
{EGA/VGA} {высота матрицы, задающей изображение символа на экране}
CRT_Points : Word absolute $0040:$0085;
.................................
{получение информации о текущем шрифте}
PROCEDURE GetCurrentFontInfo(TypePtr:Byte; VAR Info : TCurrentFontInfo);
assembler;
asm
.................................{паскаль обёртка int 10h, функция 11h, подфункция 30h}
END;

{паскаль-обёртка int 10h, функция 11h, подфункция 10h}
PROCEDURE SetUserFontEnh(VAR CharTable; FirstChar:Char;
NumChar:Word; BytePerChar,NBlock :Byte);
assembler;
asm
...........................
end;

{переворачивание одного символа}
PROCEDURE GlyphReverse(VAR Glyph; {массив с описанием символа}
GlyphHight, {высота символа}
GlyphWidth : Integer);{ширина символа}
BEGIN
............................
END;

PROCEDURE FontReverse;
VAR
FontWsys, {ширина символа в точках}
FontHsys, {высота в строках/байтах}
FontRsys, {ширина в байтах }
FontSsys : Integer;{число байтов на символ }

FontInfo : TCurrentFontInfo;

i : Integer;
b : Byte;
w : Word;

NumFontTable : Byte;
BEGIN
{получение информации о текущем шрифте}
{ - из процедуры}
GetCurrentFontInfo(fiFontTable8x8Lo, FontInfo);
FontSsys:=FontInfo.BytePerChar; {число байтов на символ}
{ - из области данных BIOS}
FontHsys:=CRT_Points; {высота в строках/байтах}
{вычисление недостающих параметров текущего шрифта}
FontRsys:=FontSsys div FontHsys; {ширина в байтах }
if FontRsys=1
then FontWsys:=8
else FontWsys:=9;
{получение правильного указателя на таблицу знакогенератора}
case FontSsys of
8: NumFontTable:=fiFontTable8x8Lo; {шрифт 8x8}
14: NumFontTable:=fiFontTable8x14; {шрифт 8x14}
16: NumFontTable:=fiFontTable8x16; {шрифт 8x16}
28: NumFontTable:=fiFontTable9x14; {шрифт 9x14}
32: NumFontTable:=fiFontTable9x16; {шрифт 9x16}
end;
GetCurrentFontInfo(NumFontTable, FontInfo);
{ WriteLn('Шрифт ', FontWsys, 'x', FontHsys);}

{перевернуть все символы шрифта}
for i:=$00 to $FF do {по символам}
GlyphReverse(TArrByte0(FontInfo.CharTablePtr^)[i*FontSsys], FontHsys, FontRsys);
{задействовать изменения}
SetUserFontEnh(FontInfo.CharTablePtr^, #0, 255, FontSsys, 0);
END;


BEGIN
.........................
if условие then FontReverse;
..........................
END.


Идея следующая.
1. Получить характеристики шрифта, т.е. размеры символа (в точках) 8x8, 8x14, 8x16, 9x14, 9x16 и размер в байтах. Это берётся из переменной BIOS'а по адресу $0040:$0085 и из прерывания int 10h, функция 11h, подфункция 30h, которое возвращает характеристики текущего шрифта и указатель на одну из таблиц знакогенератора (по выбору).
2. Теперь мы знаем размеры шрифтов и можем из той же процедуры получить указатель на текущую таблицу знакогенератора.
3. Переворачиваем каждый символ в таблице - т.е. меняем местами строки (байты или слова) в описании каждого глифа. Так для 8х16: 0-я строка (байт) меняется с 15-й, 1-я - с 14-й и т.д.
4. Но пока не вызовем int 10h, функция 11h, подфункция 10h изменения не вступят в силу - значит вызываем.

Детали реализации будут проясняться по мере изучения материала. Дерзай!

Узким местом в моей реализации является приведение типов - шаманство с массивами [0..0].
Не все переменные нужны для реализации - стоит сделать ревизию.
И прошу прощения за странные имена переменных - они "пришли" из другой программки.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 





- Текстовая версия 6.05.2024 14:57
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name