First pass of adding text to the loading progress UI. It deliberately uses the very primitive STB

generated font, so can only render basic ASCII text, and also only renders pre-defined strings,
as translations aren't available either.

Signed-off-by: cpw <cpw+github@weeksfamily.ca>
This commit is contained in:
cpw 2019-06-22 23:39:00 -04:00
parent d966746fbf
commit 448d996a45
No known key found for this signature in database
GPG key ID: 8EB3DF749553B1B7
4 changed files with 117 additions and 4 deletions

View file

@ -0,0 +1,10 @@
--- a/net/minecraft/client/gui/ResourceLoadProgressGui.java
+++ b/net/minecraft/client/gui/ResourceLoadProgressGui.java
@@ -83,6 +83,7 @@
this.func_212972_a(i / 2 - 150, j / 4 * 3, i / 2 + 150, j / 4 * 3 + 10, this.field_212978_f, 1.0F - MathHelper.func_76131_a(f, 0.0F, 1.0F));
}
+ net.minecraftforge.fml.client.ClientModLoader.renderProgressText();
if (f >= 2.0F) {
this.field_212974_b.func_213268_a((LoadingGui)null);
}

View file

@ -46,9 +46,9 @@ import net.minecraftforge.registries.ObjectHolderRegistry;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.IOException;
import java.nio.file.Path;
import java.util.*;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;
@ -101,6 +101,8 @@ public class ModLoader
private final List<ModLoadingException> loadingExceptions;
private final List<ModLoadingWarning> loadingWarnings;
private GatherDataEvent.DataGeneratorConfig dataGeneratorConfig;
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
private Optional<Consumer<String>> statusConsumer = Optional.empty();
private ModLoader()
{
@ -125,18 +127,24 @@ public class ModLoader
}
public void loadMods() {
statusConsumer.ifPresent(c->c.accept("Loading mod config"));
DistExecutor.runWhenOn(Dist.CLIENT, ()->()-> ConfigTracker.INSTANCE.loadConfigs(ModConfig.Type.CLIENT, FMLPaths.CONFIGDIR.get()));
ConfigTracker.INSTANCE.loadConfigs(ModConfig.Type.COMMON, FMLPaths.CONFIGDIR.get());
statusConsumer.ifPresent(c->c.accept("Mod setup: SETUP"));
dispatchAndHandleError(LifecycleEventProvider.SETUP);
statusConsumer.ifPresent(c->c.accept("Mod setup: SIDED SETUP"));
DistExecutor.runWhenOn(Dist.CLIENT, this::fireClientEvents);
dispatchAndHandleError(LifecycleEventProvider.SIDED_SETUP);
statusConsumer.ifPresent(c->c.accept("Mod setup complete"));
}
public void gatherAndInitializeMods() {
statusConsumer.ifPresent(c->c.accept("Loading mods"));
final ModList modList = ModList.of(loadingModList.getModFiles().stream().map(ModFileInfo::getFile).collect(Collectors.toList()), loadingModList.getMods());
if (!this.loadingExceptions.isEmpty()) {
throw new LoadingFailedException(loadingExceptions);
}
statusConsumer.ifPresent(c->c.accept("Building Mod List"));
final List<ModContainer> modContainers = loadingModList.getModFiles().stream().
map(ModFileInfo::getFile).
map(mf -> buildMods(mf, launchClassLoader)).
@ -147,11 +155,15 @@ public class ModLoader
throw new LoadingFailedException(loadingExceptions);
}
modList.setLoadedMods(modContainers);
statusConsumer.ifPresent(c->c.accept("Constructing mods"));
dispatchAndHandleError(LifecycleEventProvider.CONSTRUCT);
statusConsumer.ifPresent(c->c.accept("Creating registries"));
GameData.fireCreateRegistryEvents(LifecycleEventProvider.CREATE_REGISTRIES, this::dispatchAndHandleError);
ObjectHolderRegistry.findObjectHolders();
CapabilityManager.INSTANCE.injectCapabilities(modList.getAllScanData());
statusConsumer.ifPresent(c->c.accept("Populating registries"));
GameData.fireRegistryEvents(rl->true, LifecycleEventProvider.LOAD_REGISTRIES, this::dispatchAndHandleError);
statusConsumer.ifPresent(c->c.accept("Early mod loading complete"));
}
private void dispatchAndHandleError(LifecycleEventProvider event) {
@ -207,11 +219,16 @@ public class ModLoader
public void finishMods()
{
statusConsumer.ifPresent(c->c.accept("Mod setup: ENQUEUE IMC"));
dispatchAndHandleError(LifecycleEventProvider.ENQUEUE_IMC);
statusConsumer.ifPresent(c->c.accept("Mod setup: PROCESS IMC"));
dispatchAndHandleError(LifecycleEventProvider.PROCESS_IMC);
statusConsumer.ifPresent(c->c.accept("Mod setup: Final completion"));
dispatchAndHandleError(LifecycleEventProvider.COMPLETE);
statusConsumer.ifPresent(c->c.accept("Freezing data"));
GameData.freezeData();
NetworkRegistry.lock();
statusConsumer.ifPresent(c->c.accept(""));
}
public List<ModLoadingWarning> getWarnings()
@ -237,4 +254,8 @@ public class ModLoader
public Function<ModContainer, ModLifecycleEvent> getDataGeneratorEvent() {
return mc -> new GatherDataEvent(mc, dataGeneratorConfig.makeGenerator(p->dataGeneratorConfig.getMods().size() == 1 ? p : p.resolve(mc.getModId()), dataGeneratorConfig.getMods().contains(mc.getModId())), dataGeneratorConfig);
}
public void setStatusConsumer(Consumer<String> consumer) {
this.statusConsumer = Optional.ofNullable(consumer);
}
}

