[Scummvm-cvs-logs] CVS: scummvm/scumm boxes.cpp,1.57,1.58 scumm.h,1.296,1.297
Max Horn
fingolfin at users.sourceforge.net
Tue Sep 9 10:07:22 CEST 2003
Update of /cvsroot/scummvm/scummvm/scumm
In directory sc8-pr-cvs1:/tmp/cvs-serv27764
Modified Files:
boxes.cpp scumm.h
Log Message:
added convertScaleTableToScaleSlot method, preparing to replace scale items with scale slots
Index: boxes.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/boxes.cpp,v
retrieving revision 1.57
retrieving revision 1.58
diff -u -d -r1.57 -r1.58
--- boxes.cpp 13 Aug 2003 02:21:36 -0000 1.57
+++ boxes.cpp 9 Sep 2003 16:55:25 -0000 1.58
@@ -159,7 +159,7 @@
if (_version == 8) {
int slot = FROM_LE_32(ptr->v8.scaleSlot);
if (slot) {
- assert(1 <= slot && slot <= 20);
+ assert(1 <= slot && slot <= ARRAYSIZE(_scaleSlots));
int scaleX = 0, scaleY = 0;
ScaleSlot &s = _scaleSlots[slot-1];
@@ -248,16 +248,121 @@
tmp = 255;
*ptr++ = tmp;
}
+/*
+ // TEST!
+ printf("setScaleItem(%d, %d, %d, %d, %d)\n", slot, y1, scale1, y2, scale2);
+ convertScaleTableToScaleSlot(slot);
+*/
+}
+
+void Scumm::convertScaleTableToScaleSlot(int slot) {
+ assert(1 <= slot && slot <= ARRAYSIZE(_scaleSlots));
+
+ byte *resptr = getResourceAddress(rtScaleTable, slot);
+ ScaleSlot &s = _scaleSlots[slot-1];
+
+ int lowerIdx, upperIdx;
+ float m, oldM;
+
+ if (resptr[0] == resptr[199]) {
+ // The scale is constant This usually means we encountered one of the
+ // "broken" cases. We set pseudo scale item values which lead to a
+ // constant scale of 255.
+ // TODO
+ printf("Broken case!\n");
+ s.y1 = 0;
+ s.y2 = 199;
+ s.scale1 = s.scale2 = 255;
+ return;
+ }
+
+ /*
+ * Essentially, what we are doing here is some kind of "line fitting"
+ * algorithm. The data in the scale table represents a linear graph. What
+ * we want to find is the slope and (vertical) offset of this line. Things
+ * are complicated by the fact that the line is cut of vertically at 1 and
+ * 255. We have to be careful in handling this and some border cases.
+ *
+ * Some typical graphs look like these:
+ * --- --- ---
+ * / --- \
+ * ___/ --- \___
+ *
+ * The method used here is to compute the slope of secants fixed at the
+ * left and right end. For most cases this detects the cut-over points
+ * quite accurately.
+ */
+
+ // Search for the bend on the left side
+ m = (resptr[199] - resptr[0]) / 199.0;
+ for (lowerIdx = 0; lowerIdx < 199 && (resptr[lowerIdx] == 1 || resptr[lowerIdx] == 255); lowerIdx++) {
+ oldM = m;
+ m = (resptr[199] - resptr[lowerIdx+1]) / (float)(199 - (lowerIdx+1));
+ if (m > 0) {
+ if (m <= oldM)
+ break;
+ } else {
+ if (m >= oldM)
+ break;
+ }
+ }
+
+ // Search for the bend on the right side
+ m = (resptr[199] - resptr[0]) / 199.0;
+ for (upperIdx = 199; upperIdx > 1 && (resptr[upperIdx] == 1 || resptr[upperIdx] == 255); upperIdx--) {
+ oldM = m;
+ m = (resptr[upperIdx-1] - resptr[0]) / (float)(upperIdx-1);
+ if (m > 0) {
+ if (m <= oldM)
+ break;
+ } else {
+ if (m >= oldM)
+ break;
+ }
+ }
+
+ // If lowerIdx and upperIdx are equal, we assume that there
+ // was no bend at all, and go for the maximum range.
+ if (lowerIdx == upperIdx) {
+ lowerIdx = 0;
+ upperIdx = 199;
+ }
+
+ // The values of y1 and y2, as well as the scale, can now easily be computed
+ s.y1 = lowerIdx;
+ s.y2 = upperIdx;
+ s.scale1 = resptr[lowerIdx];
+ s.scale2 = resptr[upperIdx];
+
+
+ // Compute the variance, for debugging. It shouldn't exceed 1
+ int y;
+ int sum = 0;
+ int scale;
+ float variance;
+ for (y = 0; y < 200; y++) {
+ scale = (s.scale2 - s.scale1) * (y - s.y1) / (s.y2 - s.y1) + s.scale1;
+ if (scale < 1)
+ scale = 1;
+ else if (scale > 255)
+ scale = 255;
+
+ sum += (resptr[y] - scale) * (resptr[y] - scale);
+ }
+ variance = sum / (200.0 - 1.0);
+ if (variance > 1)
+ warning("scale item %d, variance %f exceeds 1 (room %d)\n", slot, variance, _currentRoom);
}
void Scumm::setScaleSlot(int slot, int x1, int y1, int scale1, int x2, int y2, int scale2) {
- assert(1 <= slot && slot <= 20);
- _scaleSlots[slot-1].x2 = x2;
- _scaleSlots[slot-1].y2 = y2;
- _scaleSlots[slot-1].scale2 = scale2;
- _scaleSlots[slot-1].x1 = x1;
- _scaleSlots[slot-1].y1 = y1;
- _scaleSlots[slot-1].scale1 = scale1;
+ assert(1 <= slot && slot <= ARRAYSIZE(_scaleSlots));
+ ScaleSlot &s = _scaleSlots[slot-1];
+ s.x2 = x2;
+ s.y2 = y2;
+ s.scale2 = scale2;
+ s.x1 = x1;
+ s.y1 = y1;
+ s.scale1 = scale1;
}
byte Scumm::getNumBoxes() {
Index: scumm.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/scumm.h,v
retrieving revision 1.296
retrieving revision 1.297
diff -u -d -r1.296 -r1.297
--- scumm.h 9 Sep 2003 00:13:19 -0000 1.296
+++ scumm.h 9 Sep 2003 16:55:25 -0000 1.297
@@ -1054,14 +1054,15 @@
void setScaleItem(int slot, int a, int b, int c, int d);
protected:
- // V8 scaling stuff: should be in V8 class
+ // Scaling slots/items
struct ScaleSlot {
int x1, y1, scale1;
int x2, y2, scale2;
};
- ScaleSlot _scaleSlots[20]; // FIXME - not sure if this limit is right, but based on my observations it is
+ ScaleSlot _scaleSlots[20];
void setScaleSlot(int slot, int x1, int y1, int scale1, int x2, int y2, int scale2);
void setBoxScaleSlot(int box, int slot);
+ void convertScaleTableToScaleSlot(int slot);
void createBoxMatrix();
bool areBoxesNeighbours(int i, int j);
More information about the Scummvm-git-logs
mailing list