2bd8f7644dd5421a5cd1af50a5e1f106d15b8f69
[mercenary-reloaded.git] / src / mercenary / render.c
1 /* render routines that replaces the game rendering with modern rendering
2  *
3  * (C) 2018 by Andreas Eversberg <jolly@eversberg.eu>
4  * All Rights Reserved
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include <stdio.h>
21 #include <stdint.h>
22 #include <stdlib.h>
23 #include <math.h>
24 #include "../libcpu/m68k.h"
25 #include "../libcpu/execute.h"
26 #include "mercenary.h"
27
28 #define OBJECT_COORD_MAX 256
29 static int object_coord_valid; /* set, if the coordinates below are valid */
30 static int object_coord_num;
31 static int object_coord_x[OBJECT_COORD_MAX];
32 static int object_coord_y[OBJECT_COORD_MAX];
33 static int object_coord_z[OBJECT_COORD_MAX];
34
35 /* rendering starts, initialize variables */
36 void render_start(void)
37 {
38         object_coord_valid = 0;
39 }
40
41 /* parse object's coordinates, rotate them and store them */
42 static void parse_object(void)
43 {
44 #if 0
45 #warning tbd: handling in 540D2
46         int16_t r;
47         double roll, pitch, yaw;
48         uint32_t address;
49         int16_t word_x, word_y, word_z;
50         double  x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4;
51
52         if (object_coord_valid) {
53                 fprintf(stderr, "Coodinates are valid, because previous object did not render, please fix!\n");
54                 return;
55         }
56
57         /* get observer's tilt, pitch, yaw */
58         r = (int16_t)(m68k_read_memory_16(0x530c+0x1E46) & 0x1ff);
59         roll = (double)r / 512.0 * 2 * M_PI;
60         r = (int16_t)((m68k_read_memory_16(0x530c+0x1E48) + 0x200) & 0x1ff);
61         pitch = (double)r / 512.0 * 2 * M_PI;
62         r = (int16_t)((m68k_read_memory_16(0x530c+0x1E4a) + 0x200) & 0x1ff);
63         yaw = (double)r / 512.0 * 2 * M_PI;
64
65         /* get address that points to object vertices */
66         address = mercenary_object_vertex_register;
67
68         /* parse object, see M3 code at 0x540a6 */
69 word_x = (int8_t)0xff;
70 printf("testing %x, %d (should be extended to -1 as a word)\n", word_x, word_x);
71 word_x = (int8_t)0xf1;
72 printf("testing %x, %d (should be extended to -15 as a word)\n", word_x, word_x);
73 word_x = (int8_t)0x80;
74 printf("check value: %x (should be 0x80)\n", (uint8_t)word_x);
75 exit(0);
76 tbd: wie werden die koordinaten mit der objektposition translatiert?:
77         object_coord_num = 0;
78         while(42) {
79                 word_x = (int8_t)m68k_read_memory_8(address);
80                 address += 1;
81                 /* check for 8 bit or 16 bit coordinate using this magic */
82                 if ((uint8_t)word_x != 0x80) {
83                         /* we have an 8 bit coordinate */
84                         word_y = (int8_t)m68k_read_memory_8(address);
85                         address += 1;
86                         word_z = (int8_t)m68k_read_memory_8(address);
87                         address += 1;
88                 } else {
89                         /* we have an 16 bit coordinate, make address word align */
90                         if ((address & 1))
91                                 address++;
92                         word_x = (int16_t)m68k_read_memory_16(address);
93                         address += 2;
94                         /* done if we get this magic */
95                         if ((uint16_t)word_x == 0x8000)
96                                 break;
97                         word_y = (int16_t)m68k_read_memory_16(address);
98                         address += 2;
99                         word_z = (int16_t)m68k_read_memory_16(address);
100                         address += 2;
101                 }
102
103                 /* check if too many coordinates */
104                 if (object_coord_num == OBJECT_COORD_MAX) {
105                         fprintf(stderr, "object has too many coordinates, please fix!\n");
106                         return;
107                 }
108
109                 /* convert to double */
110                 x1 = (double)word_x;
111                 y1 = (double)word_y;
112                 z1 = (double)word_z;
113
114                 /* rotate roll (tilt head to the right) */
115                 x2 = x1 * cos(roll) - y1 * sin(roll);
116                 y2 = x1 * sin(roll) + y1 * cos(roll);
117                 z2 = z1;
118
119                 /* rotate head (pitch down) */
120                 y3 = y2 * cos(pitch) - z2 * sin(pitch);
121                 z3 = y2 * sin(pitch) + z2 * cos(pitch);
122                 x3 = x2;
123
124                 /* rotate yaw (turn right) */
125                 z4 = z3 * cos(yaw) - x3 * sin(yaw);
126                 x4 = z3 * sin(yaw) + x3 * cos(yaw);
127                 y4 = y3;
128
129                 /* store vertices as float */
130                 object_coord_x[object_coord_num] = x4;
131                 object_coord_y[object_coord_num] = y4;
132                 object_coord_z[object_coord_num] = z4;
133         }
134
135         /* we are done, coordinates are valid */
136         object_coord_valid = 1;
137 #endif
138 }
139
140 void render_polygons(void)
141 {
142 #if 0
143 #warning beim polygon auf object_coord_num checken
144         if (!object_coord_valid) {
145                 print failure, if coords not valid!!
146                 return;
147         }
148
149
150         render..
151
152
153
154         /* done with rendering, mark coordinates as beeing invalid */
155         object_coord_valid = 0;
156 #endif
157 }
158
159 /* stop event from CPU received */
160 void render_improved_event(int event)
161 {
162         switch (event) {
163         case STOP_AT_PARSE_OBJECT:
164                 parse_object();
165                 break;
166         case STOP_AT_RENDER_POLYGONS:
167                 render_polygons();
168                 break;
169         }
170 }