mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-08 23:10:52 -04:00
PS1: Onscreen keyboard texture works
This commit is contained in:
parent
587dfd1eea
commit
400c3b568d
@ -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 {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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) {
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
16
src/Server.c
16
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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user