View file

@ -50,6 +50,7 @@ public class ClientModLoader
private static boolean loading;
private static Minecraft mc;
private static LoadingFailedException error;
private static EarlyLoaderGUI earlyLoaderGUI;
public static void begin(final Minecraft minecraft, final ResourcePackList<ClientResourcePackInfo> defaultResourcePacks, final IReloadableResourceManager mcResourceManager, DownloadingPackFinder metadataSerializer)
{
@ -57,6 +58,8 @@ public class ClientModLoader
ClientModLoader.mc = minecraft;
SidedProvider.setClient(()->minecraft);
LogicalSidedProvider.setClient(()->minecraft);
earlyLoaderGUI = new EarlyLoaderGUI(minecraft.mainWindow);
ModLoader.get().setStatusConsumer(earlyLoaderGUI.getStatusConsumer());
createRunnableWithCatch(ModLoader.get()::gatherAndInitializeMods).run();
ResourcePackLoader.loadResourcePacks(defaultResourcePacks);
mcResourceManager.addReloadListener(ClientModLoader::onreload);
@ -64,9 +67,9 @@ public class ClientModLoader
}
private static CompletableFuture<Void> onreload(final IFutureReloadListener.IStage stage, final IResourceManager resourceManager, final IProfiler prepareProfiler, final IProfiler executeProfiler, final Executor asyncExecutor, final Executor syncExecutor) {
return CompletableFuture.runAsync(createRunnableWithCatch(ModLoader.get()::loadMods), syncExecutor).
return CompletableFuture.runAsync(createRunnableWithCatch(ClientModLoader::startModLoading), syncExecutor).
thenCompose(stage::markCompleteAwaitingOthers).
thenRunAsync(ClientModLoader::end);
thenRunAsync(ClientModLoader::finishModLoading, syncExecutor);
}
private static Runnable createRunnableWithCatch(Runnable r) {
@ -80,7 +83,11 @@ public class ClientModLoader
};
}
public static void end()
private static void startModLoading() {
earlyLoaderGUI.handleElsewhere();
createRunnableWithCatch(ModLoader.get()::loadMods).run();
}
private static void finishModLoading()
{
createRunnableWithCatch(ModLoader.get()::finishMods).run();
loading = false;
@ -122,6 +129,9 @@ public class ClientModLoader
}
}
public static void renderProgressText() {
earlyLoaderGUI.renderFromGUI();
}
public static boolean isLoading()
{
return loading;

View file

@ -0,0 +1,72 @@
package net.minecraftforge.fml.client;
import com.mojang.blaze3d.platform.GlStateManager;
import net.minecraft.client.MainWindow;
import net.minecraft.client.Minecraft;
import org.lwjgl.opengl.GL11;
import org.lwjgl.stb.STBEasyFont;
import org.lwjgl.system.MemoryUtil;
import java.nio.ByteBuffer;
import java.util.function.Consumer;
public class EarlyLoaderGUI {
private final MainWindow window;
private String message;
private boolean handledElsewhere;
public EarlyLoaderGUI(final MainWindow window) {
this.window = window;
GlStateManager.clearColor(1.0f, 1.0f, 1.0f, 1.0f);
GlStateManager.clear(GL11.GL_COLOR_BUFFER_BIT, Minecraft.IS_RUNNING_ON_MAC);
window.update(false);
}
public Consumer<String> getStatusConsumer() {
return this::update;
}
private void update(final String message) {
this.message = message;
if (handledElsewhere) return;
doMatrix();
GlStateManager.clearColor(1.0f, 1.0f, 1.0f, 1.0f);
GlStateManager.clear(GL11.GL_COLOR_BUFFER_BIT, Minecraft.IS_RUNNING_ON_MAC);
renderMessage();
window.update(false);
}
public void handleElsewhere() {
this.handledElsewhere = true;
}
void renderFromGUI() {
doMatrix();
renderMessage();
}
void renderMessage() {
GlStateManager.enableClientState(GL11.GL_VERTEX_ARRAY);
ByteBuffer charBuffer = MemoryUtil.memAlloc(this.message.length() * 270);
int quads = STBEasyFont.stb_easy_font_print(0, 0, this.message, null, charBuffer);
GlStateManager.vertexPointer(2, GL11.GL_FLOAT, 16, charBuffer);
GlStateManager.color3f(0,0,0);
GlStateManager.pushMatrix();
GlStateManager.translatef(10, window.getFramebufferHeight() - 50, 0);
GlStateManager.scalef(3, 3, 0);
GlStateManager.drawArrays(GL11.GL_QUADS, 0, quads * 4);
GlStateManager.popMatrix();
MemoryUtil.memFree(charBuffer);
}
private void doMatrix() {
GlStateManager.clear(GL11.GL_DEPTH_BUFFER_BIT, Minecraft.IS_RUNNING_ON_MAC);
GlStateManager.matrixMode(GL11.GL_PROJECTION);
GlStateManager.loadIdentity();
GlStateManager.ortho(0.0, window.getFramebufferWidth(), window.getFramebufferHeight(), 0.0, -1.0, 1.0);
GlStateManager.matrixMode(GL11.GL_MODELVIEW);
GlStateManager.loadIdentity();
}
}