blob: 97f0cf1396d40faee5941b529261e207c76e6123 [file] [log] [blame]
/* Goom Project
* Copyright (C) <2003> iOS-Software
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "drawmethods.h"
#define DRAWMETHOD_PLUS(_out,_backbuf,_col) \
{\
int tra=0,i=0;\
unsigned char *bra = (unsigned char*)&(_backbuf);\
unsigned char *dra = (unsigned char*)&(_out);\
unsigned char *cra = (unsigned char*)&(_col);\
for (;i<4;i++) {\
tra = *cra;\
tra += *bra;\
if (tra>255) tra=255;\
*dra = tra;\
++dra;++cra;++bra;\
}\
}
#define DRAWMETHOD DRAWMETHOD_PLUS(*p,*p,col)
void
draw_line (Pixel * data, int x1, int y1, int x2, int y2, int col, int screenx,
int screeny)
{
int x, y, dx, dy, yy, xx;
Pixel *p;
if ((y1 < 0) || (y2 < 0) || (x1 < 0) || (x2 < 0) || (y1 >= screeny)
|| (y2 >= screeny) || (x1 >= screenx) || (x2 >= screenx))
return;
/* clip to top edge
if ((y1 < 0) && (y2 < 0))
return;
if (y1 < 0) {
x1 += (y1 * (x1 - x2)) / (y2 - y1);
y1 = 0;
}
if (y2 < 0) {
x2 += (y2 * (x1 - x2)) / (y2 - y1);
y2 = 0;
}
clip to bottom edge
if ((y1 >= screeny) && (y2 >= screeny))
return;
if (y1 >= screeny) {
x1 -= ((screeny - y1) * (x1 - x2)) / (y2 - y1);
y1 = screeny - 1;
}
if (y2 >= screeny) {
x2 -= ((screeny - y2) * (x1 - x2)) / (y2 - y1);
y2 = screeny - 1;
}
clip to left edge
if ((x1 < 0) && (x2 < 0))
return;
if (x1 < 0) {
y1 += (x1 * (y1 - y2)) / (x2 - x1);
x1 = 0;
}
if (x2 < 0) {
y2 += (x2 * (y1 - y2)) / (x2 - x1);
x2 = 0;
}
clip to right edge
if ((x1 >= screenx) && (x2 >= screenx))
return;
if (x1 >= screenx) {
y1 -= ((screenx - x1) * (y1 - y2)) / (x2 - x1);
x1 = screenx - 1;
}
if (x2 >= screenx) {
y2 -= ((screenx - x2) * (y1 - y2)) / (x2 - x1);
x2 = screenx - 1;
}
*/
dx = x2 - x1;
dy = y2 - y1;
if (x1 > x2) {
int tmp;
tmp = x1;
x1 = x2;
x2 = tmp;
tmp = y1;
y1 = y2;
y2 = tmp;
dx = x2 - x1;
dy = y2 - y1;
}
/* vertical line */
if (dx == 0) {
if (y1 < y2) {
p = &(data[(screenx * y1) + x1]);
for (y = y1; y <= y2; y++) {
DRAWMETHOD;
p += screenx;
}
} else {
p = &(data[(screenx * y2) + x1]);
for (y = y2; y <= y1; y++) {
DRAWMETHOD;
p += screenx;
}
}
return;
}
/* horizontal line */
if (dy == 0) {
if (x1 < x2) {
p = &(data[(screenx * y1) + x1]);
for (x = x1; x <= x2; x++) {
DRAWMETHOD;
p++;
}
return;
} else {
p = &(data[(screenx * y1) + x2]);
for (x = x2; x <= x1; x++) {
DRAWMETHOD;
p++;
}
return;
}
}
/* 1 */
/* \ */
/* \ */
/* 2 */
if (y2 > y1) {
/* steep */
if (dy > dx) {
dx = ((dx << 16) / dy);
x = x1 << 16;
for (y = y1; y <= y2; y++) {
xx = x >> 16;
p = &(data[(screenx * y) + xx]);
DRAWMETHOD;
if (xx < (screenx - 1)) {
p++;
/* DRAWMETHOD; */
}
x += dx;
}
return;
}
/* shallow */
else {
dy = ((dy << 16) / dx);
y = y1 << 16;
for (x = x1; x <= x2; x++) {
yy = y >> 16;
p = &(data[(screenx * yy) + x]);
DRAWMETHOD;
if (yy < (screeny - 1)) {
p += screeny;
/* DRAWMETHOD; */
}
y += dy;
}
}
}
/* 2 */
/* / */
/* / */
/* 1 */
else {
/* steep */
if (-dy > dx) {
dx = ((dx << 16) / -dy);
x = (x1 + 1) << 16;
for (y = y1; y >= y2; y--) {
xx = x >> 16;
p = &(data[(screenx * y) + xx]);
DRAWMETHOD;
if (xx < (screenx - 1)) {
p--;
/* DRAWMETHOD; */
}
x += dx;
}
return;
}
/* shallow */
else {
dy = ((dy << 16) / dx);
y = y1 << 16;
for (x = x1; x <= x2; x++) {
yy = y >> 16;
p = &(data[(screenx * yy) + x]);
DRAWMETHOD;
if (yy < (screeny - 1)) {
p += screeny;
/* DRAWMETHOD; */
}
y += dy;
}
return;
}
}
}