[Scummvm-git-logs] scummvm master -> a784a8db940c5f87209664f893f08c2c2804e2f7

aquadran noreply at scummvm.org
Tue Aug 12 05:22:20 UTC 2025


This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .

Summary:
a784a8db94 WINTERMUTE: Replace qsort with msvc version


Commit: a784a8db940c5f87209664f893f08c2c2804e2f7
    https://github.com/scummvm/scummvm/commit/a784a8db940c5f87209664f893f08c2c2804e2f7
Author: Paweł Kołodziejski (aquadran at gmail.com)
Date: 2025-08-12T07:22:14+02:00

Commit Message:
WINTERMUTE: Replace qsort with msvc version

Changed paths:
    engines/wintermute/ad/ad_scene.cpp
    engines/wintermute/ad/ad_scene_geometry.cpp
    engines/wintermute/base/base_surface_storage.cpp
    engines/wintermute/base/particles/part_emitter.cpp
    engines/wintermute/utils/utils.cpp
    engines/wintermute/utils/utils.h


diff --git a/engines/wintermute/ad/ad_scene.cpp b/engines/wintermute/ad/ad_scene.cpp
index 3400bc80ce8..6fee21fd3e5 100644
--- a/engines/wintermute/ad/ad_scene.cpp
+++ b/engines/wintermute/ad/ad_scene.cpp
@@ -1433,7 +1433,7 @@ bool AdScene::displayRegionContent(AdRegion *region, bool display3DOnly) {
 	}
 
 	// sort by _posY
-	qsort(objects.getData(), objects.getSize(), sizeof(AdObject *), AdScene::compareObjs);
+	qsort_msvc(objects.getData(), objects.getSize(), sizeof(AdObject *), AdScene::compareObjs);
 
 	// display them
 	for (int32 i = 0; i < objects.getSize(); i++) {
@@ -3752,7 +3752,7 @@ bool AdScene::getRegionObjects(AdRegion *region, BaseArray<AdObject *> &objects,
 	}
 
 	// sort by _posY
-	qsort(objects.getData(), objects.getSize(), sizeof(AdObject *), AdScene::compareObjs);
+	qsort_msvc(objects.getData(), objects.getSize(), sizeof(AdObject *), AdScene::compareObjs);
 
 	return STATUS_OK;
 }
diff --git a/engines/wintermute/ad/ad_scene_geometry.cpp b/engines/wintermute/ad/ad_scene_geometry.cpp
index f97fbf78b9e..16166e04da8 100644
--- a/engines/wintermute/ad/ad_scene_geometry.cpp
+++ b/engines/wintermute/ad/ad_scene_geometry.cpp
@@ -50,6 +50,7 @@
 #include "engines/wintermute/base/gfx/xmath.h"
 #include "engines/wintermute/base/gfx/3dutils.h"
 #include "engines/wintermute/utils/path_util.h"
+#include "engines/wintermute/utils/utils.h"
 #include "engines/wintermute/system/sys_class_registry.h"
 #include "engines/wintermute/wintermute.h"
 
