+ for (scanline = 0; scanline < REFLECTION_HEIGHT; scanline++) {
+ scrollModTable[scanline] = (int) (backgroundW / scrollScaleTable[scanline] + 0.5f);
+ for (i = 0; i < backgroundW; i++) {
+ x = (int)(i * scrollScaleTable[scanline] + 0.5f);
+ if (x < backgroundW) {
+ *dst = (unsigned short)(normalmap[x] >> 8) & 0xFF;
+ if ((short)*dst > maxDisplacement) maxDisplacement = (short)(*dst);
+ if ((short)*dst < minDisplacement) minDisplacement = (short)(*dst);
+ } else {
+ *dst = 0;
+ }
+ dst++;
+ }
+ normalmap += backgroundW;
+ }
+
+ if (maxDisplacement == minDisplacement) {
+ printf("Warning: grise normalmap fucked up\n");
+ return;
+ }
+
+ /* Second pass - subtract half maximum displacement to displace in both directions */
+ for (scanline = 0; scanline < REFLECTION_HEIGHT; scanline++) {
+ for (i = 0; i < backgroundW; i++) {
+ /* Remember that MIN_SCROLL is the padding around the screen, so ti's the maximum displacement we can get (positive & negative) */
+ *dst2 = 2 * MIN_SCROLL * (*dst2 - minDisplacement) / (maxDisplacement - minDisplacement) - MIN_SCROLL;
+ *dst2 = (short)((float)*dst2 / scrollScaleTable[scanline] + 0.5f); /* Displacements must also scale with distance*/
+ dst2++;
+ }
+ }
+}
+
+static float distanceScale(int scanline) {
+ float farScale, t;
+ farScale = (float)NEAR_SCROLL_SPEED / (float)FAR_SCROLL_SPEED;
+ t = (float)scanline / ((float)REFLECTION_HEIGHT - 1);
+ return 1.0f / (1.0f / farScale + (1.0f - 1.0f / farScale) * t);
+}
+
+static void initScrollTables() {
+ int i = 0;
+ for (i = 0; i < REFLECTION_HEIGHT; i++) {
+ scrollScaleTable[i] = distanceScale(i);
+ scrollTable[i] = 0.0f;
+ scrollTableRounded[i] = 0;
+ }
+}
+
+
+static void updateScrollTables(float dt) {
+ int i = 0;
+
+ nearScrollAmount += dt * NEAR_SCROLL_SPEED;
+ nearScrollAmount = (float) fmod(nearScrollAmount, 512.0f);
+
+ for (i = 0; i < REFLECTION_HEIGHT; i++) {
+ scrollTable[i] = nearScrollAmount / scrollScaleTable[i];
+ scrollTableRounded[i] = (int)(scrollTable[i] + 0.5f) % scrollModTable[i];
+ }
+}