mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-17 03:25:14 -04:00
Finish porting LoadingMapScreen and GeneratingMapScreen to C client.
This commit is contained in:
parent
4416616945
commit
1a285e2549
@ -2,7 +2,7 @@
|
||||
#define CC_ASYNCDOWNLOADER_H
|
||||
#include "Typedefs.h"
|
||||
#include "Constants.h"
|
||||
#include "Utils.h
|
||||
#include "Utils.h"
|
||||
#include "GameStructs.h"
|
||||
/* Downloads images, texture packs, skins, etc in async manner.
|
||||
Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
|
||||
|
@ -9,6 +9,10 @@
|
||||
#include "GraphicsAPI.h"
|
||||
#include "Player.h"
|
||||
#include "Funcs.h"
|
||||
#include "TerrainAtlas.h"
|
||||
#include "ModelCache.h"
|
||||
#include "MapGenerator.h"
|
||||
#include "ServerConnection.h"
|
||||
|
||||
void Screen_FreeWidgets(Widget** widgets, UInt32 widgetsCount) {
|
||||
if (widgets == NULL) return;
|
||||
@ -320,6 +324,58 @@ void StatusScreen_MakeText(StatusScreen* screen, STRING_TRANSIENT String* status
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void StatusScreen_DrawPosition(StatusScreen* screen) {
|
||||
TextAtlas* atlas = &screen->PosAtlas;
|
||||
VertexP3fT2fC4b vertices[4 * 8];
|
||||
VertexP3fT2fC4b* ptr = vertices;
|
||||
|
||||
Texture tex = atlas->Tex; tex.X = 2; tex.Width = (UInt16)atlas->Offset;
|
||||
PackedCol col = PACKEDCOL_WHITE;
|
||||
GfxCommon_Make2DQuad(&tex, col, &ptr);
|
||||
|
||||
Vector3I pos; Vector3I_Floor(&pos, &LocalPlayer_Instance.Base.Base.Position);
|
||||
atlas->CurX = atlas->Offset + 2;
|
||||
|
||||
TextAtlas_Add(atlas, 13, &ptr);
|
||||
TextAtlas_AddInt(atlas, pos.X, &ptr);
|
||||
TextAtlas_Add(atlas, 11, &ptr);
|
||||
TextAtlas_AddInt(atlas, pos.Y, &ptr);
|
||||
TextAtlas_Add(atlas, 11, &ptr);
|
||||
TextAtlas_AddInt(atlas, pos.Z, &ptr);
|
||||
TextAtlas_Add(atlas, 14, &ptr);
|
||||
|
||||
Gfx_BindTexture(atlas->Tex.ID);
|
||||
/* TODO: Do we need to use a separate VB here? */
|
||||
GfxCommon_UpdateDynamicVb_IndexedTris(ModelCache_Vb, vertices, index);
|
||||
}
|
||||
|
||||
void StatusScreen_UpdateHackState(StatusScreen* screen, bool force) {
|
||||
HacksComp* hacks = &LocalPlayer_Instance.Hacks;
|
||||
if (force || hacks->Speeding != screen->Speeding || hacks->HalfSpeeding != screen->HalfSpeeding
|
||||
|| hacks->Noclip != screen->Noclip || hacks->Flying != screen->Fly || Game_Fov != screen->LastFov) {
|
||||
screen->Speeding = hacks->Speeding; screen->Noclip = hacks->Noclip;
|
||||
screen->HalfSpeeding = hacks->HalfSpeeding; screen->Fly = hacks->Flying;
|
||||
screen->LastFov = Game_Fov;
|
||||
|
||||
UInt8 statusBuffer[String_BufferSize(STRING_SIZE * 2)];
|
||||
String status = String_InitAndClearArray(statusBuffer);
|
||||
|
||||
if (Game_Fov != Game_DefaultFov) {
|
||||
String_AppendConst(&status, "Zoom fov ");
|
||||
String_AppendInt32(&status, Game_Fov);
|
||||
String_AppendConst(&status, " ");
|
||||
}
|
||||
if (hacks->Flying) String_AppendConst(&status, "Fly ON ");
|
||||
|
||||
bool speed = (hacks->Speeding || hacks->HalfSpeeding) && (hacks->CanSpeed || hacks->BaseHorSpeed > 1);
|
||||
if (speed) String_AppendConst(&status, "Speed ON ");
|
||||
if (hacks->Noclip) String_AppendConst(&status, "Noclip ON ");
|
||||
|
||||
TextWidget_SetText(&screen->HackStates, &status);
|
||||
}
|
||||
}
|
||||
|
||||
void StatusScreen_Update(StatusScreen* screen, Real64 delta) {
|
||||
screen->Frames++;
|
||||
screen->Accumulator += delta;
|
||||
@ -335,24 +391,6 @@ void StatusScreen_Update(StatusScreen* screen, Real64 delta) {
|
||||
Game_ChunkUpdates = 0;
|
||||
}
|
||||
|
||||
void StatusScreen_Render(GuiElement* elem, Real64 delta) {
|
||||
StatusScreen* screen = (StatusScreen*)elem;
|
||||
StatusScreen_Update(screen, delta);
|
||||
if (Game_HideGui || !Game_ShowFPS) return;
|
||||
|
||||
Gfx_SetTexturing(true);
|
||||
elem = &screen->Status.Base.Base;
|
||||
elem->Render(elem, delta);
|
||||
|
||||
if (!Game_ClassicMode && Gui_Active == NULL) {
|
||||
StatusScreen_UpdateHackState(screen, false);
|
||||
StatusScreen_DrawPosition(screen);
|
||||
elem = &screen->HackStates.Base.Base;
|
||||
elem->Render(elem, delta);
|
||||
}
|
||||
Gfx_SetTexturing(false);
|
||||
}
|
||||
|
||||
void StatusScreen_OnResize(Screen* screen) { }
|
||||
void StatusScreen_ChatFontChanged(void* obj) {
|
||||
StatusScreen* screen = (StatusScreen*)obj;
|
||||
@ -403,6 +441,24 @@ void StatusScreen_Init(GuiElement* elem) {
|
||||
Event_RegisterVoid(&GfxEvents_ContextRecreated, screen, StatusScreen_ContextRecreated);
|
||||
}
|
||||
|
||||
void StatusScreen_Render(GuiElement* elem, Real64 delta) {
|
||||
StatusScreen* screen = (StatusScreen*)elem;
|
||||
StatusScreen_Update(screen, delta);
|
||||
if (Game_HideGui || !Game_ShowFPS) return;
|
||||
|
||||
Gfx_SetTexturing(true);
|
||||
elem = &screen->Status.Base.Base;
|
||||
elem->Render(elem, delta);
|
||||
|
||||
if (!Game_ClassicMode && Gui_Active == NULL) {
|
||||
StatusScreen_UpdateHackState(screen, false);
|
||||
StatusScreen_DrawPosition(screen);
|
||||
elem = &screen->HackStates.Base.Base;
|
||||
elem->Render(elem, delta);
|
||||
}
|
||||
Gfx_SetTexturing(false);
|
||||
}
|
||||
|
||||
void StatusScreen_Free(GuiElement* elem) {
|
||||
StatusScreen* screen = (StatusScreen*)elem;
|
||||
Platform_FreeFont(&screen->Font);
|
||||
@ -413,57 +469,6 @@ void StatusScreen_Free(GuiElement* elem) {
|
||||
Event_UnregisterVoid(&GfxEvents_ContextRecreated, screen, StatusScreen_ContextRecreated);
|
||||
}
|
||||
|
||||
void StatusScreen_DrawPosition(StatusScreen* screen) {
|
||||
TextAtlas* atlas = &screen->PosAtlas;
|
||||
VertexP3fT2fC4b vertices[4 * 8];
|
||||
VertexP3fT2fC4b* ptr = vertices;
|
||||
|
||||
Texture tex = atlas->Tex; tex.X = 2; tex.Width = (UInt16)atlas->Offset;
|
||||
PackedCol col = PACKEDCOL_WHITE;
|
||||
GfxCommon_Make2DQuad(&tex, col, &ptr);
|
||||
|
||||
Vector3I pos; Vector3I_Floor(&pos, &LocalPlayer_Instance.Base.Base.Position);
|
||||
atlas->CurX = atlas->Offset + 2;
|
||||
|
||||
TextAtlas_Add(atlas, 13, &ptr);
|
||||
TextAtlas_AddInt(atlas, pos.X, &ptr);
|
||||
TextAtlas_Add(atlas, 11, &ptr);
|
||||
TextAtlas_AddInt(atlas, pos.Y, &ptr);
|
||||
TextAtlas_Add(atlas, 11, &ptr);
|
||||
TextAtlas_AddInt(atlas, pos.Z, &ptr);
|
||||
TextAtlas_Add(atlas, 14, &ptr);
|
||||
|
||||
Gfx_BindTexture(atlas->Tex.ID);
|
||||
/* TODO: Do we need to use a separate VB here? */
|
||||
GfxCommon_UpdateDynamicVb_IndexedTris(game.ModelCache.vb, vertices, index);
|
||||
}
|
||||
|
||||
void StatusScreen_UpdateHackState(StatusScreen* screen, bool force) {
|
||||
HacksComp* hacks = &LocalPlayer_Instance.Hacks;
|
||||
if (force || hacks->Speeding != screen->Speeding || hacks->HalfSpeeding != screen->HalfSpeeding
|
||||
|| hacks->Noclip != screen->Noclip || hacks->Flying != screen->Fly || Game_Fov != screen->LastFov) {
|
||||
screen->Speeding = hacks->Speeding; screen->Noclip = hacks->Noclip;
|
||||
screen->HalfSpeeding = hacks->HalfSpeeding; screen->Fly = hacks->Flying;
|
||||
screen->LastFov = Game_Fov;
|
||||
|
||||
UInt8 statusBuffer[String_BufferSize(STRING_SIZE * 2)];
|
||||
String status = String_InitAndClearArray(statusBuffer);
|
||||
|
||||
if (Game_Fov != Game_DefaultFov) {
|
||||
String_AppendConst(&status, "Zoom fov ");
|
||||
String_AppendInt32(&status, Game_Fov);
|
||||
String_AppendConst(&status, " ");
|
||||
}
|
||||
if (hacks->Flying) String_AppendConst(&status, "Fly ON ");
|
||||
|
||||
bool speed = (hacks->Speeding || hacks->HalfSpeeding) && (hacks->CanSpeed || hacks->BaseHorSpeed > 1);
|
||||
if (speed) String_AppendConst(&status, "Speed ON ");
|
||||
if (hacks->Noclip) String_AppendConst(&status, "Noclip ON ");
|
||||
|
||||
TextWidget_SetText(&screen->HackStates, &status);
|
||||
}
|
||||
}
|
||||
|
||||
Screen* StatusScreen_MakeInstance(void) {
|
||||
StatusScreen* screen = &StatusScreen_Instance;
|
||||
Platform_MemSet(&screen, 0, sizeof(StatusScreen));
|
||||
@ -746,41 +751,44 @@ bool LoadingScreen_HandlesMouseUp(GuiElement* elem, Int32 x, Int32 y, MouseButto
|
||||
bool LoadingScreen_HandlesMouseMove(GuiElement* elem, Int32 x, Int32 y) { return true; }
|
||||
bool LoadingScreen_HandlesMouseScroll(GuiElement* elem, Real32 delta) { return true; }
|
||||
|
||||
void DrawBackground() {
|
||||
VertexP3fT2fC4b[] vertices = game.ModelCache.vertices;
|
||||
int index = 0, atlasIndex = 0;
|
||||
Int32 drawnY = 0;
|
||||
void LoadingScreen_UpdateBackgroundVB(VertexP3fT2fC4b* vertices, Int32 count, Int32 atlasIndex, bool* bound) {
|
||||
if (!(*bound)) {
|
||||
*bound = true;
|
||||
Gfx_BindTexture(Atlas1D_TexIds[atlasIndex]);
|
||||
}
|
||||
|
||||
Gfx_SetBatchFormat(VERTEX_FORMAT_P3FT2FC4B);
|
||||
/* TODO: Do we need to use a separate VB here? */
|
||||
GfxCommon_UpdateDynamicVb_IndexedTris(ModelCache_Vb, vertices, count);
|
||||
}
|
||||
|
||||
#define LOADING_TILE_SIZE 64
|
||||
void LoadingScreen_DrawBackground(void) {
|
||||
VertexP3fT2fC4b vertices[144];
|
||||
VertexP3fT2fC4b* ptr = vertices;
|
||||
Int32 count = 0, atlasIndex = 0, y = 0;
|
||||
PackedCol col = PACKEDCOL_CONST(64, 64, 64, 255);
|
||||
|
||||
TextureLoc texLoc = Block_GetTexLoc(BLOCK_DIRT, FACE_YMAX);
|
||||
TerrainAtlas1D atlas = game.TerrainAtlas1D;
|
||||
Texture tex = new Texture(0, 0, 0, game.Width, 64,
|
||||
atlas.GetTexRec(texLoc, 1, out atlasIndex));
|
||||
tex.U2 = (float)game.Width / 64;
|
||||
TextureRec rec = Atlas1D_TexRec(texLoc, 1, &atlasIndex);
|
||||
Texture tex = Texture_FromRec(0, 0, 0, Game_Width, LOADING_TILE_SIZE, rec);
|
||||
tex.U2 = (Real32)Game_Width / (Real32)LOADING_TILE_SIZE;
|
||||
|
||||
bool bound = false;
|
||||
while (y < Game_Height) {
|
||||
tex.Y = (Int16)y;
|
||||
y += LOADING_TILE_SIZE;
|
||||
GfxCommon_Make2DQuad(&tex, col, &ptr);
|
||||
count += 4;
|
||||
|
||||
while (drawnY < Game_Height) {
|
||||
tex.Y1 = drawnY;
|
||||
IGraphicsApi.Make2DQuad(ref tex, col, vertices, ref index);
|
||||
if (index >= vertices.Length) {
|
||||
DrawBackgroundVertices(ref index, atlasIndex, ref bound);
|
||||
}
|
||||
drawnY += 64;
|
||||
}
|
||||
DrawBackgroundVertices(ref index, atlasIndex, ref bound);
|
||||
}
|
||||
|
||||
void DrawBackgroundVertices(ref int index, int atlasIndex, ref bool bound) {
|
||||
if (index == 0) return;
|
||||
if (!bound) {
|
||||
bound = true;
|
||||
gfx.BindTexture(game.TerrainAtlas1D.TexIds[atlasIndex]);
|
||||
if (count < Array_NumElements(vertices)) continue;
|
||||
LoadingScreen_UpdateBackgroundVB(vertices, count, atlasIndex, &bound);
|
||||
count = 0;
|
||||
ptr = vertices;
|
||||
}
|
||||
|
||||
ModelCache cache = game.ModelCache;
|
||||
Gfx_SetBatchFormat(VERTEX_FORMAT_P3FT2FC4B);
|
||||
gfx.UpdateDynamicVb_IndexedTris(cache.vb, cache.vertices, index);
|
||||
index = 0;
|
||||
if (count == 0) return;
|
||||
LoadingScreen_UpdateBackgroundVB(vertices, count, atlasIndex, &bound);
|
||||
}
|
||||
|
||||
void LoadingScreen_Init(GuiElement* elem) {
|
||||
@ -798,7 +806,7 @@ void LoadingScreen_Init(GuiElement* elem) {
|
||||
void LoadingScreen_Render(GuiElement* elem, Real64 delta) {
|
||||
LoadingScreen* screen = (LoadingScreen*)elem;
|
||||
Gfx_SetTexturing(true);
|
||||
LoadingMapScreen_DrawBackground();
|
||||
LoadingScreen_DrawBackground();
|
||||
elem = &screen->TitleWidget.Base.Base; elem->Render(elem, delta);
|
||||
elem = &screen->MessageWidget.Base.Base; elem->Render(elem, delta);
|
||||
Gfx_SetTexturing(false);
|
||||
@ -809,8 +817,8 @@ void LoadingScreen_Render(GuiElement* elem, Real64 delta) {
|
||||
|
||||
PackedCol backCol = PACKEDCOL_CONST(128, 128, 128, 255);
|
||||
PackedCol progCol = PACKEDCOL_CONST(128, 255, 128, 255);
|
||||
GfxCommon_Draw2DQuadFlat(x, y, PROG_BAR_WIDTH, PROG_BAR_HEIGHT, backCol);
|
||||
GfxCommon_Draw2DQuadFlat(x, y, progWidth, PROG_BAR_HEIGHT, progCol);
|
||||
GfxCommon_Draw2DFlat(x, y, PROG_BAR_WIDTH, PROG_BAR_HEIGHT, backCol);
|
||||
GfxCommon_Draw2DFlat(x, y, progWidth, PROG_BAR_HEIGHT, progCol);
|
||||
}
|
||||
|
||||
void LoadingScreen_Free(GuiElement* elem) {
|
||||
@ -823,7 +831,7 @@ void LoadingScreen_Free(GuiElement* elem) {
|
||||
Event_UnregisterVoid(&GfxEvents_ContextRecreated, screen, LoadingScreen_ContextRecreated);
|
||||
}
|
||||
|
||||
Screen* LoadingScreen_MakeInstance(STRING_PURE String* title, STRING_PURE String* message) {
|
||||
void LoadingScreen_Make(LoadingScreen* screen, STRING_PURE String* title, STRING_PURE String* message) {
|
||||
LoadingScreen* screen = &LoadingScreen_Instance;
|
||||
Platform_MemSet(&screen, 0, sizeof(LoadingScreen));
|
||||
Screen_Reset(&screen->Base);
|
||||
@ -849,26 +857,43 @@ Screen* LoadingScreen_MakeInstance(STRING_PURE String* title, STRING_PURE String
|
||||
screen->Base.BlocksWorld = true;
|
||||
screen->Base.RenderHUDOver = true;
|
||||
screen->Base.HandlesAllInput = true;
|
||||
}
|
||||
|
||||
Screen* LoadingScreen_MakeInstance(STRING_PURE String* title, STRING_PURE String* message) {
|
||||
LoadingScreen* screen = &LoadingScreen_Instance;
|
||||
LoadingScreen_Make(screen, title, message);
|
||||
return &screen->Base;
|
||||
}
|
||||
|
||||
public class GeneratingMapScreen : LoadingScreen {
|
||||
|
||||
string lastState;
|
||||
IMapGenerator gen;
|
||||
public GeneratingMapScreen(Game game, IMapGenerator gen) : base(game, "Generating level", "Generating..") {
|
||||
this.gen = gen;
|
||||
}
|
||||
typedef struct GeneratingMapScreen_ {
|
||||
LoadingScreen Base;
|
||||
String LastState;
|
||||
UInt8 LastStateBuffer[String_BufferSize(STRING_SIZE)];
|
||||
} GeneratingMapScreen;
|
||||
GeneratingMapScreen GeneratingMapScreen_Instance;
|
||||
|
||||
public override void Render(double delta) {
|
||||
base.Render(delta);
|
||||
if (gen.Done) { game.Server.EndGeneration(); return; }
|
||||
void GeneratingScreen_Render(GuiElement* elem, Real64 delta) {
|
||||
GeneratingMapScreen* screen = (GeneratingMapScreen*)elem;
|
||||
LoadingScreen_Render(elem, delta);
|
||||
if (Gen_Done) { ServerConnection_EndGeneration(); return; }
|
||||
|
||||
string state = gen.CurrentState;
|
||||
SetProgress(gen.CurrentProgress);
|
||||
if (state == lastState) return;
|
||||
String state = Gen_CurrentState;
|
||||
screen->Base.Progress = Gen_CurrentProgress;
|
||||
if (String_Equals(&state, &screen->LastState)) return;
|
||||
|
||||
lastState = state;
|
||||
SetMessage(state);
|
||||
}
|
||||
String_Clear(&screen->LastState);
|
||||
String_AppendString(&screen->LastState, &state);
|
||||
LoadingScreen_SetMessage(&screen->Base, &state);
|
||||
}
|
||||
|
||||
Screen* GeneratingScreen_MakeInstance(void) {
|
||||
GeneratingMapScreen* screen = &GeneratingMapScreen_Instance;
|
||||
String title = String_FromConst("Generating level");
|
||||
String message = String_FromConst("Generating..");
|
||||
LoadingScreen_Make(&screen->Base, &title, &message);
|
||||
|
||||
screen->Base.Base.Base.Render = GeneratingScreen_Render;
|
||||
screen->LastState = String_InitAndClearArray(screen->LastStateBuffer);
|
||||
return &screen->Base.Base;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user