139 lines
4.4 KiB
C++
139 lines
4.4 KiB
C++
/* ScummVM - Graphic Adventure Engine
|
|
*
|
|
* ScummVM is the legal property of its developers, whose names
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
* file distributed with this source distribution.
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
*/
|
|
|
|
#include "m4/graphics/gr_line.h"
|
|
#include "m4/vars.h"
|
|
|
|
namespace M4 {
|
|
|
|
void gr_vline_xor(Buffer *buf, int32 x, int32 y1, int32 y2) {
|
|
if (y1 > y2) {
|
|
SWAP(y1, y2);
|
|
}
|
|
|
|
if ((x > buf->w) || (y1 > buf->h))
|
|
return;
|
|
|
|
if (y2 > buf->h)
|
|
y2 = buf->h; // Don't draw past bottom
|
|
|
|
byte *start = buf->data + x;
|
|
|
|
for (int32 i = y1; i < y2; i++, start += buf->stride)
|
|
*start ^= 0xff;
|
|
}
|
|
|
|
void gr_hline_xor(Buffer *buf, int32 x1, int32 x2, int32 y) {
|
|
if (x1 > x2) {
|
|
SWAP(x1, x2);
|
|
}
|
|
|
|
if ((y > buf->h) || (x1 > buf->w))
|
|
return;
|
|
|
|
byte *start = gr_buffer_pointer(buf, x1, y);
|
|
|
|
for (int32 i = x1; i < x2; i++, start++)
|
|
*start ^= 0xff;
|
|
}
|
|
|
|
void gr_vline(Buffer *buf, int32 x, int32 y1, int32 y2) {
|
|
if (y1 > y2) {
|
|
SWAP(y1, y2);
|
|
}
|
|
|
|
if ((x > buf->w) || (y1 > buf->h))
|
|
return;
|
|
|
|
y2++;
|
|
if (y2 > buf->h)
|
|
y2 = buf->h; // don't draw past bottom
|
|
|
|
byte *start = gr_buffer_pointer(buf, x, y1);
|
|
|
|
for (int32 i = y1; i < y2; i++, start += buf->stride)
|
|
*start = _G(color);
|
|
}
|
|
|
|
void gr_hline(Buffer *buf, int32 x1, int32 x2, int32 y) {
|
|
if (x1 > x2) {
|
|
SWAP(x1, x2);
|
|
}
|
|
|
|
if ((y > buf->h) || (x1 > buf->w))
|
|
return;
|
|
|
|
byte *start = gr_buffer_pointer(buf, x1, y);
|
|
|
|
x2++;
|
|
if (x2 > buf->w)
|
|
x2 = buf->w;
|
|
|
|
for (int32 i = x1; i < x2; i++, start++)
|
|
*start = _G(color);
|
|
}
|
|
|
|
void gr_line(int32 x1, int32 y1, int32 x2, int32 y2, int32 color, Buffer *screen) {
|
|
byte *myData = (byte *)screen->data;
|
|
int32 y_unit, x_unit; // Variables for amount of change in x and y
|
|
|
|
int32 offset = y1 * screen->stride + x1; // Calculate offset into video RAM
|
|
|
|
int32 ydiff = y2 - y1; // Calculate difference between y coordinates
|
|
if (ydiff < 0) { // If the line moves in the negative direction
|
|
ydiff = -ydiff; // ...get absolute value of difference
|
|
y_unit = -screen->stride; // ...and set negative unit in y dimension
|
|
} else y_unit = screen->stride; // Else set positive unit in y dimension
|
|
|
|
int32 xdiff = x2 - x1; // Calculate difference between x coordinates
|
|
if (xdiff < 0) { // If the line moves in the negative direction
|
|
xdiff = -xdiff; // ...get absolute value of difference
|
|
x_unit = -1; // ...and set negative unit in x dimension
|
|
} else x_unit = 1; // Else set positive unit in y dimension
|
|
|
|
int32 error_term = 0; // Initialize error term
|
|
if (xdiff > ydiff) { // If difference is bigger in x dimension
|
|
const int32 length = xdiff + 1; // ...prepare to count off in x direction
|
|
for (int32 i = 0; i < length; i++) { // Loop through points in x direction
|
|
myData[offset] = (char)color; // Set the next pixel in the line to COLOR
|
|
offset += x_unit; // Move offset to next pixel in x direction
|
|
error_term += ydiff; // Check to see if move required in y direction
|
|
if (error_term > xdiff) { // If so...
|
|
error_term -= xdiff; // ...reset error term
|
|
offset += y_unit; // ...and move offset to next pixel in y dir.
|
|
}
|
|
}
|
|
} else { // If difference is bigger in y dimension
|
|
const int32 length = ydiff + 1; // ...prepare to count off in y direction
|
|
for (int32 i = 0; i < length; i++) { // Loop through points in y direction
|
|
myData[offset] = (char)color; // Set the next pixel in the line to COLOR
|
|
offset += y_unit; // Move offset to next pixel in y direction
|
|
error_term += xdiff; // Check to see if move required in x direction
|
|
if (error_term > 0) { // If so...
|
|
error_term -= ydiff; // ...reset error term
|
|
offset += x_unit; // ...and move offset to next pixel in x dir.
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
} // namespace M4
|