FreeBASIC  0.91.0
io_scroll.c
Go to the documentation of this file.
1 /* console scrolling for when VIEW is used */
2 
3 #include "../fb.h"
4 #include "fb_private_console.h"
5 #include <dpmi.h>
6 #include <go32.h>
7 
8 static void hFillRect( int x1, int y1, int x2, int y2 )
9 {
10  int cols, rows;
11  fb_ConsoleGetSize( &cols, &rows );
12 
13  int chars = (x2 - x1 + 1) * (y2 - y1 + 1);
14 
15  unsigned long physAddr = fb_hGetPageAddr( __fb_con.active, cols, rows );
16  if( physAddr == 0 )
17  {
18  /* change the cursor pos (faster than using LOCATE) */
19  unsigned short oldPos = fb_hSetCursorPos( x1, y1 );
20 
21  __dpmi_regs regs;
22  regs.x.ax = 0x0920;
23  regs.h.bh = __fb_con.active;
24  regs.h.bl = fb_ConsoleGetColorAtt();
25  regs.x.cx = chars;
26  __dpmi_int(0x10, &regs);
27 
28  /* restore old pos */
29  fb_hSetCursorPos( oldPos, -1 );
30  }
31  else
32  {
33  unsigned short attr = fb_ConsoleGetColorAtt() << 8;
34  if( (x2 - x1 + 1) == cols )
35  {
36  unsigned short *buffer = alloca( chars * sizeof( short ) );
37  int i;
38  for( i = 0, buffer += chars; i < chars; ++i )
39  *--buffer = attr | 0x20;
40 
41  _movedataw( _my_ds(), (int)buffer,
42  _dos_ds, physAddr + (cols << 1) * y1,
43  chars );
44  }
45  else
46  {
47  chars = x2 - x1 + 1;
48  unsigned short *buffer = alloca( chars * sizeof( short ) );
49  int i;
50  for( i = 0, buffer += chars; i < chars; ++i )
51  *--buffer = attr | 0x20;
52 
53  for( i = y1; i < y2; i++ )
54  _movedataw( _my_ds(), (int)buffer,
55  _dos_ds, physAddr + (cols << 1) * i + (x1 << 1),
56  chars );
57  }
58  }
59 }
60 
61 static void hMoveRect( int x1, int y1, int x2, int y2, int nrows )
62 {
63  int cols, rows;
64  fb_ConsoleGetSize( &cols, &rows );
65 
66  int chars = (x2 - x1 + 1) * (y2 - y1 + 1 - nrows);
67 
68  unsigned long physAddr = fb_hGetPageAddr( __fb_con.active, cols, rows );
69  if( physAddr == 0 )
70  {
71  /* !!!WRITEME!!!*/
72  }
73  else
74  {
75  if( (x2 - x1 + 1) == cols )
76  {
77  _movedataw( _dos_ds, physAddr + (cols << 1) * (y1+nrows),
78  _dos_ds, physAddr + (cols << 1) * y1,
79  chars );
80  }
81  else
82  {
83  chars = x2 - x1 + 1;
84  int i;
85  for( i = y1; i < y2 - nrows; i++ )
86  _movedataw( _dos_ds, physAddr + (cols << 1) * (i+1) + (x1 << 1),
87  _dos_ds, physAddr + (cols << 1) * i + (x1 << 1),
88  chars );
89  }
90  }
91 
92 }
93 
94 void fb_ConsoleScroll_BIOS( int x1, int y1, int x2, int y2, int nrows )
95 {
96  __dpmi_regs regs;
97 
98  /* stupid BIOS can't scroll a specific page */
100  {
101  if( nrows == 0 )
102  {
103  hFillRect( x1, y1, x2, y2 );
104  }
105  else
106  {
107  hMoveRect( x1, y1, x2, y2, nrows );
108  hFillRect( x1, y2-(nrows-1), x2, y2 );
109  }
110 
111  return;
112  }
113 
114  regs.h.bl = 0;
115  regs.h.bh = (unsigned char) fb_ConsoleGetColorAtt();
116  regs.h.cl = (unsigned char) x1;
117  regs.h.ch = (unsigned char) y1;
118  regs.h.dl = (unsigned char) x2;
119  regs.h.dh = (unsigned char) y2;
120 
121  if( nrows >= 0 ) {
122  regs.x.ax = (unsigned short) (0x0600 + nrows);
123  } else {
124  regs.x.ax = (unsigned short) (0x0700 + -nrows);
125  }
126  __dpmi_int(0x10, &regs);
127 }
128 
129 void fb_ConsoleScrollEx( int x1, int y1, int x2, int y2, int nrows )
130 {
131  int rows;
132 
133  if( nrows == 0 )
134  return;
135 
136  fb_ConsoleGetSize( NULL, &rows );
137 
138  if( nrows <= -rows || nrows >= rows )
139  nrows = 0;
140 
141  fb_ConsoleScroll_BIOS( x1-1, y1-1, x2-1, y2-1, nrows );
142 
143 #if 0
144  if( nrows > 0 ) {
145  fb_ConsoleLocate_BIOS( y2 - 1 - nrows, x1, -1 );
146  } else if( nrows < 0 ) {
147  fb_ConsoleLocate_BIOS( y1 - 1 - nrows, x1, -1 );
148  } else {
149  fb_ConsoleLocate_BIOS( y1 - 1, x1 - 1, -1 );
150  }
151 #endif
152 }
153 
154 void fb_ConsoleScroll( int nrows )
155 {
156  int toprow, botrow;
157  int cols;
158 
159  if( nrows == 0 )
160  return;
161 
162  fb_ConsoleGetSize( &cols, NULL );
163  fb_ConsoleGetView( &toprow, &botrow );
164 
165  return fb_ConsoleScrollEx( 1, toprow, cols, botrow, nrows );
166 }