2 * Tiny Universe Simulator
3 * By John Hodge (thePowersGang)
5 * visualise.c - Displays a visual representation of the universe
14 //#define VIEW_ALGO all
17 #define VIEW_AVG_SCALE 3
27 void Visualiser_GetBounds(void);
28 void Visualiser_FillBuffers(void);
29 void Visualiser_Render(void);
32 int giVisualiserPxWidth = 800;
33 int giVisualiserPxHeight = 600;
34 tPixel gVisualiser_MaxPixelVals;
35 int giVisualiser_MinCharge = 0;
36 tPixel *gVisualiserBuffer;
37 tVector gVisualiserBase;
38 tVector gVisualiserSize;
39 tMatrix gVisualiserView;
40 tLargeInt gVisualiserMaxMass;
41 tLargeInt gVisualiserMaxCharge;
44 void Visualiser_Initialise(void)
46 Matrix_SetIdentity(&gVisualiserView);
47 gVisualiserBuffer = malloc( giVisualiserPxWidth*giVisualiserPxHeight*sizeof(tPixel) );
48 Video_SetResolution( giVisualiserPxWidth, giVisualiserPxHeight );
51 void Visualiser_Update(void)
53 Visualiser_GetBounds();
54 Visualiser_FillBuffers();
59 * \brief Scan all particles and get the populated volume
61 void Visualiser_GetBounds(void)
67 // Average Distance around Average Position
68 // - Far less volatile than ViewAll
69 tVector avg, tmp, distV;
74 LargeInt_SetNative(&numPart, giNumParticles, 0);
76 // Get the average position
77 for( i = 0; i < giNumParticles; i++ )
79 Vector_Add(&avg, &gpParticles[i].Location);
81 if( LargeInt_Compare(&gVisualiserMaxMass, &gpParticles[i].Mass) < 0 )
82 LargeInt_Set(&gVisualiserMaxMass, &gpParticles[i].Mass);
84 if( LargeInt_Compare(&gVisualiserMaxCharge, &gpParticles[i].Charge) < 0 )
85 LargeInt_Set(&gVisualiserMaxCharge, &gpParticles[i].Charge);
87 Vector_DivScalar(&avg, &numPart);
88 // Get the average distance from that position
89 for( i = 0; i < giNumParticles; i++ )
91 Vector_Set(&tmp, &gpParticles[i].Location);
92 Vector_Sub(&tmp, &avg);
94 Vector_Add(&distV, &tmp);
96 //LargeInt_Div(&dist, NULL, &dist, &numPart);
97 LargeInt_DivNative(&numPart, NULL, &numPart, VIEW_AVG_SCALE);
98 Vector_DivScalar(&distV, &numPart);
100 //for( i = 0; i < VECTOR_COMPONENTS; i ++ )
101 // LargeInt_Set(&distV.C[0], &dist);
103 Vector_Set(&min, &avg);
104 Vector_Sub(&min, &distV);
105 Vector_Set(&max, &avg);
106 Vector_Add(&max, &distV);
110 // - Ensures that all particles are on screen at the same time
112 Vector_Set(&max, &gpParticles[0].Location);
113 Vector_Set(&min, &gpParticles[0].Location);
114 //Vector_Zero(&min); Vector_Zero(&max);
115 LargeInt_Zero(&gVisualiserMaxMass);
116 LargeInt_Zero(&gVisualiserMaxCharge);
118 for( i = 1; i < giNumParticles; i++ )
120 Vector_GetMax(&max, &max, &gpParticles[i].Location);
121 Vector_GetMin(&min, &min, &gpParticles[i].Location);
124 //printf( "gpParticles[%i].Location = %s\n", i, Vector_DumpEx(&gpParticles[i].Location, 0) );
126 if( LargeInt_Compare(&gVisualiserMaxMass, &gpParticles[i].Mass) < 0 )
127 LargeInt_Set(&gVisualiserMaxMass, &gpParticles[i].Mass);
129 if( LargeInt_Compare(&gVisualiserMaxCharge, &gpParticles[i].Charge) < 0 )
130 LargeInt_Set(&gVisualiserMaxCharge, &gpParticles[i].Charge);
133 //printf("max = %s, min = %s\n", Vector_DumpEx(&max, 0), Vector_DumpEx(&min, 1));
135 //printf("gVisualiserMaxMass = %s, gVisualiserMaxCharge = %s\n",
136 // LargeInt_DumpEx(&gVisualiserMaxMass, 0),
137 // LargeInt_DumpEx(&gVisualiserMaxCharge, 1)
141 Vector_Set( &gVisualiserBase, &min );
142 Vector_Set( &gVisualiserSize, &max );
143 Vector_Sub( &gVisualiserSize, &min );
145 //printf("gVisualiserBase = %s\n", Vector_DumpEx(&gVisualiserBase, 0) );
146 //printf("gVisualiserSize = %s\n", Vector_DumpEx(&gVisualiserSize, 2) );
148 Vector_MulMatrix(&gVisualiserBase, &gVisualiserView, &gVisualiserBase);
149 Vector_MulMatrix(&gVisualiserSize, &gVisualiserView, &gVisualiserSize);
151 //printf("gVisualiserBase = %s\n", Vector_DumpEx(&gVisualiserBase, 0) );
152 //printf("gVisualiserSize = %s\n", Vector_DumpEx(&gVisualiserSize, 2) );
156 * \brief Fill the buffer from the particles
158 void Visualiser_FillBuffers(void)
165 memset( gVisualiserBuffer, 0, sizeof(tPixel)*giVisualiserPxHeight*giVisualiserPxWidth );
167 for( i = 0; i < giNumParticles; i++ )
169 Vector_Set(&tmp, &gpParticles[i].Location);
170 Vector_MulMatrix(&tmp, &gVisualiserView, &tmp);
171 Vector_Sub(&tmp, &gVisualiserBase);
173 LargeInt_MulNative(&tmp.C[0], NULL, &tmp.C[0], giVisualiserPxWidth-1);
174 LargeInt_MulNative(&tmp.C[1], NULL, &tmp.C[1], giVisualiserPxHeight-1);
176 //printf("tmp = %s\n", Vector_DumpEx(&tmp, 0));
177 //printf("gVisualiserSize = %s\n", Vector_DumpEx(&gVisualiserSize, 0));
178 Vector_DivComp(&tmp, &gVisualiserSize);
179 //printf("tmp = %s\n", Vector_DumpEx(&tmp, 0));
183 // Both components are now known to be machine integers, as
184 // giVisualiserPxWidth and giVisualiserPxHeight are native integers
185 x = tmp.C[0].W[0]; y = tmp.C[1].W[0];
186 if( x < 0 || x >= giVisualiserPxWidth ) continue;
187 if( y < 0 || y >= giVisualiserPxHeight ) continue;
188 //printf("Particle #%i (%i,%i)\n", i, x, y);
190 // Set Pixel information
191 px = &gVisualiserBuffer[y*giVisualiserPxWidth+x];
193 LargeInt_MulNative( &tmpLI, NULL, &gpParticles[i].Mass, 100);
194 LargeInt_Div( &tmpLI, NULL, &tmpLI, &gVisualiserMaxMass);
195 px->Mass += tmpLI.W[0];
197 LargeInt_MulNative( &tmpLI, NULL, &gpParticles[i].Charge, 100);
198 LargeInt_Div( &tmpLI, NULL, &tmpLI, &gVisualiserMaxCharge);
199 px->Charge += tmpLI.W[0];
203 //printf("(%i,%i) = (%i,%i,%i)\n", x, y, px->Mass, px->Charge, px->Num);
207 giVisualiser_MinCharge = px->Charge;
208 gVisualiser_MaxPixelVals.Mass = px->Mass;
209 gVisualiser_MaxPixelVals.Charge = px->Charge;
210 gVisualiser_MaxPixelVals.Num = px->Num;
214 if(gVisualiser_MaxPixelVals.Mass < px->Mass)
215 gVisualiser_MaxPixelVals.Mass = px->Mass;
216 if((int)gVisualiser_MaxPixelVals.Charge < (int)px->Charge)
217 gVisualiser_MaxPixelVals.Charge = px->Charge;
218 if(giVisualiser_MinCharge > (int)px->Charge)
219 giVisualiser_MinCharge = (int)px->Charge;
220 if(gVisualiser_MaxPixelVals.Num < px->Num)
221 gVisualiser_MaxPixelVals.Num = px->Num;
227 void Video_PSet(int x, int y, uint8_t r, uint8_t g, uint8_t b)
229 printf(" (%i,%i) %02x %02x %02x\n", x, y, r, g, b);
234 * \brief Renders the buffer to the screen
236 void Visualiser_Render(void)
242 //printf("gVisualiser_MaxPixelVals = {\n");
243 //printf(" Mass: %u\n", gVisualiser_MaxPixelVals.Mass);
244 //printf(" Charge: %i\n", gVisualiser_MaxPixelVals.Charge);
245 //printf(" Num: %u\n", gVisualiser_MaxPixelVals.Num);
248 //if(gVisualiser_MaxPixelVals.Mass ==0) gVisualiser_MaxPixelVals.Mass = 1;
249 //if(gVisualiser_MaxPixelVals.Charge ==0) gVisualiser_MaxPixelVals.Charge = 1;
250 //if(gVisualiser_MaxPixelVals.Num ==0) gVisualiser_MaxPixelVals.Num = 1;
252 gVisualiser_MaxPixelVals.Charge -= giVisualiser_MinCharge;
254 px = &gVisualiserBuffer[0];
255 for( y = 0; y < giVisualiserPxHeight; y ++ )
257 for( x = 0; x < giVisualiserPxWidth; x ++ )
260 r = 255 * px->Mass / gVisualiser_MaxPixelVals.Mass;
261 g = 255 * (px->Charge - giVisualiser_MinCharge) / gVisualiser_MaxPixelVals.Charge;
262 b = 255 * px->Num / gVisualiser_MaxPixelVals.Num;
264 // printf(" (%i,%i) %02x %02x %02x\n", x, y, r, g, b);
269 Video_PSet(x, y, r, g, b);