59 static byte _dirty_blocks[DIRTY_BYTES_PER_LINE * MAX_SCREEN_HEIGHT / 8]; |
59 static byte _dirty_blocks[DIRTY_BYTES_PER_LINE * MAX_SCREEN_HEIGHT / 8]; |
60 |
60 |
61 void GfxScroll(int left, int top, int width, int height, int xo, int yo) |
61 void GfxScroll(int left, int top, int width, int height, int xo, int yo) |
62 { |
62 { |
63 Blitter *blitter = BlitterFactoryBase::GetCurrentBlitter(); |
63 Blitter *blitter = BlitterFactoryBase::GetCurrentBlitter(); |
64 const void *src; |
|
65 void *dst; |
|
66 |
64 |
67 if (xo == 0 && yo == 0) return; |
65 if (xo == 0 && yo == 0) return; |
68 |
66 |
69 if (_cursor.visible) UndrawMouseCursor(); |
67 if (_cursor.visible) UndrawMouseCursor(); |
70 UndrawTextMessage(); |
68 UndrawTextMessage(); |
71 |
69 |
72 if (yo > 0) { |
70 blitter->ScrollBuffer(_screen.dst_ptr, left, top, width, height, xo, yo); |
73 /*Calculate pointers */ |
|
74 dst = blitter->MoveTo(_screen.dst_ptr, left, top + height - 1); |
|
75 src = blitter->MoveTo(dst, 0, -yo); |
|
76 |
|
77 /* Decrease height and increase top */ |
|
78 top += yo; |
|
79 height -= yo; |
|
80 assert(height > 0); |
|
81 |
|
82 /* Adjust left & width */ |
|
83 if (xo >= 0) { |
|
84 dst = blitter->MoveTo(dst, xo, 0); |
|
85 left += xo; |
|
86 width -= xo; |
|
87 } else { |
|
88 src = blitter->MoveTo(src, -xo, 0); |
|
89 width += xo; |
|
90 } |
|
91 |
|
92 /* Negative height as we want to copy from bottom to top */ |
|
93 blitter->CopyFromBuffer(dst, src, width, -height, _screen.pitch); |
|
94 } else { |
|
95 /* Calculate pointers */ |
|
96 dst = blitter->MoveTo(_screen.dst_ptr, left, top); |
|
97 src = blitter->MoveTo(dst, 0, -yo); |
|
98 |
|
99 /* Decrese height. (yo is <=0). */ |
|
100 height += yo; |
|
101 assert(height > 0); |
|
102 |
|
103 /* Adjust left & width */ |
|
104 if (xo >= 0) { |
|
105 dst = blitter->MoveTo(dst, xo, 0); |
|
106 left += xo; |
|
107 width -= xo; |
|
108 } else { |
|
109 src = blitter->MoveTo(src, -xo, 0); |
|
110 width += xo; |
|
111 } |
|
112 |
|
113 /* the y-displacement may be 0 therefore we have to use memmove, |
|
114 * because source and destination may overlap */ |
|
115 blitter->MoveBuffer(dst, src, width, height); |
|
116 } |
|
117 /* This part of the screen is now dirty. */ |
71 /* This part of the screen is now dirty. */ |
118 _video_driver->make_dirty(left, top, width, height); |
72 _video_driver->make_dirty(left, top, width, height); |
119 } |
73 } |
120 |
74 |
121 |
75 |