File: gr_line.cpp

package info (click to toggle)
scummvm 2.9.1%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 450,580 kB
  • sloc: cpp: 4,299,825; asm: 28,322; python: 12,901; sh: 11,302; java: 9,289; xml: 7,895; perl: 2,639; ansic: 2,465; yacc: 1,670; javascript: 1,020; makefile: 933; lex: 578; awk: 275; objc: 82; sed: 11; php: 1
file content (151 lines) | stat: -rw-r--r-- 4,555 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/* 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) {
	byte *start;
	int32 i;

	if (y1 > y2) {
		i = y1; y1 = y2; y2 = i;
	}

	if ((x > buf->w) || (y1 > buf->h))
		return;

	if (y2 > buf->h)
		y2 = buf->h;	// Don't draw past bottom

	start = buf->data + x;

	for (i = y1; i < y2; i++, start += buf->stride)
		*start ^= 0xff;
}

void gr_hline_xor(Buffer *buf, int32 x1, int32 x2, int32 y) {
	byte *start;
	int32 i;

	if (x1 > x2) {
		i = x1; x1 = x2; x2 = i;
	}

	if ((y > buf->h) || (x1 > buf->w))
		return;

	start = gr_buffer_pointer(buf, x1, y);

	for (i = x1; i < x2; i++, start++)
		*start ^= 0xff;
}

void gr_vline(Buffer *buf, int32 x, int32 y1, int32 y2) {
	byte *start;
	int32 i;

	if (y1 > y2) {
		i = y1; y1 = y2; y2 = i;
	}

	if ((x > buf->w) || (y1 > buf->h))
		return;

	y2++;
	if (y2 > buf->h)
		y2 = buf->h;	// don't draw past bottom

	start = gr_buffer_pointer(buf, x, y1);

	for (i = y1; i < y2; i++, start += buf->stride)
		*start = _G(color);
}

void gr_hline(Buffer *buf, int32 x1, int32 x2, int32 y) {
	byte *start;
	int32 i;

	if (x1 > x2) {
		i = x1; x1 = x2; x2 = i;
	}

	if ((y > buf->h) || (x1 > buf->w))
		return;

	start = gr_buffer_pointer(buf, x1, y);

	x2++;
	if (x2 > buf->w)
		x2 = buf->w;

	for (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
		int32 length = xdiff + 1;					// ...prepare to count off in x direction
		int32 i;
		for (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
		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