From 9ba39f65b3a4ffa0d9c4ae5efbe9b2dd8dceaa58 Mon Sep 17 00:00:00 2001 From: mittorn Date: Tue, 26 Mar 2019 03:12:35 +0700 Subject: [PATCH] ref_soft: Triangle drawing --- adivtab.h | 1077 +++++++++++++++++++++++++++++++++ r_aclip.c | 323 ++++++++++ r_local.h | 34 +- r_main.c | 47 ++ r_misc.c | 16 +- r_polyse.c | 1612 ++++++++++++++++++++++++++++++++++++++++++++++++++ r_trialias.c | 229 +++++++ 7 files changed, 3327 insertions(+), 11 deletions(-) create mode 100644 adivtab.h create mode 100644 r_aclip.c create mode 100644 r_polyse.c create mode 100644 r_trialias.c diff --git a/adivtab.h b/adivtab.h new file mode 100644 index 00000000..aad0c562 --- /dev/null +++ b/adivtab.h @@ -0,0 +1,1077 @@ +/* +Copyright (C) 1997-2001 Id Software, Inc. + +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 2 +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, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +// table of quotients and remainders for [-15...16] / [-15...16] + +// numerator = -15 +{1, 0}, +{1, -1}, +{1, -2}, +{1, -3}, +{1, -4}, +{1, -5}, +{1, -6}, +{1, -7}, +{2, -1}, +{2, -3}, +{3, 0}, +{3, -3}, +{5, 0}, +{7, -1}, +{15, 0}, +{0, 0}, +{-15, 0}, +{-8, 1}, +{-5, 0}, +{-4, 1}, +{-3, 0}, +{-3, 3}, +{-3, 6}, +{-2, 1}, +{-2, 3}, +{-2, 5}, +{-2, 7}, +{-2, 9}, +{-2, 11}, +{-2, 13}, +{-1, 0}, +{-1, 1}, +// numerator = -14 +{0, -14}, +{1, 0}, +{1, -1}, +{1, -2}, +{1, -3}, +{1, -4}, +{1, -5}, +{1, -6}, +{2, 0}, +{2, -2}, +{2, -4}, +{3, -2}, +{4, -2}, +{7, 0}, +{14, 0}, +{0, 0}, +{-14, 0}, +{-7, 0}, +{-5, 1}, +{-4, 2}, +{-3, 1}, +{-3, 4}, +{-2, 0}, +{-2, 2}, +{-2, 4}, +{-2, 6}, +{-2, 8}, +{-2, 10}, +{-2, 12}, +{-1, 0}, +{-1, 1}, +{-1, 2}, +// numerator = -13 +{0, -13}, +{0, -13}, +{1, 0}, +{1, -1}, +{1, -2}, +{1, -3}, +{1, -4}, +{1, -5}, +{1, -6}, +{2, -1}, +{2, -3}, +{3, -1}, +{4, -1}, +{6, -1}, +{13, 0}, +{0, 0}, +{-13, 0}, +{-7, 1}, +{-5, 2}, +{-4, 3}, +{-3, 2}, +{-3, 5}, +{-2, 1}, +{-2, 3}, +{-2, 5}, +{-2, 7}, +{-2, 9}, +{-2, 11}, +{-1, 0}, +{-1, 1}, +{-1, 2}, +{-1, 3}, +// numerator = -12 +{0, -12}, +{0, -12}, +{0, -12}, +{1, 0}, +{1, -1}, +{1, -2}, +{1, -3}, +{1, -4}, +{1, -5}, +{2, 0}, +{2, -2}, +{3, 0}, +{4, 0}, +{6, 0}, +{12, 0}, +{0, 0}, +{-12, 0}, +{-6, 0}, +{-4, 0}, +{-3, 0}, +{-3, 3}, +{-2, 0}, +{-2, 2}, +{-2, 4}, +{-2, 6}, +{-2, 8}, +{-2, 10}, +{-1, 0}, +{-1, 1}, +{-1, 2}, +{-1, 3}, +{-1, 4}, +// numerator = -11 +{0, -11}, +{0, -11}, +{0, -11}, +{0, -11}, +{1, 0}, +{1, -1}, +{1, -2}, +{1, -3}, +{1, -4}, +{1, -5}, +{2, -1}, +{2, -3}, +{3, -2}, +{5, -1}, +{11, 0}, +{0, 0}, +{-11, 0}, +{-6, 1}, +{-4, 1}, +{-3, 1}, +{-3, 4}, +{-2, 1}, +{-2, 3}, +{-2, 5}, +{-2, 7}, +{-2, 9}, +{-1, 0}, +{-1, 1}, +{-1, 2}, +{-1, 3}, +{-1, 4}, +{-1, 5}, +// numerator = -10 +{0, -10}, +{0, -10}, +{0, -10}, +{0, -10}, +{0, -10}, +{1, 0}, +{1, -1}, +{1, -2}, +{1, -3}, +{1, -4}, +{2, 0}, +{2, -2}, +{3, -1}, +{5, 0}, +{10, 0}, +{0, 0}, +{-10, 0}, +{-5, 0}, +{-4, 2}, +{-3, 2}, +{-2, 0}, +{-2, 2}, +{-2, 4}, +{-2, 6}, +{-2, 8}, +{-1, 0}, +{-1, 1}, +{-1, 2}, +{-1, 3}, +{-1, 4}, +{-1, 5}, +{-1, 6}, +// numerator = -9 +{0, -9}, +{0, -9}, +{0, -9}, +{0, -9}, +{0, -9}, +{0, -9}, +{1, 0}, +{1, -1}, +{1, -2}, +{1, -3}, +{1, -4}, +{2, -1}, +{3, 0}, +{4, -1}, +{9, 0}, +{0, 0}, +{-9, 0}, +{-5, 1}, +{-3, 0}, +{-3, 3}, +{-2, 1}, +{-2, 3}, +{-2, 5}, +{-2, 7}, +{-1, 0}, +{-1, 1}, +{-1, 2}, +{-1, 3}, +{-1, 4}, +{-1, 5}, +{-1, 6}, +{-1, 7}, +// numerator = -8 +{0, -8}, +{0, -8}, +{0, -8}, +{0, -8}, +{0, -8}, +{0, -8}, +{0, -8}, +{1, 0}, +{1, -1}, +{1, -2}, +{1, -3}, +{2, 0}, +{2, -2}, +{4, 0}, +{8, 0}, +{0, 0}, +{-8, 0}, +{-4, 0}, +{-3, 1}, +{-2, 0}, +{-2, 2}, +{-2, 4}, +{-2, 6}, +{-1, 0}, +{-1, 1}, +{-1, 2}, +{-1, 3}, +{-1, 4}, +{-1, 5}, +{-1, 6}, +{-1, 7}, +{-1, 8}, +// numerator = -7 +{0, -7}, +{0, -7}, +{0, -7}, +{0, -7}, +{0, -7}, +{0, -7}, +{0, -7}, +{0, -7}, +{1, 0}, +{1, -1}, +{1, -2}, +{1, -3}, +{2, -1}, +{3, -1}, +{7, 0}, +{0, 0}, +{-7, 0}, +{-4, 1}, +{-3, 2}, +{-2, 1}, +{-2, 3}, +{-2, 5}, +{-1, 0}, +{-1, 1}, +{-1, 2}, +{-1, 3}, +{-1, 4}, +{-1, 5}, +{-1, 6}, +{-1, 7}, +{-1, 8}, +{-1, 9}, +// numerator = -6 +{0, -6}, +{0, -6}, +{0, -6}, +{0, -6}, +{0, -6}, +{0, -6}, +{0, -6}, +{0, -6}, +{0, -6}, +{1, 0}, +{1, -1}, +{1, -2}, +{2, 0}, +{3, 0}, +{6, 0}, +{0, 0}, +{-6, 0}, +{-3, 0}, +{-2, 0}, +{-2, 2}, +{-2, 4}, +{-1, 0}, +{-1, 1}, +{-1, 2}, +{-1, 3}, +{-1, 4}, +{-1, 5}, +{-1, 6}, +{-1, 7}, +{-1, 8}, +{-1, 9}, +{-1, 10}, +// numerator = -5 +{0, -5}, +{0, -5}, +{0, -5}, +{0, -5}, +{0, -5}, +{0, -5}, +{0, -5}, +{0, -5}, +{0, -5}, +{0, -5}, +{1, 0}, +{1, -1}, +{1, -2}, +{2, -1}, +{5, 0}, +{0, 0}, +{-5, 0}, +{-3, 1}, +{-2, 1}, +{-2, 3}, +{-1, 0}, +{-1, 1}, +{-1, 2}, +{-1, 3}, +{-1, 4}, +{-1, 5}, +{-1, 6}, +{-1, 7}, +{-1, 8}, +{-1, 9}, +{-1, 10}, +{-1, 11}, +// numerator = -4 +{0, -4}, +{0, -4}, +{0, -4}, +{0, -4}, +{0, -4}, +{0, -4}, +{0, -4}, +{0, -4}, +{0, -4}, +{0, -4}, +{0, -4}, +{1, 0}, +{1, -1}, +{2, 0}, +{4, 0}, +{0, 0}, +{-4, 0}, +{-2, 0}, +{-2, 2}, +{-1, 0}, +{-1, 1}, +{-1, 2}, +{-1, 3}, +{-1, 4}, +{-1, 5}, +{-1, 6}, +{-1, 7}, +{-1, 8}, +{-1, 9}, +{-1, 10}, +{-1, 11}, +{-1, 12}, +// numerator = -3 +{0, -3}, +{0, -3}, +{0, -3}, +{0, -3}, +{0, -3}, +{0, -3}, +{0, -3}, +{0, -3}, +{0, -3}, +{0, -3}, +{0, -3}, +{0, -3}, +{1, 0}, +{1, -1}, +{3, 0}, +{0, 0}, +{-3, 0}, +{-2, 1}, +{-1, 0}, +{-1, 1}, +{-1, 2}, +{-1, 3}, +{-1, 4}, +{-1, 5}, +{-1, 6}, +{-1, 7}, +{-1, 8}, +{-1, 9}, +{-1, 10}, +{-1, 11}, +{-1, 12}, +{-1, 13}, +// numerator = -2 +{0, -2}, +{0, -2}, +{0, -2}, +{0, -2}, +{0, -2}, +{0, -2}, +{0, -2}, +{0, -2}, +{0, -2}, +{0, -2}, +{0, -2}, +{0, -2}, +{0, -2}, +{1, 0}, +{2, 0}, +{0, 0}, +{-2, 0}, +{-1, 0}, +{-1, 1}, +{-1, 2}, +{-1, 3}, +{-1, 4}, +{-1, 5}, +{-1, 6}, +{-1, 7}, +{-1, 8}, +{-1, 9}, +{-1, 10}, +{-1, 11}, +{-1, 12}, +{-1, 13}, +{-1, 14}, +// numerator = -1 +{0, -1}, +{0, -1}, +{0, -1}, +{0, -1}, +{0, -1}, +{0, -1}, +{0, -1}, +{0, -1}, +{0, -1}, +{0, -1}, +{0, -1}, +{0, -1}, +{0, -1}, +{0, -1}, +{1, 0}, +{0, 0}, +{-1, 0}, +{-1, 1}, +{-1, 2}, +{-1, 3}, +{-1, 4}, +{-1, 5}, +{-1, 6}, +{-1, 7}, +{-1, 8}, +{-1, 9}, +{-1, 10}, +{-1, 11}, +{-1, 12}, +{-1, 13}, +{-1, 14}, +{-1, 15}, +// numerator = 0 +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +// numerator = 1 +{-1, -14}, +{-1, -13}, +{-1, -12}, +{-1, -11}, +{-1, -10}, +{-1, -9}, +{-1, -8}, +{-1, -7}, +{-1, -6}, +{-1, -5}, +{-1, -4}, +{-1, -3}, +{-1, -2}, +{-1, -1}, +{-1, 0}, +{0, 0}, +{1, 0}, +{0, 1}, +{0, 1}, +{0, 1}, +{0, 1}, +{0, 1}, +{0, 1}, +{0, 1}, +{0, 1}, +{0, 1}, +{0, 1}, +{0, 1}, +{0, 1}, +{0, 1}, +{0, 1}, +{0, 1}, +// numerator = 2 +{-1, -13}, +{-1, -12}, +{-1, -11}, +{-1, -10}, +{-1, -9}, +{-1, -8}, +{-1, -7}, +{-1, -6}, +{-1, -5}, +{-1, -4}, +{-1, -3}, +{-1, -2}, +{-1, -1}, +{-1, 0}, +{-2, 0}, +{0, 0}, +{2, 0}, +{1, 0}, +{0, 2}, +{0, 2}, +{0, 2}, +{0, 2}, +{0, 2}, +{0, 2}, +{0, 2}, +{0, 2}, +{0, 2}, +{0, 2}, +{0, 2}, +{0, 2}, +{0, 2}, +{0, 2}, +// numerator = 3 +{-1, -12}, +{-1, -11}, +{-1, -10}, +{-1, -9}, +{-1, -8}, +{-1, -7}, +{-1, -6}, +{-1, -5}, +{-1, -4}, +{-1, -3}, +{-1, -2}, +{-1, -1}, +{-1, 0}, +{-2, -1}, +{-3, 0}, +{0, 0}, +{3, 0}, +{1, 1}, +{1, 0}, +{0, 3}, +{0, 3}, +{0, 3}, +{0, 3}, +{0, 3}, +{0, 3}, +{0, 3}, +{0, 3}, +{0, 3}, +{0, 3}, +{0, 3}, +{0, 3}, +{0, 3}, +// numerator = 4 +{-1, -11}, +{-1, -10}, +{-1, -9}, +{-1, -8}, +{-1, -7}, +{-1, -6}, +{-1, -5}, +{-1, -4}, +{-1, -3}, +{-1, -2}, +{-1, -1}, +{-1, 0}, +{-2, -2}, +{-2, 0}, +{-4, 0}, +{0, 0}, +{4, 0}, +{2, 0}, +{1, 1}, +{1, 0}, +{0, 4}, +{0, 4}, +{0, 4}, +{0, 4}, +{0, 4}, +{0, 4}, +{0, 4}, +{0, 4}, +{0, 4}, +{0, 4}, +{0, 4}, +{0, 4}, +// numerator = 5 +{-1, -10}, +{-1, -9}, +{-1, -8}, +{-1, -7}, +{-1, -6}, +{-1, -5}, +{-1, -4}, +{-1, -3}, +{-1, -2}, +{-1, -1}, +{-1, 0}, +{-2, -3}, +{-2, -1}, +{-3, -1}, +{-5, 0}, +{0, 0}, +{5, 0}, +{2, 1}, +{1, 2}, +{1, 1}, +{1, 0}, +{0, 5}, +{0, 5}, +{0, 5}, +{0, 5}, +{0, 5}, +{0, 5}, +{0, 5}, +{0, 5}, +{0, 5}, +{0, 5}, +{0, 5}, +// numerator = 6 +{-1, -9}, +{-1, -8}, +{-1, -7}, +{-1, -6}, +{-1, -5}, +{-1, -4}, +{-1, -3}, +{-1, -2}, +{-1, -1}, +{-1, 0}, +{-2, -4}, +{-2, -2}, +{-2, 0}, +{-3, 0}, +{-6, 0}, +{0, 0}, +{6, 0}, +{3, 0}, +{2, 0}, +{1, 2}, +{1, 1}, +{1, 0}, +{0, 6}, +{0, 6}, +{0, 6}, +{0, 6}, +{0, 6}, +{0, 6}, +{0, 6}, +{0, 6}, +{0, 6}, +{0, 6}, +// numerator = 7 +{-1, -8}, +{-1, -7}, +{-1, -6}, +{-1, -5}, +{-1, -4}, +{-1, -3}, +{-1, -2}, +{-1, -1}, +{-1, 0}, +{-2, -5}, +{-2, -3}, +{-2, -1}, +{-3, -2}, +{-4, -1}, +{-7, 0}, +{0, 0}, +{7, 0}, +{3, 1}, +{2, 1}, +{1, 3}, +{1, 2}, +{1, 1}, +{1, 0}, +{0, 7}, +{0, 7}, +{0, 7}, +{0, 7}, +{0, 7}, +{0, 7}, +{0, 7}, +{0, 7}, +{0, 7}, +// numerator = 8 +{-1, -7}, +{-1, -6}, +{-1, -5}, +{-1, -4}, +{-1, -3}, +{-1, -2}, +{-1, -1}, +{-1, 0}, +{-2, -6}, +{-2, -4}, +{-2, -2}, +{-2, 0}, +{-3, -1}, +{-4, 0}, +{-8, 0}, +{0, 0}, +{8, 0}, +{4, 0}, +{2, 2}, +{2, 0}, +{1, 3}, +{1, 2}, +{1, 1}, +{1, 0}, +{0, 8}, +{0, 8}, +{0, 8}, +{0, 8}, +{0, 8}, +{0, 8}, +{0, 8}, +{0, 8}, +// numerator = 9 +{-1, -6}, +{-1, -5}, +{-1, -4}, +{-1, -3}, +{-1, -2}, +{-1, -1}, +{-1, 0}, +{-2, -7}, +{-2, -5}, +{-2, -3}, +{-2, -1}, +{-3, -3}, +{-3, 0}, +{-5, -1}, +{-9, 0}, +{0, 0}, +{9, 0}, +{4, 1}, +{3, 0}, +{2, 1}, +{1, 4}, +{1, 3}, +{1, 2}, +{1, 1}, +{1, 0}, +{0, 9}, +{0, 9}, +{0, 9}, +{0, 9}, +{0, 9}, +{0, 9}, +{0, 9}, +// numerator = 10 +{-1, -5}, +{-1, -4}, +{-1, -3}, +{-1, -2}, +{-1, -1}, +{-1, 0}, +{-2, -8}, +{-2, -6}, +{-2, -4}, +{-2, -2}, +{-2, 0}, +{-3, -2}, +{-4, -2}, +{-5, 0}, +{-10, 0}, +{0, 0}, +{10, 0}, +{5, 0}, +{3, 1}, +{2, 2}, +{2, 0}, +{1, 4}, +{1, 3}, +{1, 2}, +{1, 1}, +{1, 0}, +{0, 10}, +{0, 10}, +{0, 10}, +{0, 10}, +{0, 10}, +{0, 10}, +// numerator = 11 +{-1, -4}, +{-1, -3}, +{-1, -2}, +{-1, -1}, +{-1, 0}, +{-2, -9}, +{-2, -7}, +{-2, -5}, +{-2, -3}, +{-2, -1}, +{-3, -4}, +{-3, -1}, +{-4, -1}, +{-6, -1}, +{-11, 0}, +{0, 0}, +{11, 0}, +{5, 1}, +{3, 2}, +{2, 3}, +{2, 1}, +{1, 5}, +{1, 4}, +{1, 3}, +{1, 2}, +{1, 1}, +{1, 0}, +{0, 11}, +{0, 11}, +{0, 11}, +{0, 11}, +{0, 11}, +// numerator = 12 +{-1, -3}, +{-1, -2}, +{-1, -1}, +{-1, 0}, +{-2, -10}, +{-2, -8}, +{-2, -6}, +{-2, -4}, +{-2, -2}, +{-2, 0}, +{-3, -3}, +{-3, 0}, +{-4, 0}, +{-6, 0}, +{-12, 0}, +{0, 0}, +{12, 0}, +{6, 0}, +{4, 0}, +{3, 0}, +{2, 2}, +{2, 0}, +{1, 5}, +{1, 4}, +{1, 3}, +{1, 2}, +{1, 1}, +{1, 0}, +{0, 12}, +{0, 12}, +{0, 12}, +{0, 12}, +// numerator = 13 +{-1, -2}, +{-1, -1}, +{-1, 0}, +{-2, -11}, +{-2, -9}, +{-2, -7}, +{-2, -5}, +{-2, -3}, +{-2, -1}, +{-3, -5}, +{-3, -2}, +{-4, -3}, +{-5, -2}, +{-7, -1}, +{-13, 0}, +{0, 0}, +{13, 0}, +{6, 1}, +{4, 1}, +{3, 1}, +{2, 3}, +{2, 1}, +{1, 6}, +{1, 5}, +{1, 4}, +{1, 3}, +{1, 2}, +{1, 1}, +{1, 0}, +{0, 13}, +{0, 13}, +{0, 13}, +// numerator = 14 +{-1, -1}, +{-1, 0}, +{-2, -12}, +{-2, -10}, +{-2, -8}, +{-2, -6}, +{-2, -4}, +{-2, -2}, +{-2, 0}, +{-3, -4}, +{-3, -1}, +{-4, -2}, +{-5, -1}, +{-7, 0}, +{-14, 0}, +{0, 0}, +{14, 0}, +{7, 0}, +{4, 2}, +{3, 2}, +{2, 4}, +{2, 2}, +{2, 0}, +{1, 6}, +{1, 5}, +{1, 4}, +{1, 3}, +{1, 2}, +{1, 1}, +{1, 0}, +{0, 14}, +{0, 14}, +// numerator = 15 +{-1, 0}, +{-2, -13}, +{-2, -11}, +{-2, -9}, +{-2, -7}, +{-2, -5}, +{-2, -3}, +{-2, -1}, +{-3, -6}, +{-3, -3}, +{-3, 0}, +{-4, -1}, +{-5, 0}, +{-8, -1}, +{-15, 0}, +{0, 0}, +{15, 0}, +{7, 1}, +{5, 0}, +{3, 3}, +{3, 0}, +{2, 3}, +{2, 1}, +{1, 7}, +{1, 6}, +{1, 5}, +{1, 4}, +{1, 3}, +{1, 2}, +{1, 1}, +{1, 0}, +{0, 15}, +// numerator = 16 +{-2, -14}, +{-2, -12}, +{-2, -10}, +{-2, -8}, +{-2, -6}, +{-2, -4}, +{-2, -2}, +{-2, 0}, +{-3, -5}, +{-3, -2}, +{-4, -4}, +{-4, 0}, +{-6, -2}, +{-8, 0}, +{-16, 0}, +{0, 0}, +{16, 0}, +{8, 0}, +{5, 1}, +{4, 0}, +{3, 1}, +{2, 4}, +{2, 2}, +{2, 0}, +{1, 7}, +{1, 6}, +{1, 5}, +{1, 4}, +{1, 3}, +{1, 2}, +{1, 1}, +{1, 0}, diff --git a/r_aclip.c b/r_aclip.c new file mode 100644 index 00000000..e807bd61 --- /dev/null +++ b/r_aclip.c @@ -0,0 +1,323 @@ +/* +Copyright (C) 1997-2001 Id Software, Inc. + +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 2 +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, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +// r_aclip.c: clip routines for drawing Alias models directly to the screen + +#include "r_local.h" + +static finalvert_t fv[2][8]; + +void R_AliasProjectAndClipTestFinalVert (finalvert_t *fv); +void R_Alias_clip_top (finalvert_t *pfv0, finalvert_t *pfv1, + finalvert_t *out); +void R_Alias_clip_bottom (finalvert_t *pfv0, finalvert_t *pfv1, + finalvert_t *out); +void R_Alias_clip_left (finalvert_t *pfv0, finalvert_t *pfv1, + finalvert_t *out); +void R_Alias_clip_right (finalvert_t *pfv0, finalvert_t *pfv1, + finalvert_t *out); + + +/* +================ +R_Alias_clip_z + +pfv0 is the unclipped vertex, pfv1 is the z-clipped vertex +================ +*/ +void R_Alias_clip_z (finalvert_t *pfv0, finalvert_t *pfv1, finalvert_t *out) +{ + float scale; + + scale = (ALIAS_Z_CLIP_PLANE - pfv0->xyz[2]) / + (pfv1->xyz[2] - pfv0->xyz[2]); + + out->xyz[0] = pfv0->xyz[0] + (pfv1->xyz[0] - pfv0->xyz[0]) * scale; + out->xyz[1] = pfv0->xyz[1] + (pfv1->xyz[1] - pfv0->xyz[1]) * scale; + out->xyz[2] = ALIAS_Z_CLIP_PLANE; + + out->s = pfv0->s + (pfv1->s - pfv0->s) * scale; + out->t = pfv0->t + (pfv1->t - pfv0->t) * scale; + out->l = pfv0->l + (pfv1->l - pfv0->l) * scale; + + R_AliasProjectAndClipTestFinalVert (out); +} + + +#if !id386 + +void R_Alias_clip_left (finalvert_t *pfv0, finalvert_t *pfv1, finalvert_t *out) +{ + float scale; + + if (pfv0->v >= pfv1->v ) + { + scale = (float)(RI.aliasvrect.x - pfv0->u) / + (pfv1->u - pfv0->u); + out->u = pfv0->u + ( pfv1->u - pfv0->u ) * scale + 0.5; + out->v = pfv0->v + ( pfv1->v - pfv0->v ) * scale + 0.5; + out->s = pfv0->s + ( pfv1->s - pfv0->s ) * scale + 0.5; + out->t = pfv0->t + ( pfv1->t - pfv0->t ) * scale + 0.5; + out->l = pfv0->l + ( pfv1->l - pfv0->l ) * scale + 0.5; + out->zi = pfv0->zi + ( pfv1->zi - pfv0->zi) * scale + 0.5; + } + else + { + scale = (float)(RI.aliasvrect.x - pfv1->u) / + (pfv0->u - pfv1->u); + out->u = pfv1->u + ( pfv0->u - pfv1->u ) * scale + 0.5; + out->v = pfv1->v + ( pfv0->v - pfv1->v ) * scale + 0.5; + out->s = pfv1->s + ( pfv0->s - pfv1->s ) * scale + 0.5; + out->t = pfv1->t + ( pfv0->t - pfv1->t ) * scale + 0.5; + out->l = pfv1->l + ( pfv0->l - pfv1->l ) * scale + 0.5; + out->zi = pfv1->zi + ( pfv0->zi - pfv1->zi) * scale + 0.5; + } +} + + +void R_Alias_clip_right (finalvert_t *pfv0, finalvert_t *pfv1, finalvert_t *out) +{ + float scale; + + if ( pfv0->v >= pfv1->v ) + { + scale = (float)(RI.aliasvrectright - pfv0->u ) / + (pfv1->u - pfv0->u ); + out->u = pfv0->u + ( pfv1->u - pfv0->u ) * scale + 0.5; + out->v = pfv0->v + ( pfv1->v - pfv0->v ) * scale + 0.5; + out->s = pfv0->s + ( pfv1->s - pfv0->s ) * scale + 0.5; + out->t = pfv0->t + ( pfv1->t - pfv0->t ) * scale + 0.5; + out->l = pfv0->l + ( pfv1->l - pfv0->l ) * scale + 0.5; + out->zi = pfv0->zi + ( pfv1->zi - pfv0->zi) * scale + 0.5; + } + else + { + scale = (float)(RI.aliasvrectright - pfv1->u ) / + (pfv0->u - pfv1->u ); + out->u = pfv1->u + ( pfv0->u - pfv1->u ) * scale + 0.5; + out->v = pfv1->v + ( pfv0->v - pfv1->v ) * scale + 0.5; + out->s = pfv1->s + ( pfv0->s - pfv1->s ) * scale + 0.5; + out->t = pfv1->t + ( pfv0->t - pfv1->t ) * scale + 0.5; + out->l = pfv1->l + ( pfv0->l - pfv1->l ) * scale + 0.5; + out->zi = pfv1->zi + ( pfv0->zi - pfv1->zi) * scale + 0.5; + } +} + + +void R_Alias_clip_top (finalvert_t *pfv0, finalvert_t *pfv1, finalvert_t *out) +{ + float scale; + + if (pfv0->v >= pfv1->v) + { + scale = (float)(RI.aliasvrect.y - pfv0->v) / + (pfv1->v - pfv0->v); + out->u = pfv0->u + ( pfv1->u - pfv0->u ) * scale + 0.5; + out->v = pfv0->v + ( pfv1->v - pfv0->v ) * scale + 0.5; + out->s = pfv0->s + ( pfv1->s - pfv0->s ) * scale + 0.5; + out->t = pfv0->t + ( pfv1->t - pfv0->t ) * scale + 0.5; + out->l = pfv0->l + ( pfv1->l - pfv0->l ) * scale + 0.5; + out->zi = pfv0->zi + ( pfv1->zi - pfv0->zi) * scale + 0.5; + } + else + { + scale = (float)(RI.aliasvrect.y - pfv1->v) / + (pfv0->v - pfv1->v); + out->u = pfv1->u + ( pfv0->u - pfv1->u ) * scale + 0.5; + out->v = pfv1->v + ( pfv0->v - pfv1->v ) * scale + 0.5; + out->s = pfv1->s + ( pfv0->s - pfv1->s ) * scale + 0.5; + out->t = pfv1->t + ( pfv0->t - pfv1->t ) * scale + 0.5; + out->l = pfv1->l + ( pfv0->l - pfv1->l ) * scale + 0.5; + out->zi = pfv1->zi + ( pfv0->zi - pfv1->zi) * scale + 0.5; + } +} + + +void R_Alias_clip_bottom (finalvert_t *pfv0, finalvert_t *pfv1, + finalvert_t *out) +{ + float scale; + + if (pfv0->v >= pfv1->v) + { + scale = (float)(RI.aliasvrectbottom - pfv0->v) / + (pfv1->v - pfv0->v); + + out->u = pfv0->u + ( pfv1->u - pfv0->u ) * scale + 0.5; + out->v = pfv0->v + ( pfv1->v - pfv0->v ) * scale + 0.5; + out->s = pfv0->s + ( pfv1->s - pfv0->s ) * scale + 0.5; + out->t = pfv0->t + ( pfv1->t - pfv0->t ) * scale + 0.5; + out->l = pfv0->l + ( pfv1->l - pfv0->l ) * scale + 0.5; + out->zi = pfv0->zi + ( pfv1->zi - pfv0->zi) * scale + 0.5; + } + else + { + scale = (float)(RI.aliasvrectbottom - pfv1->v) / + (pfv0->v - pfv1->v); + + out->u = pfv1->u + ( pfv0->u - pfv1->u ) * scale + 0.5; + out->v = pfv1->v + ( pfv0->v - pfv1->v ) * scale + 0.5; + out->s = pfv1->s + ( pfv0->s - pfv1->s ) * scale + 0.5; + out->t = pfv1->t + ( pfv0->t - pfv1->t ) * scale + 0.5; + out->l = pfv1->l + ( pfv0->l - pfv1->l ) * scale + 0.5; + out->zi = pfv1->zi + ( pfv0->zi - pfv1->zi) * scale + 0.5; + } +} + +#endif + + +int R_AliasClip (finalvert_t *in, finalvert_t *out, int flag, int count, + void(*clip)(finalvert_t *pfv0, finalvert_t *pfv1, finalvert_t *out) ) +{ + int i,j,k; + int flags, oldflags; + + j = count-1; + k = 0; + for (i=0 ; i RI.aliasvrectright) + out[k].flags |= ALIAS_RIGHT_CLIP; + if (out[k].v > RI.aliasvrectbottom) + out[k].flags |= ALIAS_BOTTOM_CLIP; + k++; + } + if (!flags) + { + out[k] = in[i]; + k++; + } + } + + return k; +} + + +/* +================ +R_AliasClipTriangle +================ +*/ +void R_AliasClipTriangle (finalvert_t *index0, finalvert_t *index1, finalvert_t *index2) +{ + int i, k, pingpong; + unsigned clipflags; + +// copy vertexes and fix seam texture coordinates + fv[0][0] = *index0; + fv[0][1] = *index1; + fv[0][2] = *index2; + +// clip + clipflags = fv[0][0].flags | fv[0][1].flags | fv[0][2].flags; + + if (clipflags & ALIAS_Z_CLIP) + { + k = R_AliasClip (fv[0], fv[1], ALIAS_Z_CLIP, 3, R_Alias_clip_z); + if (k == 0) + return; + + pingpong = 1; + clipflags = fv[1][0].flags | fv[1][1].flags | fv[1][2].flags; + } + else + { + pingpong = 0; + k = 3; + } + + if (clipflags & ALIAS_LEFT_CLIP) + { + k = R_AliasClip (fv[pingpong], fv[pingpong ^ 1], + ALIAS_LEFT_CLIP, k, R_Alias_clip_left); + if (k == 0) + return; + + pingpong ^= 1; + } + + if (clipflags & ALIAS_RIGHT_CLIP) + { + k = R_AliasClip (fv[pingpong], fv[pingpong ^ 1], + ALIAS_RIGHT_CLIP, k, R_Alias_clip_right); + if (k == 0) + return; + + pingpong ^= 1; + } + + if (clipflags & ALIAS_BOTTOM_CLIP) + { + k = R_AliasClip (fv[pingpong], fv[pingpong ^ 1], + ALIAS_BOTTOM_CLIP, k, R_Alias_clip_bottom); + if (k == 0) + return; + + pingpong ^= 1; + } + + if (clipflags & ALIAS_TOP_CLIP) + { + k = R_AliasClip (fv[pingpong], fv[pingpong ^ 1], + ALIAS_TOP_CLIP, k, R_Alias_clip_top); + if (k == 0) + return; + + pingpong ^= 1; + } + + for (i=0 ; i RI.aliasvrectright) + fv[pingpong][i].u = RI.aliasvrectright; + + if (fv[pingpong][i].v < RI.aliasvrect.y) + fv[pingpong][i].v = RI.aliasvrect.y; + else if (fv[pingpong][i].v > RI.aliasvrectbottom) + fv[pingpong][i].v = RI.aliasvrectbottom; + + fv[pingpong][i].flags = 0; + } + +// draw triangles + for (i=1 ; ileafs)] + +extern int ubasestep, errorterm, erroradjustup, erroradjustdown; + + +extern mvertex_t *r_pcurrentvertbase; +extern int r_maxvalidedgeoffset; + +typedef struct +{ + finalvert_t *a, *b, *c; +} aliastriangleparms_t; + +extern aliastriangleparms_t aliastriangleparms; + + +extern int r_aliasblendcolor; + +extern float aliasxscale, aliasyscale, aliasxcenter, aliasycenter; + +void R_DrawTriangle( void ); +//void R_DrawTriangle (finalvert_t *index0, finalvert_t *index1, finalvert_t *index2); +void R_AliasClipTriangle (finalvert_t *index0, finalvert_t *index1, finalvert_t *index2); + // // r_bsp.c // @@ -1294,9 +1317,14 @@ void TransformVector (vec3_t in, vec3_t out); void R_RenderBmodelFace (bedge_t *pedges, msurface_t *psurf); void R_RenderFace (msurface_t *fa, int clipflags); -#if id386 -#error aaa -#endif +// +// r_main.c +// +void R_ConcatTransforms (float in1[3][4], float in2[3][4], float out[3][4]); + + +void R_RenderTriangle( finalvert_t *pfv ); +void R_SetupFinalVert( finalvert_t *fv, float x, float y, float z, int light, int s, int t ); // // engine callbacks diff --git a/r_main.c b/r_main.c index 5ea7cd62..34c35cf6 100644 --- a/r_main.c +++ b/r_main.c @@ -130,6 +130,7 @@ int r_clipflags; byte r_warpbuffer[WARP_WIDTH * WARP_HEIGHT]; int r_numallocatededges; +float r_aliasuvscale = 1.0; /* ================ @@ -157,6 +158,39 @@ void R_ConcatRotations (float in1[3][3], float in2[3][3], float out[3][3]) out[2][2] = in1[2][0] * in2[0][2] + in1[2][1] * in2[1][2] + in1[2][2] * in2[2][2]; } +/* +================ +R_ConcatTransforms +================ +*/ +void R_ConcatTransforms (float in1[3][4], float in2[3][4], float out[3][4]) +{ + out[0][0] = in1[0][0] * in2[0][0] + in1[0][1] * in2[1][0] + + in1[0][2] * in2[2][0]; + out[0][1] = in1[0][0] * in2[0][1] + in1[0][1] * in2[1][1] + + in1[0][2] * in2[2][1]; + out[0][2] = in1[0][0] * in2[0][2] + in1[0][1] * in2[1][2] + + in1[0][2] * in2[2][2]; + out[0][3] = in1[0][0] * in2[0][3] + in1[0][1] * in2[1][3] + + in1[0][2] * in2[2][3] + in1[0][3]; + out[1][0] = in1[1][0] * in2[0][0] + in1[1][1] * in2[1][0] + + in1[1][2] * in2[2][0]; + out[1][1] = in1[1][0] * in2[0][1] + in1[1][1] * in2[1][1] + + in1[1][2] * in2[2][1]; + out[1][2] = in1[1][0] * in2[0][2] + in1[1][1] * in2[1][2] + + in1[1][2] * in2[2][2]; + out[1][3] = in1[1][0] * in2[0][3] + in1[1][1] * in2[1][3] + + in1[1][2] * in2[2][3] + in1[1][3]; + out[2][0] = in1[2][0] * in2[0][0] + in1[2][1] * in2[1][0] + + in1[2][2] * in2[2][0]; + out[2][1] = in1[2][0] * in2[0][1] + in1[2][1] * in2[1][1] + + in1[2][2] * in2[2][1]; + out[2][2] = in1[2][0] * in2[0][2] + in1[2][1] * in2[1][2] + + in1[2][2] * in2[2][2]; + out[2][3] = in1[2][0] * in2[0][3] + in1[2][1] * in2[1][3] + + in1[2][2] * in2[2][3] + in1[2][3]; +} + @@ -991,6 +1025,19 @@ void R_DrawEntitiesOnList( void ) break; case mod_studio: //R_DrawStudioModel( RI.currententity ); + {finalvert_t fv[3]; + void R_AliasSetUpTransform (void); + extern void (*d_pdrawspans)(void *); + extern void R_PolysetFillSpans8 ( void * ); + d_pdrawspans = R_PolysetFillSpans8; + //RI.currententity = gEngfuncs.GetEntityByIndex(0); + R_AliasSetUpTransform(); + R_SetupFinalVert( &fv[0], -10, -10, 5, 0, 0, 0); + R_SetupFinalVert( &fv[1], -10, 10, 10, 0, 0, 0); + R_SetupFinalVert( &fv[2], 10, 10, -10, 0, 0, 0); + R_RenderTriangle( &fv ); + } + break; default: break; diff --git a/r_misc.c b/r_misc.c index d9112e46..fbccc98b 100644 --- a/r_misc.c +++ b/r_misc.c @@ -244,10 +244,10 @@ void R_ViewChanged (vrect_t *vr) RI.fvrectbottom = (float)RI.vrectbottom; RI.fvrectbottom_adj = (float)RI.vrectbottom - 0.5; - //RI.aliasvrect.x = (int)(RI.vrect.x * r_aliasuvscale); - //RI.aliasvrect.y = (int)(RI.vrect.y * r_aliasuvscale); - //RI.aliasvrect.width = (int)(RI.vrect.width * r_aliasuvscale); - //RI.aliasvrect.height = (int)(RI.vrect.height * r_aliasuvscale); + RI.aliasvrect.x = (int)(RI.vrect.x * r_aliasuvscale); + RI.aliasvrect.y = (int)(RI.vrect.y * r_aliasuvscale); + RI.aliasvrect.width = (int)(RI.vrect.width * r_aliasuvscale); + RI.aliasvrect.height = (int)(RI.vrect.height * r_aliasuvscale); RI.aliasvrectright = RI.aliasvrect.x + RI.aliasvrect.width; RI.aliasvrectbottom = RI.aliasvrect.y + @@ -264,17 +264,17 @@ void R_ViewChanged (vrect_t *vr) // buffer origin to get an exact edge to edge fill xcenter = ((float)RI.vrect.width * XCENTERING) + RI.vrect.x - 0.5; - //aliasxcenter = xcenter * r_aliasuvscale; + aliasxcenter = xcenter * r_aliasuvscale; ycenter = ((float)RI.vrect.height * YCENTERING) + RI.vrect.y - 0.5; -// aliasycenter = ycenter * r_aliasuvscale; + aliasycenter = ycenter * r_aliasuvscale; xscale = RI.vrect.width / RI.horizontalFieldOfView; -// aliasxscale = xscale * r_aliasuvscale; + aliasxscale = xscale * r_aliasuvscale; xscaleinv = 1.0 / xscale; yscale = xscale; -// aliasyscale = yscale * r_aliasuvscale; + aliasyscale = yscale * r_aliasuvscale; yscaleinv = 1.0 / yscale; xscaleshrink = (RI.vrect.width-6)/RI.horizontalFieldOfView; yscaleshrink = xscaleshrink; diff --git a/r_polyse.c b/r_polyse.c new file mode 100644 index 00000000..fed994a0 --- /dev/null +++ b/r_polyse.c @@ -0,0 +1,1612 @@ +/* +Copyright (C) 1997-2001 Id Software, Inc. + +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 2 +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, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +// d_polyset.c: routines for drawing sets of polygons sharing the same +// texture (used for Alias models) + +#include "r_local.h" +/* +int rand1k[] = { +#include "rand1k.h" +}; +*/ +#define MASK_1K 0x3FF + +int rand1k_index = 0; + +// TODO: put in span spilling to shrink list size +// !!! if this is changed, it must be changed in d_polysa.s too !!! +#define DPS_MAXSPANS MAXHEIGHT+1 + // 1 extra for spanpackage that marks end + +// !!! if this is changed, it must be changed in asm_draw.h too !!! +typedef struct { + void *pdest; + short *pz; + int count; + byte *ptex; + int sfrac, tfrac, light, zi; +} spanpackage_t; + +typedef struct { + int isflattop; + int numleftedges; + int *pleftedgevert0; + int *pleftedgevert1; + int *pleftedgevert2; + int numrightedges; + int *prightedgevert0; + int *prightedgevert1; + int *prightedgevert2; +} edgetable; + +aliastriangleparms_t aliastriangleparms; + +int r_p0[6], r_p1[6], r_p2[6]; + +byte *d_pcolormap; + +int d_aflatcolor; +int d_xdenom; + +edgetable *pedgetable; + +edgetable edgetables[12] = { + {0, 1, r_p0, r_p2, NULL, 2, r_p0, r_p1, r_p2 }, + {0, 2, r_p1, r_p0, r_p2, 1, r_p1, r_p2, NULL}, + {1, 1, r_p0, r_p2, NULL, 1, r_p1, r_p2, NULL}, + {0, 1, r_p1, r_p0, NULL, 2, r_p1, r_p2, r_p0 }, + {0, 2, r_p0, r_p2, r_p1, 1, r_p0, r_p1, NULL}, + {0, 1, r_p2, r_p1, NULL, 1, r_p2, r_p0, NULL}, + {0, 1, r_p2, r_p1, NULL, 2, r_p2, r_p0, r_p1 }, + {0, 2, r_p2, r_p1, r_p0, 1, r_p2, r_p0, NULL}, + {0, 1, r_p1, r_p0, NULL, 1, r_p1, r_p2, NULL}, + {1, 1, r_p2, r_p1, NULL, 1, r_p0, r_p1, NULL}, + {1, 1, r_p1, r_p0, NULL, 1, r_p2, r_p0, NULL}, + {0, 1, r_p0, r_p2, NULL, 1, r_p0, r_p1, NULL}, +}; + +// FIXME: some of these can become statics +int a_sstepxfrac, a_tstepxfrac, r_lstepx, a_ststepxwhole; +int r_sstepx, r_tstepx, r_lstepy, r_sstepy, r_tstepy; +int r_zistepx, r_zistepy; +int d_aspancount, d_countextrastep; + +spanpackage_t *a_spans; +spanpackage_t *d_pedgespanpackage; +static int ystart; +pixel_t *d_pdest, *d_ptex; +short *d_pz; +int d_sfrac, d_tfrac, d_light, d_zi; +int d_ptexextrastep, d_sfracextrastep; +int d_tfracextrastep, d_lightextrastep, d_pdestextrastep; +int d_lightbasestep, d_pdestbasestep, d_ptexbasestep; +int d_sfracbasestep, d_tfracbasestep; +int d_ziextrastep, d_zibasestep; +int d_pzextrastep, d_pzbasestep; + +typedef struct { + int quotient; + int remainder; +} adivtab_t; + +static adivtab_t adivtab[32*32] = { +#include "adivtab.h" +}; + +byte *skintable[MAX_LBM_HEIGHT]; +int skinwidth; +byte *skinstart; + +void (*d_pdrawspans)(spanpackage_t *pspanpackage); + +void R_PolysetDrawSpans8_33 (spanpackage_t *pspanpackage); +void R_PolysetDrawSpans8_66 (spanpackage_t *pspanpackage); +void R_PolysetDrawSpans8_Opaque (spanpackage_t *pspanpackage); + +void R_PolysetDrawThreshSpans8 (spanpackage_t *pspanpackage); +void R_PolysetCalcGradients (int skinwidth); +void R_DrawNonSubdiv (void); +void R_PolysetSetEdgeTable (void); +void R_RasterizeAliasPolySmooth (void); +void R_PolysetScanLeftEdge(int height); +void R_PolysetScanLeftEdge_C(int height); + +// ====================== +// PGM +// 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 +byte iractive = 0; +byte irtable[256] = { 79, 78, 77, 76, 75, 74, 73, 72, // black/white + 71, 70, 69, 68, 67, 66, 65, 64, + 64, 65, 66, 67, 68, 69, 70, 71, // dark taupe + 72, 73, 74, 75, 76, 77, 78, 79, + + 64, 65, 66, 67, 68, 69, 70, 71, // slate grey + 72, 73, 74, 75, 76, 77, 78, 79, + 208, 208, 208, 208, 208, 208, 208, 208, // unused?' + 64, 66, 68, 70, 72, 74, 76, 78, // dark yellow + + 64, 65, 66, 67, 68, 69, 70, 71, // dark red + 72, 73, 74, 75, 76, 77, 78, 79, + 64, 65, 66, 67, 68, 69, 70, 71, // grey/tan + 72, 73, 74, 75, 76, 77, 78, 79, + + 64, 66, 68, 70, 72, 74, 76, 78, // chocolate + 68, 67, 66, 65, 64, 65, 66, 67, // mauve / teal + 68, 69, 70, 71, 72, 73, 74, 75, + 76, 76, 77, 77, 78, 78, 79, 79, + + 64, 65, 66, 67, 68, 69, 70, 71, // more mauve + 72, 73, 74, 75, 76, 77, 78, 79, + 64, 65, 66, 67, 68, 69, 70, 71, // olive + 72, 73, 74, 75, 76, 77, 78, 79, + + 64, 65, 66, 67, 68, 69, 70, 71, // maroon + 72, 73, 74, 75, 76, 77, 78, 79, + 64, 65, 66, 67, 68, 69, 70, 71, // sky blue + 72, 73, 74, 75, 76, 77, 78, 79, + + 64, 65, 66, 67, 68, 69, 70, 71, // olive again + 72, 73, 74, 75, 76, 77, 78, 79, + 64, 65, 66, 67, 68, 69, 70, 71, // nuclear green + 64, 65, 66, 67, 68, 69, 70, 71, // bright yellow + + 64, 65, 66, 67, 68, 69, 70, 71, // fire colors + 72, 73, 74, 75, 76, 77, 78, 79, + 208, 208, 64, 64, 70, 71, 72, 64, // mishmash1 + 66, 68, 70, 64, 65, 66, 67, 68}; // mishmash2 +// PGM +// ====================== + +/* +================ +R_PolysetUpdateTables +================ +*/ +void R_PolysetUpdateTables (void) +{ + int i; + byte *s; + + if (r_affinetridesc.skinwidth != skinwidth || + r_affinetridesc.pskin != skinstart) + { + skinwidth = r_affinetridesc.skinwidth; + skinstart = r_affinetridesc.pskin; + s = skinstart; + for (i=0 ; iv[1] - aliastriangleparms.b->v[1] ) * ( aliastriangleparms.a->v[0] - aliastriangleparms.c->v[0] ) - + ( aliastriangleparms.a->v[0] - aliastriangleparms.b->v[0] ) * ( aliastriangleparms.a->v[1] - aliastriangleparms.c->v[1] ); + */ + + dv0_ab = aliastriangleparms.a->u - aliastriangleparms.b->u; + dv1_ab = aliastriangleparms.a->v - aliastriangleparms.b->v; + + if ( !( dv0_ab | dv1_ab ) ) + return; + + dv0_ac = aliastriangleparms.a->u - aliastriangleparms.c->u; + dv1_ac = aliastriangleparms.a->v - aliastriangleparms.c->v; + + if ( !( dv0_ac | dv1_ac ) ) + return; + + d_xdenom = ( dv0_ac * dv1_ab ) - ( dv0_ab * dv1_ac ); + + if ( d_xdenom < 0 ) + { + a_spans = spans; + + r_p0[0] = aliastriangleparms.a->u; // u + r_p0[1] = aliastriangleparms.a->v; // v + r_p0[2] = aliastriangleparms.a->s; // s + r_p0[3] = aliastriangleparms.a->t; // t + r_p0[4] = aliastriangleparms.a->l; // light + r_p0[5] = aliastriangleparms.a->zi; // iz + + r_p1[0] = aliastriangleparms.b->u; + r_p1[1] = aliastriangleparms.b->v; + r_p1[2] = aliastriangleparms.b->s; + r_p1[3] = aliastriangleparms.b->t; + r_p1[4] = aliastriangleparms.b->l; + r_p1[5] = aliastriangleparms.b->zi; + + r_p2[0] = aliastriangleparms.c->u; + r_p2[1] = aliastriangleparms.c->v; + r_p2[2] = aliastriangleparms.c->s; + r_p2[3] = aliastriangleparms.c->t; + r_p2[4] = aliastriangleparms.c->l; + r_p2[5] = aliastriangleparms.c->zi; + + R_PolysetSetEdgeTable (); + R_RasterizeAliasPolySmooth (); + } +} + + +/* +=================== +R_PolysetScanLeftEdge_C +==================== +*/ +void R_PolysetScanLeftEdge_C(int height) +{ + do + { + d_pedgespanpackage->pdest = d_pdest; + d_pedgespanpackage->pz = d_pz; + d_pedgespanpackage->count = d_aspancount; + d_pedgespanpackage->ptex = d_ptex; + + d_pedgespanpackage->sfrac = d_sfrac; + d_pedgespanpackage->tfrac = d_tfrac; + + // FIXME: need to clamp l, s, t, at both ends? + d_pedgespanpackage->light = d_light; + d_pedgespanpackage->zi = d_zi; + + d_pedgespanpackage++; + + errorterm += erroradjustup; + if (errorterm >= 0) + { + d_pdest += d_pdestextrastep; + d_pz += d_pzextrastep; + d_aspancount += d_countextrastep; + d_ptex += d_ptexextrastep; + d_sfrac += d_sfracextrastep; + d_ptex += d_sfrac >> 16; + + d_sfrac &= 0xFFFF; + d_tfrac += d_tfracextrastep; + if (d_tfrac & 0x10000) + { + d_ptex += r_affinetridesc.skinwidth; + d_tfrac &= 0xFFFF; + } + d_light += d_lightextrastep; + d_zi += d_ziextrastep; + errorterm -= erroradjustdown; + } + else + { + d_pdest += d_pdestbasestep; + d_pz += d_pzbasestep; + d_aspancount += ubasestep; + d_ptex += d_ptexbasestep; + d_sfrac += d_sfracbasestep; + d_ptex += d_sfrac >> 16; + d_sfrac &= 0xFFFF; + d_tfrac += d_tfracbasestep; + if (d_tfrac & 0x10000) + { + d_ptex += r_affinetridesc.skinwidth; + d_tfrac &= 0xFFFF; + } + d_light += d_lightbasestep; + d_zi += d_zibasestep; + } + } while (--height); +} + +/* +=================== +FloorDivMod + +Returns mathematically correct (floor-based) quotient and remainder for +numer and denom, both of which should contain no fractional part. The +quotient must fit in 32 bits. +FIXME: GET RID OF THIS! (FloorDivMod) +==================== +*/ +void FloorDivMod (float numer, float denom, int *quotient, + int *rem) +{ + int q, r; + float x; + + if (numer >= 0.0) + { + + x = floor(numer / denom); + q = (int)x; + r = (int)floor(numer - (x * denom)); + } + else + { + // + // perform operations with positive values, and fix mod to make floor-based + // + x = floor(-numer / denom); + q = -(int)x; + r = (int)floor(-numer - (x * denom)); + if (r != 0) + { + q--; + r = (int)denom - r; + } + } + + *quotient = q; + *rem = r; +} + + +/* +=================== +R_PolysetSetUpForLineScan +==================== +*/ +void R_PolysetSetUpForLineScan(fixed8_t startvertu, fixed8_t startvertv, + fixed8_t endvertu, fixed8_t endvertv) +{ + float dm, dn; + int tm, tn; + adivtab_t *ptemp; + +// TODO: implement x86 version + + errorterm = -1; + + tm = endvertu - startvertu; + tn = endvertv - startvertv; + + if (((tm <= 16) && (tm >= -15)) && + ((tn <= 16) && (tn >= -15))) + { + ptemp = &adivtab[((tm+15) << 5) + (tn+15)]; + ubasestep = ptemp->quotient; + erroradjustup = ptemp->remainder; + erroradjustdown = tn; + } + else + { + dm = tm; + dn = tn; + + FloorDivMod (dm, dn, &ubasestep, &erroradjustup); + + erroradjustdown = dn; + } +} + + + +/* +================ +R_PolysetCalcGradients +================ +*/ +#if id386 && !defined __linux__ +void R_PolysetCalcGradients( int skinwidth ) +{ + static float xstepdenominv, ystepdenominv, t0, t1; + static float p01_minus_p21, p11_minus_p21, p00_minus_p20, p10_minus_p20; + static float one = 1.0F, negative_one = -1.0F; + static unsigned long t0_int, t1_int; + + extern unsigned long fpu_sp24_ceil_cw, fpu_ceil_cw, fpu_chop_cw; + + /* + p00_minus_p20 = r_p0[0] - r_p2[0]; + p01_minus_p21 = r_p0[1] - r_p2[1]; + p10_minus_p20 = r_p1[0] - r_p2[0]; + p11_minus_p21 = r_p1[1] - r_p2[1]; + */ + + __asm mov eax, dword ptr [r_p0+0] + __asm mov ebx, dword ptr [r_p0+4] + __asm sub eax, dword ptr [r_p2+0] + __asm sub ebx, dword ptr [r_p2+4] + __asm mov p00_minus_p20, eax + __asm mov p01_minus_p21, ebx + __asm fild dword ptr p00_minus_p20 + __asm fild dword ptr p01_minus_p21 + __asm mov eax, dword ptr [r_p1+0] + __asm mov ebx, dword ptr [r_p1+4] + __asm sub eax, dword ptr [r_p2+0] + __asm sub ebx, dword ptr [r_p2+4] + __asm fstp p01_minus_p21 + __asm fstp p00_minus_p20 + __asm mov p10_minus_p20, eax + __asm mov p11_minus_p21, ebx + __asm fild dword ptr p10_minus_p20 + __asm fild dword ptr p11_minus_p21 + __asm fstp p11_minus_p21 + __asm fstp p10_minus_p20 + + /* + xstepdenominv = 1.0 / (float)d_xdenom; + + ystepdenominv = -xstepdenominv; + */ + + /* + ** put FPU in single precision ceil mode + */ + __asm fldcw word ptr [fpu_sp24_ceil_cw] +// __asm fldcw word ptr [fpu_ceil_cw] + + __asm fild dword ptr d_xdenom ; d_xdenom + __asm fdivr one ; 1 / d_xdenom + __asm fst xstepdenominv ; + __asm fmul negative_one ; -( 1 / d_xdenom ) + +// ceil () for light so positive steps are exaggerated, negative steps +// diminished, pushing us away from underflow toward overflow. Underflow is +// very visible, overflow is very unlikely, because of ambient lighting + /* + t0 = r_p0[4] - r_p2[4]; + t1 = r_p1[4] - r_p2[4]; + r_lstepx = (int) + ceil((t1 * p01_minus_p21 - t0 * p11_minus_p21) * xstepdenominv); + r_lstepy = (int) + ceil((t1 * p00_minus_p20 - t0 * p10_minus_p20) * ystepdenominv); + */ + __asm mov eax, dword ptr [r_p0+16] + __asm mov ebx, dword ptr [r_p1+16] + __asm sub eax, dword ptr [r_p2+16] + __asm sub ebx, dword ptr [r_p2+16] + + __asm fstp ystepdenominv ; (empty) + + __asm mov t0_int, eax + __asm mov t1_int, ebx + __asm fild t0_int ; t0 + __asm fild t1_int ; t1 | t0 + __asm fxch st(1) ; t0 | t1 + __asm fstp t0 ; t1 + __asm fst t1 ; t1 + __asm fmul p01_minus_p21 ; t1 * p01_minus_p21 + __asm fld t0 ; t0 | t1 * p01_minus_p21 + __asm fmul p11_minus_p21 ; t0 * p11_minus_p21 | t1 * p01_minus_p21 + __asm fld t1 ; t1 | t0 * p11_minus_p21 | t1 * p01_minus_p21 + __asm fmul p00_minus_p20 ; t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21 + __asm fld t0 ; t0 | t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21 + __asm fmul p10_minus_p20 ; t0 * p10_minus_p20 | t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21 + __asm fxch st(2) ; t0 * p11_minus_p21 | t0 * p10_minus_p20 | t1 * p00_minus_p20 | t1 * p01_minus_p21 + __asm fsubp st(3), st ; t0 * p10_minus_p20 | t1 * p00_minus_p20 | t1 * p01_minus_p21 - t0 * p11_minus_p21 + __asm fsubrp st(1), st ; t1 * p00_minus_p20 - t0 * p10_minus_p20 | t1 * p01_minus_p21 - t0 * p11_minus_p21 + __asm fxch st(1) ; t1 * p01_minus_p21 - t0 * p11_minus_p21 | t1 * p00_minus_p20 - t0 * p10_minus_p20 + __asm fmul xstepdenominv ; r_lstepx | t1 * p00_minus_p20 - t0 * p10_minus_p20 + __asm fxch st(1) + __asm fmul ystepdenominv ; r_lstepy | r_lstepx + __asm fxch st(1) ; r_lstepx | r_lstepy + __asm fistp dword ptr [r_lstepx] + __asm fistp dword ptr [r_lstepy] + + /* + ** put FPU back into extended precision chop mode + */ + __asm fldcw word ptr [fpu_chop_cw] + + /* + t0 = r_p0[2] - r_p2[2]; + t1 = r_p1[2] - r_p2[2]; + r_sstepx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) * + xstepdenominv); + r_sstepy = (int)((t1 * p00_minus_p20 - t0* p10_minus_p20) * + ystepdenominv); + */ + __asm mov eax, dword ptr [r_p0+8] + __asm mov ebx, dword ptr [r_p1+8] + __asm sub eax, dword ptr [r_p2+8] + __asm sub ebx, dword ptr [r_p2+8] + __asm mov t0_int, eax + __asm mov t1_int, ebx + __asm fild t0_int ; t0 + __asm fild t1_int ; t1 | t0 + __asm fxch st(1) ; t0 | t1 + __asm fstp t0 ; t1 + __asm fst t1 ; (empty) + + __asm fmul p01_minus_p21 ; t1 * p01_minus_p21 + __asm fld t0 ; t0 | t1 * p01_minus_p21 + __asm fmul p11_minus_p21 ; t0 * p11_minus_p21 | t1 * p01_minus_p21 + __asm fld t1 ; t1 | t0 * p11_minus_p21 | t1 * p01_minus_p21 + __asm fmul p00_minus_p20 ; t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21 + __asm fld t0 ; t0 | t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21 + __asm fmul p10_minus_p20 ; t0 * p10_minus_p20 | t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21 + __asm fxch st(2) ; t0 * p11_minus_p21 | t0 * p10_minus_p20 | t1 * p00_minus_p20 | t1 * p01_minus_p21 + __asm fsubp st(3), st ; t0 * p10_minus_p20 | t1 * p00_minus_p20 | t1 * p01_minus_p21 - t0 * p11_minus_p21 + __asm fsubrp st(1), st ; t1 * p00_minus_p20 - t0 * p10_minus_p20 | t1 * p01_minus_p21 - t0 * p11_minus_p21 + __asm fxch st(1) ; t1 * p01_minus_p21 - t0 * p11_minus_p21 | t1 * p00_minus_p20 - t0 * p10_minus_p20 + __asm fmul xstepdenominv ; r_lstepx | t1 * p00_minus_p20 - t0 * p10_minus_p20 + __asm fxch st(1) + __asm fmul ystepdenominv ; r_lstepy | r_lstepx + __asm fxch st(1) ; r_lstepx | r_lstepy + __asm fistp dword ptr [r_sstepx] + __asm fistp dword ptr [r_sstepy] + + /* + t0 = r_p0[3] - r_p2[3]; + t1 = r_p1[3] - r_p2[3]; + r_tstepx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) * + xstepdenominv); + r_tstepy = (int)((t1 * p00_minus_p20 - t0 * p10_minus_p20) * + ystepdenominv); + */ + __asm mov eax, dword ptr [r_p0+12] + __asm mov ebx, dword ptr [r_p1+12] + __asm sub eax, dword ptr [r_p2+12] + __asm sub ebx, dword ptr [r_p2+12] + + __asm mov t0_int, eax + __asm mov t1_int, ebx + __asm fild t0_int ; t0 + __asm fild t1_int ; t1 | t0 + __asm fxch st(1) ; t0 | t1 + __asm fstp t0 ; t1 + __asm fst t1 ; (empty) + + __asm fmul p01_minus_p21 ; t1 * p01_minus_p21 + __asm fld t0 ; t0 | t1 * p01_minus_p21 + __asm fmul p11_minus_p21 ; t0 * p11_minus_p21 | t1 * p01_minus_p21 + __asm fld t1 ; t1 | t0 * p11_minus_p21 | t1 * p01_minus_p21 + __asm fmul p00_minus_p20 ; t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21 + __asm fld t0 ; t0 | t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21 + __asm fmul p10_minus_p20 ; t0 * p10_minus_p20 | t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21 + __asm fxch st(2) ; t0 * p11_minus_p21 | t0 * p10_minus_p20 | t1 * p00_minus_p20 | t1 * p01_minus_p21 + __asm fsubp st(3), st ; t0 * p10_minus_p20 | t1 * p00_minus_p20 | t1 * p01_minus_p21 - t0 * p11_minus_p21 + __asm fsubrp st(1), st ; t1 * p00_minus_p20 - t0 * p10_minus_p20 | t1 * p01_minus_p21 - t0 * p11_minus_p21 + __asm fxch st(1) ; t1 * p01_minus_p21 - t0 * p11_minus_p21 | t1 * p00_minus_p20 - t0 * p10_minus_p20 + __asm fmul xstepdenominv ; r_lstepx | t1 * p00_minus_p20 - t0 * p10_minus_p20 + __asm fxch st(1) + __asm fmul ystepdenominv ; r_lstepy | r_lstepx + __asm fxch st(1) ; r_lstepx | r_lstepy + __asm fistp dword ptr [r_tstepx] + __asm fistp dword ptr [r_tstepy] + + /* + t0 = r_p0[5] - r_p2[5]; + t1 = r_p1[5] - r_p2[5]; + r_zistepx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) * + xstepdenominv); + r_zistepy = (int)((t1 * p00_minus_p20 - t0 * p10_minus_p20) * + ystepdenominv); + */ + __asm mov eax, dword ptr [r_p0+20] + __asm mov ebx, dword ptr [r_p1+20] + __asm sub eax, dword ptr [r_p2+20] + __asm sub ebx, dword ptr [r_p2+20] + + __asm mov t0_int, eax + __asm mov t1_int, ebx + __asm fild t0_int ; t0 + __asm fild t1_int ; t1 | t0 + __asm fxch st(1) ; t0 | t1 + __asm fstp t0 ; t1 + __asm fst t1 ; (empty) + + __asm fmul p01_minus_p21 ; t1 * p01_minus_p21 + __asm fld t0 ; t0 | t1 * p01_minus_p21 + __asm fmul p11_minus_p21 ; t0 * p11_minus_p21 | t1 * p01_minus_p21 + __asm fld t1 ; t1 | t0 * p11_minus_p21 | t1 * p01_minus_p21 + __asm fmul p00_minus_p20 ; t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21 + __asm fld t0 ; t0 | t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21 + __asm fmul p10_minus_p20 ; t0 * p10_minus_p20 | t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21 + __asm fxch st(2) ; t0 * p11_minus_p21 | t0 * p10_minus_p20 | t1 * p00_minus_p20 | t1 * p01_minus_p21 + __asm fsubp st(3), st ; t0 * p10_minus_p20 | t1 * p00_minus_p20 | t1 * p01_minus_p21 - t0 * p11_minus_p21 + __asm fsubrp st(1), st ; t1 * p00_minus_p20 - t0 * p10_minus_p20 | t1 * p01_minus_p21 - t0 * p11_minus_p21 + __asm fxch st(1) ; t1 * p01_minus_p21 - t0 * p11_minus_p21 | t1 * p00_minus_p20 - t0 * p10_minus_p20 + __asm fmul xstepdenominv ; r_lstepx | t1 * p00_minus_p20 - t0 * p10_minus_p20 + __asm fxch st(1) + __asm fmul ystepdenominv ; r_lstepy | r_lstepx + __asm fxch st(1) ; r_lstepx | r_lstepy + __asm fistp dword ptr [r_zistepx] + __asm fistp dword ptr [r_zistepy] + + /* +#if id386ALIAS + a_sstepxfrac = r_sstepx << 16; + a_tstepxfrac = r_tstepx << 16; +#else + a_sstepxfrac = r_sstepx & 0xFFFF; + a_tstepxfrac = r_tstepx & 0xFFFF; +#endif + */ + __asm mov eax, d_pdrawspans + __asm cmp eax, offset R_PolysetDrawSpans8_Opaque + __asm mov eax, r_sstepx + __asm mov ebx, r_tstepx + __asm jne translucent +//#if id386ALIAS + __asm shl eax, 16 + __asm shl ebx, 16 + __asm jmp done_with_steps +//#else +translucent: + __asm and eax, 0ffffh + __asm and ebx, 0ffffh +//#endif +done_with_steps: + __asm mov a_sstepxfrac, eax + __asm mov a_tstepxfrac, ebx + + /* + a_ststepxwhole = skinwidth * (r_tstepx >> 16) + (r_sstepx >> 16); + */ + __asm mov ebx, r_tstepx + __asm mov ecx, r_sstepx + __asm sar ebx, 16 + __asm mov eax, skinwidth + __asm mul ebx + __asm sar ecx, 16 + __asm add eax, ecx + __asm mov a_ststepxwhole, eax +} +#else +void R_PolysetCalcGradients (int skinwidth) +{ + float xstepdenominv, ystepdenominv, t0, t1; + float p01_minus_p21, p11_minus_p21, p00_minus_p20, p10_minus_p20; + + p00_minus_p20 = r_p0[0] - r_p2[0]; + p01_minus_p21 = r_p0[1] - r_p2[1]; + p10_minus_p20 = r_p1[0] - r_p2[0]; + p11_minus_p21 = r_p1[1] - r_p2[1]; + + xstepdenominv = 1.0 / (float)d_xdenom; + + ystepdenominv = -xstepdenominv; + +// ceil () for light so positive steps are exaggerated, negative steps +// diminished, pushing us away from underflow toward overflow. Underflow is +// very visible, overflow is very unlikely, because of ambient lighting + t0 = r_p0[4] - r_p2[4]; + t1 = r_p1[4] - r_p2[4]; + r_lstepx = (int) + ceil((t1 * p01_minus_p21 - t0 * p11_minus_p21) * xstepdenominv); + r_lstepy = (int) + ceil((t1 * p00_minus_p20 - t0 * p10_minus_p20) * ystepdenominv); + + t0 = r_p0[2] - r_p2[2]; + t1 = r_p1[2] - r_p2[2]; + r_sstepx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) * + xstepdenominv); + r_sstepy = (int)((t1 * p00_minus_p20 - t0* p10_minus_p20) * + ystepdenominv); + + t0 = r_p0[3] - r_p2[3]; + t1 = r_p1[3] - r_p2[3]; + r_tstepx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) * + xstepdenominv); + r_tstepy = (int)((t1 * p00_minus_p20 - t0 * p10_minus_p20) * + ystepdenominv); + + t0 = r_p0[5] - r_p2[5]; + t1 = r_p1[5] - r_p2[5]; + r_zistepx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) * + xstepdenominv); + r_zistepy = (int)((t1 * p00_minus_p20 - t0 * p10_minus_p20) * + ystepdenominv); + +//#if id386ALIAS +#if id386 + if ( d_pdrawspans == R_PolysetDrawSpans8_Opaque ) + { + a_sstepxfrac = r_sstepx << 16; + a_tstepxfrac = r_tstepx << 16; + } + else +#endif + { +//#else + a_sstepxfrac = r_sstepx & 0xFFFF; + a_tstepxfrac = r_tstepx & 0xFFFF; + } +//#endif + + a_ststepxwhole = skinwidth * (r_tstepx >> 16) + (r_sstepx >> 16); +} +#endif + +/* +================ +R_PolysetDrawThreshSpans8 + +Random fizzle fade rasterizer +================ +*/ +void R_PolysetDrawThreshSpans8 (spanpackage_t *pspanpackage) +{ + int lcount; + byte *lpdest; + byte *lptex; + int lsfrac, ltfrac; + int llight; + int lzi; + short *lpz; + + do + { + lcount = d_aspancount - pspanpackage->count; + + errorterm += erroradjustup; + if (errorterm >= 0) + { + d_aspancount += d_countextrastep; + errorterm -= erroradjustdown; + } + else + { + d_aspancount += ubasestep; + } + + if (lcount) + { + lpdest = pspanpackage->pdest; + lptex = pspanpackage->ptex; + lpz = pspanpackage->pz; + lsfrac = pspanpackage->sfrac; + ltfrac = pspanpackage->tfrac; + llight = pspanpackage->light; + lzi = pspanpackage->zi; + + do + { + if ((lzi >> 16) >= *lpz) + { + rand1k_index = (rand1k_index + 1) & MASK_1K; + + /*if (rand1k[rand1k_index] <= r_affinetridesc.vis_thresh) + { + *lpdest = ((byte *)vid.colormap)[*lptex + (llight & 0xFF00)]; + *lpz = lzi >> 16; + }*/ + } + + lpdest++; + lzi += r_zistepx; + lpz++; + llight += r_lstepx; + lptex += a_ststepxwhole; + lsfrac += a_sstepxfrac; + lptex += lsfrac >> 16; + lsfrac &= 0xFFFF; + ltfrac += a_tstepxfrac; + if (ltfrac & 0x10000) + { + lptex += r_affinetridesc.skinwidth; + ltfrac &= 0xFFFF; + } + } while (--lcount); + } + + pspanpackage++; + } while (pspanpackage->count != -999999); +} + + +/* +================ +R_PolysetDrawSpans8 +================ +*/ +void R_PolysetDrawSpans8_33( spanpackage_t *pspanpackage) +{ + int lcount; + byte *lpdest; + byte *lptex; + int lsfrac, ltfrac; + int llight; + int lzi; + short *lpz; + + do + { + lcount = d_aspancount - pspanpackage->count; + + errorterm += erroradjustup; + if (errorterm >= 0) + { + d_aspancount += d_countextrastep; + errorterm -= erroradjustdown; + } + else + { + d_aspancount += ubasestep; + } + + if (lcount) + { + lpdest = pspanpackage->pdest; + lptex = pspanpackage->ptex; + lpz = pspanpackage->pz; + lsfrac = pspanpackage->sfrac; + ltfrac = pspanpackage->tfrac; + llight = pspanpackage->light; + lzi = pspanpackage->zi; + + do + { + if ((lzi >> 16) >= *lpz) + { + int temp = vid.colormap[*lptex + ( llight & 0xFF00 )]; + + *lpdest = vid.alphamap[temp+ *lpdest*256]; + } + lpdest++; + lzi += r_zistepx; + lpz++; + llight += r_lstepx; + lptex += a_ststepxwhole; + lsfrac += a_sstepxfrac; + lptex += lsfrac >> 16; + lsfrac &= 0xFFFF; + ltfrac += a_tstepxfrac; + if (ltfrac & 0x10000) + { + lptex += r_affinetridesc.skinwidth; + ltfrac &= 0xFFFF; + } + } while (--lcount); + } + + pspanpackage++; + } while (pspanpackage->count != -999999); +} + +void R_PolysetDrawSpansConstant8_33( spanpackage_t *pspanpackage) +{ + int lcount; + byte *lpdest; + int lzi; + short *lpz; + + do + { + lcount = d_aspancount - pspanpackage->count; + + errorterm += erroradjustup; + if (errorterm >= 0) + { + d_aspancount += d_countextrastep; + errorterm -= erroradjustdown; + } + else + { + d_aspancount += ubasestep; + } + + if (lcount) + { + lpdest = pspanpackage->pdest; + lpz = pspanpackage->pz; + lzi = pspanpackage->zi; + + do + { + if ((lzi >> 16) >= *lpz) + { + *lpdest = vid.alphamap[r_aliasblendcolor + *lpdest*256]; + } + lpdest++; + lzi += r_zistepx; + lpz++; + } while (--lcount); + } + + pspanpackage++; + } while (pspanpackage->count != -999999); +} + +void R_PolysetDrawSpans8_66(spanpackage_t *pspanpackage) +{ + int lcount; + byte *lpdest; + byte *lptex; + int lsfrac, ltfrac; + int llight; + int lzi; + short *lpz; + + do + { + lcount = d_aspancount - pspanpackage->count; + + errorterm += erroradjustup; + if (errorterm >= 0) + { + d_aspancount += d_countextrastep; + errorterm -= erroradjustdown; + } + else + { + d_aspancount += ubasestep; + } + + if (lcount) + { + lpdest = pspanpackage->pdest; + lptex = pspanpackage->ptex; + lpz = pspanpackage->pz; + lsfrac = pspanpackage->sfrac; + ltfrac = pspanpackage->tfrac; + llight = pspanpackage->light; + lzi = pspanpackage->zi; + + do + { + if ((lzi >> 16) >= *lpz) + { + int temp = vid.colormap[*lptex + ( llight & 0xFF00 )]; + + *lpdest = vid.alphamap[temp*256 + *lpdest]; + *lpz = lzi >> 16; + } + lpdest++; + lzi += r_zistepx; + lpz++; + llight += r_lstepx; + lptex += a_ststepxwhole; + lsfrac += a_sstepxfrac; + lptex += lsfrac >> 16; + lsfrac &= 0xFFFF; + ltfrac += a_tstepxfrac; + if (ltfrac & 0x10000) + { + lptex += r_affinetridesc.skinwidth; + ltfrac &= 0xFFFF; + } + } while (--lcount); + } + + pspanpackage++; + } while (pspanpackage->count != -999999); +} + +void R_PolysetDrawSpansConstant8_66( spanpackage_t *pspanpackage) +{ + int lcount; + byte *lpdest; + int lzi; + short *lpz; + + do + { + lcount = d_aspancount - pspanpackage->count; + + errorterm += erroradjustup; + if (errorterm >= 0) + { + d_aspancount += d_countextrastep; + errorterm -= erroradjustdown; + } + else + { + d_aspancount += ubasestep; + } + + if (lcount) + { + lpdest = pspanpackage->pdest; + lpz = pspanpackage->pz; + lzi = pspanpackage->zi; + + do + { + if ((lzi >> 16) >= *lpz) + { + *lpdest = vid.alphamap[r_aliasblendcolor*256 + *lpdest]; + } + lpdest++; + lzi += r_zistepx; + lpz++; + } while (--lcount); + } + + pspanpackage++; + } while (pspanpackage->count != -999999); +} + +#if !id386 +void R_PolysetDrawSpans8_Opaque (spanpackage_t *pspanpackage) +{ + int lcount; + + do + { + lcount = d_aspancount - pspanpackage->count; + + errorterm += erroradjustup; + if (errorterm >= 0) + { + d_aspancount += d_countextrastep; + errorterm -= erroradjustdown; + } + else + { + d_aspancount += ubasestep; + } + + if (lcount) + { + int lsfrac, ltfrac; + byte *lpdest; + byte *lptex; + int llight; + int lzi; + short *lpz; + + lpdest = pspanpackage->pdest; + lptex = pspanpackage->ptex; + lpz = pspanpackage->pz; + lsfrac = pspanpackage->sfrac; + ltfrac = pspanpackage->tfrac; + llight = pspanpackage->light; + lzi = pspanpackage->zi; + + do + { + if ((lzi >> 16) >= *lpz) + { +//PGM + /*if(r_newrefdef.rdflags & RDF_IRGOGGLES && RI.currententity->flags & RF_IR_VISIBLE) + *lpdest = ((byte *)vid.colormap)[irtable[*lptex]]; + else*/ + *lpdest = ((byte *)vid.colormap)[*lptex + (llight & 0xFF00)]; +//PGM + *lpz = lzi >> 16; + } + lpdest++; + lzi += r_zistepx; + lpz++; + llight += r_lstepx; + lptex += a_ststepxwhole; + lsfrac += a_sstepxfrac; + lptex += lsfrac >> 16; + lsfrac &= 0xFFFF; + ltfrac += a_tstepxfrac; + if (ltfrac & 0x10000) + { + lptex += r_affinetridesc.skinwidth; + ltfrac &= 0xFFFF; + } + } while (--lcount); + } + + pspanpackage++; + } while (pspanpackage->count != -999999); +} +#endif + +#if 0 +/* +================ +R_PolysetFillSpans8 +================ +*/ +void R_PolysetFillSpans8 (spanpackage_t *pspanpackage) +{ + int color; + +// FIXME: do z buffering + + color = d_aflatcolor++; + + while (1) + { + int lcount; + byte *lpdest; + + lcount = pspanpackage->count; + + if (lcount == -1) + return; + + if (lcount) + { + lpdest = pspanpackage->pdest; + + do + { + *lpdest++ = color; + } while (--lcount); + } + + pspanpackage++; + } +} +#else +void R_PolysetFillSpans8 (spanpackage_t *pspanpackage) +{ + int color; + int lcount; +// FIXME: do z buffering + + color = d_aflatcolor+= 100; + + do + { + lcount = d_aspancount - pspanpackage->count; + + errorterm += erroradjustup; + if (errorterm >= 0) + { + d_aspancount += d_countextrastep; + errorterm -= erroradjustdown; + } + else + { + d_aspancount += ubasestep; + } + + if (lcount) + { + int lsfrac, ltfrac; + pixel_t *lpdest; + byte *lptex; + int llight; + int lzi; + short *lpz; + + lpdest = pspanpackage->pdest; + lptex = pspanpackage->ptex; + lpz = pspanpackage->pz; + lsfrac = pspanpackage->sfrac; + ltfrac = pspanpackage->tfrac; + llight = pspanpackage->light; + lzi = pspanpackage->zi; + + do + { + if ((lzi >> 16) >= *lpz) + { +//PGM + /*if(r_newrefdef.rdflags & RDF_IRGOGGLES && RI.currententity->flags & RF_IR_VISIBLE) + *lpdest = ((byte *)vid.colormap)[irtable[*lptex]]; + else*/ + *lpdest = color; //((byte *)vid.colormap)[*lptex + (llight & 0xFF00)]; +//PGM + *lpz = lzi >> 16; + } + lpdest++; + lzi += r_zistepx; + lpz++; + llight += r_lstepx; + lptex += a_ststepxwhole; + lsfrac += a_sstepxfrac; + lptex += lsfrac >> 16; + lsfrac &= 0xFFFF; + ltfrac += a_tstepxfrac; + if (ltfrac & 0x10000) + { + lptex += r_affinetridesc.skinwidth; + ltfrac &= 0xFFFF; + } + } while (--lcount); + } + + pspanpackage++; + } while (pspanpackage->count != -999999); +} +#endif +/* +================ +R_RasterizeAliasPolySmooth +================ +*/ +void R_RasterizeAliasPolySmooth (void) +{ + int initialleftheight, initialrightheight; + int *plefttop, *prighttop, *pleftbottom, *prightbottom; + int working_lstepx, originalcount; + + plefttop = pedgetable->pleftedgevert0; + prighttop = pedgetable->prightedgevert0; + + pleftbottom = pedgetable->pleftedgevert1; + prightbottom = pedgetable->prightedgevert1; + + initialleftheight = pleftbottom[1] - plefttop[1]; + initialrightheight = prightbottom[1] - prighttop[1]; + +// +// set the s, t, and light gradients, which are consistent across the triangle +// because being a triangle, things are affine +// + R_PolysetCalcGradients (r_affinetridesc.skinwidth); +// +// rasterize the polygon +// + +// +// scan out the top (and possibly only) part of the left edge +// + d_pedgespanpackage = a_spans; + + ystart = plefttop[1]; + d_aspancount = plefttop[0] - prighttop[0]; + + d_ptex = (byte *)r_affinetridesc.pskin + (plefttop[2] >> 16) + + (plefttop[3] >> 16) * r_affinetridesc.skinwidth; +//#if id386ALIAS +#if id386 + if ( d_pdrawspans == R_PolysetDrawSpans8_Opaque ) + { + d_sfrac = (plefttop[2] & 0xFFFF) << 16; + d_tfrac = (plefttop[3] & 0xFFFF) << 16; + } +//#else + else +#endif + { + d_sfrac = plefttop[2] & 0xFFFF; + d_tfrac = plefttop[3] & 0xFFFF; + } +//#endif + d_light = plefttop[4]; + d_zi = plefttop[5]; + + d_pdest = (pixel_t *)d_viewbuffer + + ystart * r_screenwidth + plefttop[0]; + d_pz = d_pzbuffer + ystart * d_zwidth + plefttop[0]; + + if (initialleftheight == 1) + { + d_pedgespanpackage->pdest = d_pdest; + d_pedgespanpackage->pz = d_pz; + d_pedgespanpackage->count = d_aspancount; + d_pedgespanpackage->ptex = d_ptex; + + d_pedgespanpackage->sfrac = d_sfrac; + d_pedgespanpackage->tfrac = d_tfrac; + + // FIXME: need to clamp l, s, t, at both ends? + d_pedgespanpackage->light = d_light; + d_pedgespanpackage->zi = d_zi; + + d_pedgespanpackage++; + } + else + { + R_PolysetSetUpForLineScan(plefttop[0], plefttop[1], + pleftbottom[0], pleftbottom[1]); + +//#if id386ALIAS +#if id386 + if ( d_pdrawspans == R_PolysetDrawSpans8_Opaque ) + { + d_pzbasestep = (d_zwidth + ubasestep) << 1; + d_pzextrastep = d_pzbasestep + 2; + } +//#else + else +#endif + { + d_pzbasestep = d_zwidth + ubasestep; + d_pzextrastep = d_pzbasestep + 1; + } +//#endif + + d_pdestbasestep = r_screenwidth + ubasestep; + d_pdestextrastep = d_pdestbasestep + 1; + + // TODO: can reuse partial expressions here + + // for negative steps in x along left edge, bias toward overflow rather than + // underflow (sort of turning the floor () we did in the gradient calcs into + // ceil (), but plus a little bit) + if (ubasestep < 0) + working_lstepx = r_lstepx - 1; + else + working_lstepx = r_lstepx; + + d_countextrastep = ubasestep + 1; + d_ptexbasestep = ((r_sstepy + r_sstepx * ubasestep) >> 16) + + ((r_tstepy + r_tstepx * ubasestep) >> 16) * + r_affinetridesc.skinwidth; +//#if id386ALIAS +#if id386 + if ( d_pdrawspans == R_PolysetDrawSpans8_Opaque ) + { + d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) << 16; + d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) << 16; + } + else +#endif + { +//#else + d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) & 0xFFFF; + d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) & 0xFFFF; + } +//#endif + d_lightbasestep = r_lstepy + working_lstepx * ubasestep; + d_zibasestep = r_zistepy + r_zistepx * ubasestep; + + d_ptexextrastep = ((r_sstepy + r_sstepx * d_countextrastep) >> 16) + + ((r_tstepy + r_tstepx * d_countextrastep) >> 16) * + r_affinetridesc.skinwidth; +//#if id386ALIAS +#if id386 + if ( d_pdrawspans == R_PolysetDrawSpans8_Opaque ) + { + d_sfracextrastep = (r_sstepy + r_sstepx*d_countextrastep) << 16; + d_tfracextrastep = (r_tstepy + r_tstepx*d_countextrastep) << 16; + } + else +#endif + { +//#else + d_sfracextrastep = (r_sstepy + r_sstepx*d_countextrastep) & 0xFFFF; + d_tfracextrastep = (r_tstepy + r_tstepx*d_countextrastep) & 0xFFFF; + } +//#endif + d_lightextrastep = d_lightbasestep + working_lstepx; + d_ziextrastep = d_zibasestep + r_zistepx; + +#if id386 + if ( d_pdrawspans == R_PolysetDrawSpans8_Opaque ) + { + R_PolysetScanLeftEdge (initialleftheight); + } + else +#endif + { + R_PolysetScanLeftEdge_C(initialleftheight); + } + } + +// +// scan out the bottom part of the left edge, if it exists +// + if (pedgetable->numleftedges == 2) + { + int height; + + plefttop = pleftbottom; + pleftbottom = pedgetable->pleftedgevert2; + + height = pleftbottom[1] - plefttop[1]; + +// TODO: make this a function; modularize this function in general + + ystart = plefttop[1]; + d_aspancount = plefttop[0] - prighttop[0]; + d_ptex = (byte *)r_affinetridesc.pskin + (plefttop[2] >> 16) + + (plefttop[3] >> 16) * r_affinetridesc.skinwidth; + d_sfrac = 0; + d_tfrac = 0; + d_light = plefttop[4]; + d_zi = plefttop[5]; + + d_pdest = (pixel_t *)d_viewbuffer + ystart * r_screenwidth + plefttop[0]; + d_pz = d_pzbuffer + ystart * d_zwidth + plefttop[0]; + + if (height == 1) + { + d_pedgespanpackage->pdest = d_pdest; + d_pedgespanpackage->pz = d_pz; + d_pedgespanpackage->count = d_aspancount; + d_pedgespanpackage->ptex = d_ptex; + + d_pedgespanpackage->sfrac = d_sfrac; + d_pedgespanpackage->tfrac = d_tfrac; + + // FIXME: need to clamp l, s, t, at both ends? + d_pedgespanpackage->light = d_light; + d_pedgespanpackage->zi = d_zi; + + d_pedgespanpackage++; + } + else + { + R_PolysetSetUpForLineScan(plefttop[0], plefttop[1], + pleftbottom[0], pleftbottom[1]); + + d_pdestbasestep = r_screenwidth + ubasestep; + d_pdestextrastep = d_pdestbasestep + 1; + +//#if id386ALIAS +#if id386 + if ( d_pdrawspans == R_PolysetDrawSpans8_Opaque ) + { + d_pzbasestep = (d_zwidth + ubasestep) << 1; + d_pzextrastep = d_pzbasestep + 2; + } +//#else + else +#endif + { + d_pzbasestep = d_zwidth + ubasestep; + d_pzextrastep = d_pzbasestep + 1; + } +//#endif + + if (ubasestep < 0) + working_lstepx = r_lstepx - 1; + else + working_lstepx = r_lstepx; + + d_countextrastep = ubasestep + 1; + d_ptexbasestep = ((r_sstepy + r_sstepx * ubasestep) >> 16) + + ((r_tstepy + r_tstepx * ubasestep) >> 16) * + r_affinetridesc.skinwidth; +//#if id386ALIAS +#if id386 + if ( d_pdrawspans == R_PolysetDrawSpans8_Opaque ) + { + d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) << 16; + d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) << 16; + } +//#else + else +#endif + { + d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) & 0xFFFF; + d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) & 0xFFFF; + } +//#endif + d_lightbasestep = r_lstepy + working_lstepx * ubasestep; + d_zibasestep = r_zistepy + r_zistepx * ubasestep; + + d_ptexextrastep = ((r_sstepy + r_sstepx * d_countextrastep) >> 16) + + ((r_tstepy + r_tstepx * d_countextrastep) >> 16) * + r_affinetridesc.skinwidth; +//#if id386ALIAS +#if id386 + if ( d_pdrawspans == R_PolysetDrawSpans8_Opaque ) + { + d_sfracextrastep = ((r_sstepy+r_sstepx*d_countextrastep) & 0xFFFF)<<16; + d_tfracextrastep = ((r_tstepy+r_tstepx*d_countextrastep) & 0xFFFF)<<16; + } + else +#endif +//#endif + { + d_sfracextrastep = (r_sstepy+r_sstepx*d_countextrastep) & 0xFFFF; + d_tfracextrastep = (r_tstepy+r_tstepx*d_countextrastep) & 0xFFFF; + } +//#endif + d_lightextrastep = d_lightbasestep + working_lstepx; + d_ziextrastep = d_zibasestep + r_zistepx; + +#if id386 + if ( d_pdrawspans == R_PolysetDrawSpans8_Opaque ) + { + R_PolysetScanLeftEdge (height); + } + else +#endif + { + R_PolysetScanLeftEdge_C(height); + } + } + } + +// scan out the top (and possibly only) part of the right edge, updating the +// count field + d_pedgespanpackage = a_spans; + + R_PolysetSetUpForLineScan(prighttop[0], prighttop[1], + prightbottom[0], prightbottom[1]); + d_aspancount = 0; + d_countextrastep = ubasestep + 1; + originalcount = a_spans[initialrightheight].count; + a_spans[initialrightheight].count = -999999; // mark end of the spanpackages + (*d_pdrawspans) (a_spans); + +// scan out the bottom part of the right edge, if it exists + if (pedgetable->numrightedges == 2) + { + int height; + spanpackage_t *pstart; + + pstart = a_spans + initialrightheight; + pstart->count = originalcount; + + d_aspancount = prightbottom[0] - prighttop[0]; + + prighttop = prightbottom; + prightbottom = pedgetable->prightedgevert2; + + height = prightbottom[1] - prighttop[1]; + + R_PolysetSetUpForLineScan(prighttop[0], prighttop[1], + prightbottom[0], prightbottom[1]); + + d_countextrastep = ubasestep + 1; + a_spans[initialrightheight + height].count = -999999; + // mark end of the spanpackages + (*d_pdrawspans) (pstart); + } +} + + +/* +================ +R_PolysetSetEdgeTable +================ +*/ +void R_PolysetSetEdgeTable (void) +{ + int edgetableindex; + + edgetableindex = 0; // assume the vertices are already in + // top to bottom order + +// +// determine which edges are right & left, and the order in which +// to rasterize them +// + if (r_p0[1] >= r_p1[1]) + { + if (r_p0[1] == r_p1[1]) + { + if (r_p0[1] < r_p2[1]) + pedgetable = &edgetables[2]; + else + pedgetable = &edgetables[5]; + + return; + } + else + { + edgetableindex = 1; + } + } + + if (r_p0[1] == r_p2[1]) + { + if (edgetableindex) + pedgetable = &edgetables[8]; + else + pedgetable = &edgetables[9]; + + return; + } + else if (r_p1[1] == r_p2[1]) + { + if (edgetableindex) + pedgetable = &edgetables[10]; + else + pedgetable = &edgetables[11]; + + return; + } + + if (r_p0[1] > r_p2[1]) + edgetableindex += 2; + + if (r_p1[1] > r_p2[1]) + edgetableindex += 4; + + pedgetable = &edgetables[edgetableindex]; +} + + diff --git a/r_trialias.c b/r_trialias.c new file mode 100644 index 00000000..5616da31 --- /dev/null +++ b/r_trialias.c @@ -0,0 +1,229 @@ +#include "r_local.h" + +// not really draw alias models here, but use this to draw triangles + +int r_amodels_drawn; + +affinetridesc_t r_affinetridesc; + +vec3_t r_plightvec; +vec3_t r_lerped[1024]; +vec3_t r_lerp_frontv, r_lerp_backv, r_lerp_move; + +int r_ambientlight; +int r_aliasblendcolor; +float r_shadelight; + + +float aliastransform[3][4]; +float aliasworldtransform[3][4]; +float aliasoldworldtransform[3][4]; + +static float s_ziscale; +static vec3_t s_alias_forward, s_alias_right, s_alias_up; + + +#define NUMVERTEXNORMALS 162 + +float r_avertexnormals[NUMVERTEXNORMALS][3] = { +#include "anorms.h" +}; + + +void R_AliasSetUpTransform (void); +void R_AliasTransformVector (vec3_t in, vec3_t out, float m[3][4] ); +void R_AliasProjectAndClipTestFinalVert (finalvert_t *fv); + +void R_AliasTransformFinalVerts( int numpoints, finalvert_t *fv, dtrivertx_t *oldv, dtrivertx_t *newv ); + + +/* +================ +R_AliasCheckBBox +================ +*/ +typedef struct { + int index0; + int index1; +} aedge_t; + +static aedge_t aedges[12] = { +{0, 1}, {1, 2}, {2, 3}, {3, 0}, +{4, 5}, {5, 6}, {6, 7}, {7, 4}, +{0, 5}, {1, 4}, {2, 7}, {3, 6} +}; + +#define BBOX_TRIVIAL_ACCEPT 0 +#define BBOX_MUST_CLIP_XY 1 +#define BBOX_MUST_CLIP_Z 2 +#define BBOX_TRIVIAL_REJECT 8 + + +/* +================ +R_AliasTransformVector +================ +*/ +void R_AliasTransformVector(vec3_t in, vec3_t out, float xf[3][4] ) +{ + out[0] = DotProduct(in, xf[0]) + xf[0][3]; + out[1] = DotProduct(in, xf[1]) + xf[1][3]; + out[2] = DotProduct(in, xf[2]) + xf[2][3]; +} + +void VectorInverse (vec3_t v) +{ + v[0] = -v[0]; + v[1] = -v[1]; + v[2] = -v[2]; +} + +/* +================ +R_AliasSetUpTransform +================ +*/ +void R_AliasSetUpTransform (void) +{ + int i; + static float viewmatrix[3][4]; + vec3_t angles; + +// TODO: should really be stored with the entity instead of being reconstructed +// TODO: should use a look-up table +// TODO: could cache lazily, stored in the entity +// + + s_ziscale = (float)0x8000 * (float)0x10000; + angles[ROLL] = RI.currententity->angles[ROLL]; + angles[PITCH] = RI.currententity->angles[PITCH]; + angles[YAW] = RI.currententity->angles[YAW]; + AngleVectors( angles, s_alias_forward, s_alias_right, s_alias_up ); + +// TODO: can do this with simple matrix rearrangement + + memset( aliasworldtransform, 0, sizeof( aliasworldtransform ) ); + memset( aliasoldworldtransform, 0, sizeof( aliasworldtransform ) ); + + for (i=0 ; i<3 ; i++) + { + aliasoldworldtransform[i][0] = aliasworldtransform[i][0] = s_alias_forward[i]; + aliasoldworldtransform[i][0] = aliasworldtransform[i][1] = -s_alias_right[i]; + aliasoldworldtransform[i][0] = aliasworldtransform[i][2] = s_alias_up[i]; + } + + aliasworldtransform[0][3] = RI.currententity->origin[0]-r_origin[0]; + aliasworldtransform[1][3] = RI.currententity->origin[1]-r_origin[1]; + aliasworldtransform[2][3] = RI.currententity->origin[2]-r_origin[2]; + + //aliasoldworldtransform[0][3] = RI.currententity->oldorigin[0]-r_origin[0]; + //aliasoldworldtransform[1][3] = RI.currententity->oldorigin[1]-r_origin[1]; + //aliasoldworldtransform[2][3] = RI.currententity->oldorigin[2]-r_origin[2]; + +// FIXME: can do more efficiently than full concatenation +// memcpy( rotationmatrix, t2matrix, sizeof( rotationmatrix ) ); + +// R_ConcatTransforms (t2matrix, tmatrix, rotationmatrix); + +// TODO: should be global, set when vright, etc., set + VectorCopy (vright, viewmatrix[0]); + VectorCopy (vup, viewmatrix[1]); + VectorInverse (viewmatrix[1]); + //VectorScale(viewmatrix[1], -1, viewmatrix[1]); + VectorCopy (vpn, viewmatrix[2]); + + viewmatrix[0][3] = 0; + viewmatrix[1][3] = 0; + viewmatrix[2][3] = 0; + +// memcpy( aliasworldtransform, rotationmatrix, sizeof( aliastransform ) ); + + R_ConcatTransforms (viewmatrix, aliasworldtransform, aliastransform); + + aliasworldtransform[0][3] = RI.currententity->origin[0]; + aliasworldtransform[1][3] = RI.currententity->origin[1]; + aliasworldtransform[2][3] = RI.currententity->origin[2]; + + //aliasoldworldtransform[0][3] = RI.currententity->oldorigin[0]; + //aliasoldworldtransform[1][3] = RI.currententity->oldorigin[1]; + //aliasoldworldtransform[2][3] = RI.currententity->oldorigin[2]; +} + +/* +================ +R_AliasProjectAndClipTestFinalVert +================ +*/ +void R_AliasProjectAndClipTestFinalVert( finalvert_t *fv ) +{ + float zi; + float x, y, z; + + // project points + x = fv->xyz[0]; + y = fv->xyz[1]; + z = fv->xyz[2]; + zi = 1.0 / z; + + fv->zi = zi * s_ziscale; + + fv->u = (x * aliasxscale * zi) + aliasxcenter; + fv->v = (y * aliasyscale * zi) + aliasycenter; + + if (fv->u < RI.aliasvrect.x) + fv->flags |= ALIAS_LEFT_CLIP; + if (fv->v < RI.aliasvrect.y) + fv->flags |= ALIAS_TOP_CLIP; + if (fv->u > RI.aliasvrectright) + fv->flags |= ALIAS_RIGHT_CLIP; + if (fv->v > RI.aliasvrectbottom) + fv->flags |= ALIAS_BOTTOM_CLIP; +} + +void R_SetupFinalVert( finalvert_t *fv, float x, float y, float z, int light, int s, int t ) +{ + vec3_t v = {x, y, z}; + + fv->xyz[0] = DotProduct(v, aliastransform[0]) + aliastransform[0][3]; + fv->xyz[1] = DotProduct(v, aliastransform[1]) + aliastransform[1][3]; + fv->xyz[2] = DotProduct(v, aliastransform[2]) + aliastransform[2][3]; + + fv->flags = 0; + + fv->l = light; + + if ( fv->xyz[2] < ALIAS_Z_CLIP_PLANE ) + { + fv->flags |= ALIAS_Z_CLIP; + } + else + { + R_AliasProjectAndClipTestFinalVert( fv ); + } + + fv->s = s << 16; + fv->t = t << 16; +} + +void R_RenderTriangle( finalvert_t *pfv ) +{ + + if ( pfv[0].flags & pfv[1].flags & pfv[2].flags ) + return ; // completely clipped + + if ( ! (pfv[0].flags | pfv[1].flags | pfv[2].flags) ) + { // totally unclipped + aliastriangleparms.a = &pfv[0]; + aliastriangleparms.b = &pfv[1]; + aliastriangleparms.c = &pfv[2]; + + R_DrawTriangle(); + } + else + { // partially clipped + R_AliasClipTriangle (&pfv[0], &pfv[1], &pfv[2]); + } +} + + +