diff --git a/misc/ps1/ps1defs.h b/misc/ps1/ps1defs.h index b92c8677e..d087eed06 100644 --- a/misc/ps1/ps1defs.h +++ b/misc/ps1/ps1defs.h @@ -2,6 +2,12 @@ // and so takes less cycles to access #define SCRATCHPAD_MEM ((cc_uint8*)0x1F800000) +// === GTE COMMANDS === +#define GTE_SetTransX(value) __asm__ volatile("ctc2 %0, $5;" :: "r" (value) : ) +#define GTE_SetTransY(value) __asm__ volatile("ctc2 %0, $6;" :: "r" (value) : ) +#define GTE_SetTransZ(value) __asm__ volatile("ctc2 %0, $7;" :: "r" (value) : ); + +// === DMA REGISTERS === enum dma_chrc_flags { CHRC_STATUS_BUSY = (1 << 24), }; @@ -15,12 +21,14 @@ enum dma_chrc_CMD { CHRC_NO_DREQ_WAIT = (1 << 28), }; +// === GPU REGISTERS === enum gpu_status_flags { GPU_STATUS_CMD_READY = (1 << 26), GPU_STATUS_DMA_RECV_READY = (1 << 28), }; +// === GP0 COMMANDS === enum gp0_cmd_type { GP0_CMD_CLEAR_VRAM_CACHE = 0x01000000, GP0_CMD_MEM_FILL = 0x02000000, @@ -44,6 +52,20 @@ enum gp0_rectcmd_flags { RECT_CMD_1x1 = 1u << 27, }; +#define PACK_RGBC(r, g, b, c) ( (r) | ((g) << 8) | ((b) << 16) | (c) ) + +#define GP0_CMD_DRAW_MIN_PACK(x, y) ( GP0_CMD_DRAW_AREA_MIN | ((x) & 0x3FF) | (((y) & 0x3FF) << 10) ) +#define GP0_CMD_DRAW_MAX_PACK(x, y) ( GP0_CMD_DRAW_AREA_MAX | ((x) & 0x3FF) | (((y) & 0x3FF) << 10) ) + +#define GP0_CMD_DRAW_OFFSET_PACK(x, y) ( GP0_CMD_DRAW_AREA_OFFSET | ((x) & 0x7FF) | (((y) & 0x7FF) << 11) ) + +#define GP0_CMD_FILL_XY(x, y) ( ((x) & 0xFFFF) | (((y) & 0xFFFF) << 16) ) +#define GP0_CMD_FILL_WH(w, h) ( ((w) & 0xFFFF) | (((h) & 0xFFFF) << 16) ) + +#define GP0_CMD_CLUT_XY(x, y) ( ((x) & 0x3F) | (((y) & 0x1FF) << 6) ) + + +// === GP1 COMMANDS === enum gp1_cmd_type { GP1_CMD_RESET_GPU = 0x00000000, GP1_CMD_DISPLAY_ACTIVE = 0x03000000, @@ -69,24 +91,10 @@ enum gp1_cmd_display_mode { GP1_VER_RES_240 = 0 << 2, }; - -// === MISC COMMANDS === -#define GP0_CMD_DRAW_MIN_PACK(x, y) ( GP0_CMD_DRAW_AREA_MIN | ((x) & 0x3FF) | (((y) & 0x3FF) << 10) ) -#define GP0_CMD_DRAW_MAX_PACK(x, y) ( GP0_CMD_DRAW_AREA_MAX | ((x) & 0x3FF) | (((y) & 0x3FF) << 10) ) - -#define GP0_CMD_DRAW_OFFSET_PACK(x, y) ( GP0_CMD_DRAW_AREA_OFFSET | ((x) & 0x7FF) | (((y) & 0x7FF) << 11) ) - #define GP1_CMD_DISPLAY_ADDRESS_XY(x, y) ( ((x) & 0x3FF) | (((y) & 0x1FF) << 10) ) -#define GP0_CMD_FILL_XY(x, y) ( ((x) & 0xFFFF) | (((y) & 0xFFFF) << 16) ) -#define GP0_CMD_FILL_WH(w, h) ( ((w) & 0xFFFF) | (((h) & 0xFFFF) << 16) ) -#define PACK_RGBC(r, g, b, c) ( (r) | ((g) << 8) | ((b) << 16) | (c) ) - -#define GP0_CMD_CLUT_XY(x, y) ( ((x) & 0x3F) | (((y) & 0x1FF) << 6) ) - - -// === POLYGON COMMANDS === +// === GP0 POLYGON COMMANDS === #define POLY_CODE_F4 (GP0_CMD_POLYGON | POLY_CMD_QUAD) #define POLY_LEN_F4 5 struct PSX_POLY_F4 { diff --git a/src/Entity.c b/src/Entity.c index ed03bb638..a581d2855 100644 --- a/src/Entity.c +++ b/src/Entity.c @@ -515,7 +515,7 @@ int Entities_GetClosest(struct Entity* src) { if (!e || e == &Entities.CurPlayer->Base) continue; if (!Intersection_RayIntersectsRotatedBox(eyePos, dir, e, &t0, &t1)) continue; - if (targetID == -1 || t0 < closestDist) { + if (targetID < 0 || t0 < closestDist) { closestDist = t0; targetID = i; } diff --git a/src/Graphics.h b/src/Graphics.h index 20182700d..a16bce418 100644 --- a/src/Graphics.h +++ b/src/Graphics.h @@ -347,9 +347,14 @@ USAGE NOTES: is setup to draw groups of 2 triangles from 4 vertices (1 quad) */ +/* Optional draw hints used by some rendering backends to speed up 2D drawing */ typedef enum DrawHints_ { DRAW_HINT_NONE = 0, - DRAW_HINT_SPRITE = 9, + /* Vertices are 2D rects with possible texture scaling and/or repeating */ + DRAW_HINT_SPRITE = 0x02, + /* Vertices are 2D rects with no texture scaling or repeating */ + /* Typically this is only used for textures purely containing text */ + DRAW_HINT_RECT = 0x04, } DrawHints; /* Sets the format of the rendered vertices */ diff --git a/src/Graphics_PS1.c b/src/Graphics_PS1.c index b1294cdd7..e47e58d4a 100644 --- a/src/Graphics_PS1.c +++ b/src/Graphics_PS1.c @@ -249,42 +249,23 @@ void Gfx_TransferToVRAM(int x, int y, int w, int h, void* pixels) { // 10 texture pages are occupied by the doublebuffered display // 22 texture pages are usable for textures // These 22 pages are then divided into: -// - 5 for 128+ wide horizontal, 6 otherwise -// - 11 pages for vertical textures +// - 4,4,3 pages for horizontal textures +// - 4,4,3 pages for vertical textures #define TPAGE_WIDTH 64 #define TPAGE_HEIGHT 256 #define TPAGES_PER_HALF 16 -// Horizontally oriented textures (first group of 16) -#define TPAGE_START_HOR 5 -#define MAX_HOR_TEX_PAGES 11 -#define MAX_HOR_TEX_LINES (MAX_HOR_TEX_PAGES * TPAGE_HEIGHT) +#define MAX_TEX_GROUPS 3 +#define TEX_GROUP_LINES 256 +#define MAX_TEX_LINES (MAX_TEX_GROUPS * TEX_GROUP_LINES) -// Horizontally oriented textures (second group of 16) -#define TPAGE_START_VER (16 + 5) -#define MAX_VER_TEX_PAGES 11 -#define MAX_VER_TEX_LINES (MAX_VER_TEX_PAGES * TPAGE_WIDTH) - -static cc_uint8 vram_used[(MAX_HOR_TEX_LINES + MAX_VER_TEX_LINES) / 8]; +static cc_uint8 vram_used[(MAX_TEX_LINES + MAX_TEX_LINES) / 8]; #define VRAM_SetUsed(line) (vram_used[(line) / 8] |= (1 << ((line) % 8))) #define VRAM_UnUsed(line) (vram_used[(line) / 8] &= ~(1 << ((line) % 8))) #define VRAM_IsUsed(line) (vram_used[(line) / 8] & (1 << ((line) % 8))) #define VRAM_BoundingAxis(width, height) height > width ? width : height -static void VRAM_GetBlockRange(int width, int height, int* beg, int* end) { - if (height > width) { - *beg = MAX_HOR_TEX_LINES; - *end = MAX_HOR_TEX_LINES + MAX_VER_TEX_LINES; - } else if (width >= 128) { - *beg = 0; - *end = 5 * TPAGE_HEIGHT; - } else { - *beg = 5 * TPAGE_HEIGHT; - *end = MAX_HOR_TEX_LINES; - } -} - static cc_bool VRAM_IsRangeFree(int beg, int end) { for (int i = beg; i < end; i++) { @@ -293,16 +274,33 @@ static cc_bool VRAM_IsRangeFree(int beg, int end) { return true; } -static int VRAM_FindFreeBlock(int width, int height) { - int beg, end; - VRAM_GetBlockRange(width, height, &beg, &end); - +static int VRAM_FindFreeLines(int group, int lines) { + int beg = group * TEX_GROUP_LINES; + int end = beg + TEX_GROUP_LINES; + // TODO kinda inefficient - for (int i = beg; i < end - height; i++) + for (int i = beg; i < end - lines; i++) { if (VRAM_IsUsed(i)) continue; - if (VRAM_IsRangeFree(i, i + height)) return i; + if (VRAM_IsRangeFree(i, i + lines)) return i; + } + return -1; +} + +static int VRAM_FindFreeBlock(int width, int height) { + int l; + + if (height > width) { + // Vertically oriented texture + if ((l = VRAM_FindFreeLines(3, width)) >= 0) return l; + if ((l = VRAM_FindFreeLines(4, width)) >= 0) return l; + if ((l = VRAM_FindFreeLines(5, width)) >= 0) return l; + } else { + // Horizontally oriented texture + if ((l = VRAM_FindFreeLines(0, height)) >= 0) return l; + if ((l = VRAM_FindFreeLines(1, height)) >= 0) return l; + if ((l = VRAM_FindFreeLines(2, height)) >= 0) return l; } return -1; } @@ -323,11 +321,15 @@ static void VRAM_FreeBlock(int line, int width, int height) { } } +#define TPAGE_START_HOR 5 +#define TPAGE_START_VER 21 + static int VRAM_CalcPage(int line) { - if (line < MAX_HOR_TEX_LINES) { - return TPAGE_START_HOR + (line / TPAGE_HEIGHT); + if (line < TEX_GROUP_LINES * MAX_TEX_GROUPS) { + int group = line / TPAGE_HEIGHT; + return TPAGE_START_HOR + (group * 4); } else { - line -= MAX_HOR_TEX_LINES; + line -= TEX_GROUP_LINES * MAX_TEX_GROUPS; return TPAGE_START_VER + (line / TPAGE_WIDTH); } } @@ -713,17 +715,17 @@ void Gfx_DeleteDynamicVb(GfxResourceID* vb) { Gfx_DeleteVb(vb); } *---------------------------------------------------------Matrices--------------------------------------------------------* *#########################################################################################################################*/ static struct Matrix _view, _proj; -static MATRIX transform_matrix; -#define ToFixed(v) (int)(v * (1 << 12)) +#define ToFixed(v) (int)(v * (1 << 12)) #define ToFixedTr(v) (int)(v * (1 << 8)) static void LoadTransformMatrix(struct Matrix* src) { + MATRIX transform_matrix; // Use w instead of z // (row123.z = row123.w, only difference is row4.z/w being different) - transform_matrix.t[0] = ToFixedTr(src->row4.x); - transform_matrix.t[1] = ToFixedTr(-src->row4.y); - transform_matrix.t[2] = ToFixedTr(src->row4.w); + GTE_SetTransX(ToFixedTr( src->row4.x)); + GTE_SetTransY(ToFixedTr(-src->row4.y)); + GTE_SetTransZ(ToFixedTr( src->row4.w)); transform_matrix.m[0][0] = ToFixed(src->row1.x); @@ -739,7 +741,6 @@ static void LoadTransformMatrix(struct Matrix* src) { transform_matrix.m[2][2] = ToFixed(src->row3.w); gte_SetRotMatrix(&transform_matrix); - gte_SetTransMatrix(&transform_matrix); } void Gfx_LoadMatrix(MatrixType type, const struct Matrix* matrix) { diff --git a/src/Graphics_SoftGPU.c b/src/Graphics_SoftGPU.c index 156834a82..3ddcba7ad 100644 --- a/src/Graphics_SoftGPU.c +++ b/src/Graphics_SoftGPU.c @@ -384,7 +384,7 @@ static CC_INLINE int FastFloor(float value) { return valueI > value ? valueI - 1 : valueI; } -static void DrawSprite2D(Vertex* V0, Vertex* V1, Vertex* V2) { +static void DrawSprite2D(Vertex* V0, Vertex* V1, Vertex* V2, int hints) { PackedCol vColor = V0->c; int minX = (int)V0->x; int minY = (int)V0->y; @@ -961,7 +961,7 @@ void DrawQuads(int startVertex, int verticesCount, DrawHints hints) { Vertex vertices[4]; int j = startVertex; - if (gfx_rendering2D && hints == DRAW_HINT_SPRITE) { + if (gfx_rendering2D && (hints & (DRAW_HINT_SPRITE|DRAW_HINT_RECT))) { // 4 vertices = 1 quad = 2 triangles for (int i = 0; i < verticesCount / 4; i++, j += 4) { diff --git a/src/Menus.c b/src/Menus.c index db0811ca0..edf9e42f1 100644 --- a/src/Menus.c +++ b/src/Menus.c @@ -2632,7 +2632,7 @@ static void TexIdsOverlay_Render(void* screen, float delta) { offset = TexIdsOverlay_RenderTerrain(s, offset); Gfx_BindTexture(s->idAtlas.tex.ID); - Gfx_DrawVb_IndexedTris_Range(s->textVertices, offset, DRAW_HINT_SPRITE); + Gfx_DrawVb_IndexedTris_Range(s->textVertices, offset, DRAW_HINT_RECT); } static int TexIdsOverlay_KeyDown(void* screen, int key, struct InputDevice* device) { diff --git a/src/Screens.c b/src/Screens.c index 51946392c..8de67e047 100644 --- a/src/Screens.c +++ b/src/Screens.c @@ -400,7 +400,7 @@ static void HUDScreen_Render(void* screen, float delta) { } else if (IsOnlyChatActive() && Gui.ShowFPS) { Widget_Render2(&s->line2, 8); Gfx_BindTexture(s->posAtlas.tex.ID); - Gfx_DrawVb_IndexedTris_Range(s->posCount, 12 + HOTBAR_MAX_VERTICES, DRAW_HINT_SPRITE); + Gfx_DrawVb_IndexedTris_Range(s->posCount, 12 + HOTBAR_MAX_VERTICES, DRAW_HINT_RECT); /* TODO swap these two lines back */ } @@ -845,7 +845,7 @@ static void TabListOverlay_Render(void* screen, float delta) { if (!s->textures[i].ID) continue; Gfx_BindTexture(s->textures[i].ID); - Gfx_DrawVb_IndexedTris_Range(4, offset, DRAW_HINT_SPRITE); + Gfx_DrawVb_IndexedTris_Range(4, offset, DRAW_HINT_RECT); offset += 4; } @@ -1176,7 +1176,7 @@ static void ChatScreen_DrawChat(struct ChatScreen* s, float delta) { if (Chat_GetLogTime(logIdx) + 10 < now) continue; Gfx_BindTexture(texID); - Gfx_DrawVb_IndexedTris_Range(4, i * 4, DRAW_HINT_SPRITE); + Gfx_DrawVb_IndexedTris_Range(4, i * 4, DRAW_HINT_RECT); } } @@ -1949,7 +1949,7 @@ static void LoadingScreen_Render(void* screen, float delta) { if (s->rows) { loc = Block_Tex(BLOCK_DIRT, FACE_YMAX); Atlas1D_Bind(Atlas1D_Index(loc)); - Gfx_DrawVb_IndexedTris_Range(s->rows * 4, 0, DRAW_HINT_SPRITE); + Gfx_DrawVb_IndexedTris_Range(s->rows * 4, 0, 0); offset = s->rows * 4; } diff --git a/src/Server.c b/src/Server.c index 0fc50fdb8..f6fea3c60 100644 --- a/src/Server.c +++ b/src/Server.c @@ -241,7 +241,7 @@ static double net_lastPacket; static cc_uint8 lastOpcode; static cc_bool net_connecting; -static double net_connectTimeout; +static float net_connectElapsed; #define NET_TIMEOUT_SECS 15 static void MPConnection_FinishConnect(void) { @@ -276,20 +276,20 @@ static void MPConnection_FailConnect(cc_result result) { MPConnection_Fail(&reason); } -static void MPConnection_TickConnect(void) { +static void MPConnection_TickConnect(struct ScheduledTask* task) { cc_bool writable; - double now = Game.Time; cc_result res = Socket_CheckWritable(net_socket, &writable); + net_connectElapsed += task->interval; if (res) { MPConnection_FailConnect(res); } else if (writable) { MPConnection_FinishConnect(); - } else if (now > net_connectTimeout) { + } else if (net_connectElapsed > NET_TIMEOUT_SECS) { MPConnection_FailConnect(0); } else { - double left = net_connectTimeout - now; - Event_RaiseFloat(&WorldEvents.Loading, (float)left / NET_TIMEOUT_SECS); + float left = NET_TIMEOUT_SECS - net_connectElapsed; + Event_RaiseFloat(&WorldEvents.Loading, left / NET_TIMEOUT_SECS); } } @@ -325,7 +325,7 @@ static void MPConnection_BeginConnect(void) { } else { Server.Disconnected = false; net_connecting = true; - net_connectTimeout = Game.Time + NET_TIMEOUT_SECS; + net_connectElapsed = 0; String_Format2(&title, "Connecting to %s:%i..", &Server.Address, &Server.Port); LoadingScreen_Show(&title, &String_Empty); @@ -386,7 +386,7 @@ static void MPConnection_Tick(struct ScheduledTask* task) { cc_result res; if (Server.Disconnected) return; - if (net_connecting) { MPConnection_TickConnect(); return; } + if (net_connecting) { MPConnection_TickConnect(task); return; } /* NOTE: using a read call that is a multiple of 4096 (appears to?) improve read performance */ res = Socket_Read(net_socket, net_readCurrent, 4096 * 4, &read); diff --git a/src/Widgets.c b/src/Widgets.c index 293156870..63629681b 100644 --- a/src/Widgets.c +++ b/src/Widgets.c @@ -61,7 +61,7 @@ static int TextWidget_Render2(void* widget, int offset) { struct TextWidget* w = (struct TextWidget*)widget; if (w->tex.ID) { Gfx_BindTexture(w->tex.ID); - Gfx_DrawVb_IndexedTris_Range(4, offset, DRAW_HINT_SPRITE); + Gfx_DrawVb_IndexedTris_Range(4, offset, DRAW_HINT_RECT); } return offset + 4; } @@ -1592,12 +1592,12 @@ static void TextInputWidget_BuildMesh(void* widget, struct VertexTextured** vert static int TextInputWidget_Render2(void* widget, int offset) { struct InputWidget* w = (struct InputWidget*)widget; Gfx_BindTexture(w->inputTex.ID); - Gfx_DrawVb_IndexedTris_Range(4, offset, DRAW_HINT_SPRITE); + Gfx_DrawVb_IndexedTris_Range(4, offset, DRAW_HINT_RECT); offset += 4; if (w->showCaret && Math_Mod1((float)w->caretAccumulator) < 0.5f) { Gfx_BindTexture(w->caretTex.ID); - Gfx_DrawVb_IndexedTris_Range(4, offset, DRAW_HINT_SPRITE); + Gfx_DrawVb_IndexedTris_Range(4, offset, DRAW_HINT_RECT); } return offset + 4; } @@ -2455,7 +2455,7 @@ static int TextGroupWidget_Render2(void* widget, int offset) { if (!textures[i].ID) continue; Gfx_BindTexture(textures[i].ID); - Gfx_DrawVb_IndexedTris_Range(4, offset, DRAW_HINT_SPRITE); + Gfx_DrawVb_IndexedTris_Range(4, offset, DRAW_HINT_RECT); } return offset; }