@@ -949,7 +950,7 @@ bool AdSceneGeometry::enableLights(DXVector3 point, BaseArray<char *> &ignoreLig
 
 		// sort by distance
 		if (activeLights.getSize() > 0) {
-			qsort(activeLights.getData(), activeLights.getSize(), sizeof(Light3D *), AdSceneGeometry::compareLights);
+			qsort_msvc(activeLights.getData(), activeLights.getSize(), sizeof(Light3D *), AdSceneGeometry::compareLights);
 
 			for (int32 i = 0; i < activeLights.getSize(); i++) {
 				activeLights[i]->_isAvailable = static_cast<int32>(i) < maxLights;
diff --git a/engines/wintermute/base/base_surface_storage.cpp b/engines/wintermute/base/base_surface_storage.cpp
index 9ed354c6063..3ce51f12940 100644
--- a/engines/wintermute/base/base_surface_storage.cpp
+++ b/engines/wintermute/base/base_surface_storage.cpp
@@ -32,6 +32,7 @@
 #include "engines/wintermute/base/base_engine.h"
 #include "engines/wintermute/base/base_file_manager.h"
 #include "engines/wintermute/platform_osystem.h"
+#include "engines/wintermute/utils/utils.h"
 #include "common/str.h"
 
 namespace Wintermute {
@@ -170,7 +171,7 @@ bool BaseSurfaceStorage::persist(BasePersistenceManager *persistMgr)
 
 //////////////////////////////////////////////////////////////////////////
 bool BaseSurfaceStorage::sortSurfaces() {
-	qsort(_surfaces.getData(), _surfaces.getSize(), sizeof(BaseSurface *), surfaceSortCB);
+	qsort_msvc(_surfaces.getData(), _surfaces.getSize(), sizeof(BaseSurface *), surfaceSortCB);
 	return STATUS_OK;
 }
 
diff --git a/engines/wintermute/base/particles/part_emitter.cpp b/engines/wintermute/base/particles/part_emitter.cpp
index 7c92767221a..ac7d089e607 100644
--- a/engines/wintermute/base/particles/part_emitter.cpp
+++ b/engines/wintermute/base/particles/part_emitter.cpp
@@ -366,7 +366,7 @@ bool PartEmitter::start() {
 //////////////////////////////////////////////////////////////////////////
 bool PartEmitter::sortParticlesByZ() {
 	// sort particles by _posY
-	qsort(_particles.getData(), _particles.getSize(), sizeof(PartParticle *), PartEmitter::compareZ);
+	qsort_msvc(_particles.getData(), _particles.getSize(), sizeof(PartParticle *), PartEmitter::compareZ);
 	return STATUS_OK;
 }
 
diff --git a/engines/wintermute/utils/utils.cpp b/engines/wintermute/utils/utils.cpp
index 49c8d861e19..34a3a778df3 100644
--- a/engines/wintermute/utils/utils.cpp
+++ b/engines/wintermute/utils/utils.cpp
@@ -25,6 +25,12 @@
  * Copyright (c) 2011 Jan Nedoma
  */
 
+/*
+ * qsort code originated from Wine sources.
+ * Copyright 2000 Jon Griffiths
+ * Copyright 2014 Piotr Caban
+ */
+
 #include "engines/wintermute/utils/utils.h"
 #include "engines/wintermute/wintermute.h"
 #include "engines/wintermute/base/base_engine.h"
@@ -302,4 +308,116 @@ float BaseUtils::Hue2RGB(float v1, float v2, float vH) {
 	return (v1);
 }
 
+static inline void swapBytes(byte *l, byte *r, uint32 size) {
+	byte tmp;
+
+	while (size--) {
+		tmp = *l;
+		*l++ = *r;
+		*r++ = tmp;
+	}
+}
+
+static void smallSort(void *base, uint32 num, uint32 size,
+	              int32 (*compare)(const void *, const void *)) {
+	byte *max, *p;
+
+	for (uint32 e = num; e > 1; e--) {
+		max = (byte *)base;
+		for (uint32 i = 1; i < e; i++) {
+			p = (byte *)base + i * size;
+			if (compare(p, max) > 0)
+				max = p;
+		}
+
+		if (p != max)
+			swapBytes(p, max, size);
+	}
+}
+
+static void quickSort(void *base, uint32 num, uint32 size,
+	              int32 (*compare)(const void *, const void *)) {
+	uint32 stackLo[8 * sizeof(uint32)], stackHi[8 * sizeof(uint32)];
+	uint32 beg, end, lo, hi, med;
+	int32 stackPos;
+
+	stackPos = 0;
+	stackLo[stackPos] = 0;
+	stackHi[stackPos] = num - 1;
+
+#define X(i) ((byte *)base + size * (i))
+	while (stackPos >= 0) {
+		beg = stackLo[stackPos];
+		end = stackHi[stackPos--];
+
+		if (end - beg < 8) {
+			smallSort(X(beg), end - beg + 1, size, compare);
+			continue;
+		}
+
+		lo = beg;
+		hi = end;
+		med = lo + (hi - lo + 1) / 2;
+		if (compare(X(lo), X(med)) > 0)
+			swapBytes(X(lo), X(med), size);
+		if (compare(X(lo), X(hi)) > 0)
+			swapBytes(X(lo), X(hi), size);
+		if (compare(X(med), X(hi)) > 0)
+			swapBytes(X(med), X(hi), size);
+
+		lo++;
+		hi--;
+		while (1) {
+			while (lo <= hi) {
+				if (lo != med && compare(X(lo), X(med)) > 0)
+					break;
+				lo++;
+			}
+
+			while (med != hi) {
+				if (compare(X(hi), X(med)) <= 0)
+					break;
+				hi--;
+			}
+
+			
+			if (hi < lo)
+				break;
+
+			swapBytes(X(lo), X(hi), size);
+			if (hi == med)
+				med = lo;
+			lo++;
+			hi--;
+		}
+
+		while (hi > beg) {
+			if (hi != med && compare(X(hi), X(med)) != 0)
+				break;
+			hi--;
+		}
+
+		if (hi - beg >= end-lo) {
+			stackLo[++stackPos] = beg;
+			stackHi[stackPos] = hi;
+			stackLo[++stackPos] = lo;
+			stackHi[stackPos] = end;
+		} else {
+			stackLo[++stackPos] = lo;
+			stackHi[stackPos] = end;
+			stackLo[++stackPos] = beg;
+			stackHi[stackPos] = hi;
+		}
+	}
+#undef X
+}
+
+void qsort_msvc(void *base, uint32 num, uint32 size,
+	        int32 (*compare)(const void *, const void *)) {
+	if (base == NULL || num == 0)
+		return;
+
+	quickSort(base, num, size, compare);
+}
+
 } // End of namespace Wintermute
diff --git a/engines/wintermute/utils/utils.h b/engines/wintermute/utils/utils.h
index 9a796674767..6c467d741fc 100644
--- a/engines/wintermute/utils/utils.h
+++ b/engines/wintermute/utils/utils.h
@@ -60,6 +60,9 @@ private:
 	static float Hue2RGB(float v1, float v2, float vH);
 };
 
+void qsort_msvc(void *base, uint32 nmemb, uint32 size,
+                int (*compare)(const void *, const void *));
+
 } // End of namespace Wintermute
 
 #endif




More information about the Scummvm-git-logs mailing list