PS1: Onscreen keyboard texture works

This commit is contained in:
UnknownShadow200 2025-03-15 19:43:58 +11:00
parent 587dfd1eea
commit 400c3b568d
9 changed files with 90 additions and 76 deletions

View File

@ -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 {

View File

@ -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;
}

View File

@ -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 */

View File

@ -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) {

View File

@ -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)
{

View File

@ -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) {

View File

@ -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;
}

View File

@ -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);

View File

@ -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;
}