mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-12 09:06:55 -04:00
Merge branch 'ClassiCube:master' into wii-audio
This commit is contained in:
commit
1cb87ee034
4
.gitignore
vendored
4
.gitignore
vendored
@ -72,6 +72,10 @@ ClassiCube*
|
||||
screenshots
|
||||
fontscache.txt
|
||||
|
||||
# CMake files
|
||||
CMakeFiles/
|
||||
CMakeCache.txt
|
||||
|
||||
#GCC object files
|
||||
*.o
|
||||
|
||||
|
3
Makefile
3
Makefile
@ -138,6 +138,9 @@ vita:
|
||||
$(MAKE) -f misc/vita/Makefile PLAT=vita
|
||||
ps3:
|
||||
$(MAKE) -f misc/ps3/Makefile PLAT=ps3
|
||||
ps1:
|
||||
cmake --preset default misc/ps1
|
||||
cmake --build misc/ps1/build
|
||||
ps2:
|
||||
$(MAKE) -f misc/ps2/Makefile PLAT=ps2
|
||||
xbox:
|
||||
|
21
misc/ps1/CMakeLists.txt
Normal file
21
misc/ps1/CMakeLists.txt
Normal file
@ -0,0 +1,21 @@
|
||||
cmake_minimum_required(VERSION 3.21)
|
||||
|
||||
project(
|
||||
ClassiCube
|
||||
LANGUAGES C ASM
|
||||
VERSION 1.0.0
|
||||
DESCRIPTION "ClassiCube PS1 port"
|
||||
HOMEPAGE_URL "https://classicube.net"
|
||||
)
|
||||
|
||||
add_definitions(-DPLAT_PS1)
|
||||
file(GLOB _sources ../../src/*.c)
|
||||
|
||||
psn00bsdk_add_executable(template GPREL ${_sources})
|
||||
|
||||
psn00bsdk_add_cd_image(
|
||||
iso # Target name
|
||||
template # Output file name (= template.bin + template.cue)
|
||||
iso.xml # Path to config file
|
||||
DEPENDS template system.cnf
|
||||
)
|
26
misc/ps1/CMakePresets.json
Normal file
26
misc/ps1/CMakePresets.json
Normal file
@ -0,0 +1,26 @@
|
||||
{
|
||||
"version": 3,
|
||||
"cmakeMinimumRequired": {
|
||||
"major": 3,
|
||||
"minor": 21,
|
||||
"patch": 0
|
||||
},
|
||||
"configurePresets": [
|
||||
{
|
||||
"name": "default",
|
||||
"displayName": "Default configuration",
|
||||
"description": "Use this preset to build the project using PSn00bSDK.",
|
||||
"generator": "Ninja",
|
||||
"toolchainFile": "$env{PSN00BSDK_LIBS}/cmake/sdk.cmake",
|
||||
"binaryDir": "${sourceDir}/build",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Debug",
|
||||
"PSN00BSDK_TC": "",
|
||||
"PSN00BSDK_TARGET": "mipsel-none-elf"
|
||||
},
|
||||
"warnings": {
|
||||
"dev": false
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
83
misc/ps1/iso.xml
Normal file
83
misc/ps1/iso.xml
Normal file
@ -0,0 +1,83 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
This file is processed by CMake and used by mkpsxiso to build the CD image.
|
||||
|
||||
NOTE: all paths are relative to the build directory; if you want to include
|
||||
a file from the source tree, you'll have to prepend its path with
|
||||
${PROJECT_SOURCE_DIR}.
|
||||
-->
|
||||
<iso_project>
|
||||
<track type="data">
|
||||
<!--
|
||||
The "volume", "volume_set", "publisher", "data_preparer" and
|
||||
"copyright" strings below can be freely modified. The ISO9660
|
||||
specification, however, imposes the following limitations:
|
||||
|
||||
- "volume" and "volume_set" must be 32 characters or less, and can
|
||||
only contain uppercase letters, digits and underscores.
|
||||
- "publisher" and "data_preparer" can be up to 128 characters long
|
||||
and can additionally contain spaces and some special characters.
|
||||
- "copyright" should be a path to a file on the disc, even one that
|
||||
does not exist (but in practice it can be set to anything).
|
||||
|
||||
"system" and "application" must always be set to "PLAYSTATION" in
|
||||
order for the disc to be recognized as valid.
|
||||
-->
|
||||
<identifiers
|
||||
system ="PLAYSTATION"
|
||||
volume ="PSN00BSDK_TEMPLATE"
|
||||
volume_set ="PSN00BSDK_TEMPLATE"
|
||||
publisher ="MEIDOTEK"
|
||||
data_preparer ="PSN00BSDK ${PSN00BSDK_VERSION}"
|
||||
application ="PLAYSTATION"
|
||||
copyright ="README.TXT;1"
|
||||
/>
|
||||
|
||||
<!--
|
||||
You may optionally include a license file using the <license> tag.
|
||||
Some consoles, particularly Japanese or PAL models with a modchip,
|
||||
require the disc to contain valid license data and will refuse to
|
||||
boot if it is missing. License files are usually not required on
|
||||
US consoles or when booting via softmods or cheat cartridges.
|
||||
|
||||
License files are region-specific and are not distributed with
|
||||
PSn00bSDK for obvious reasons, but can be dumped from an official
|
||||
game using dumpsxiso or extracted from the Sony SDK.
|
||||
-->
|
||||
<!--<license file="${PROJECT_SOURCE_DIR}/license.dat" />-->
|
||||
|
||||
<!--
|
||||
Files and directories can be added to the disc by placing <file>
|
||||
and <dir> tags below. All file names are case-insensitive and must
|
||||
be in 8.3 format, i.e. no more than 8 characters for the name and 3
|
||||
for the optional extension. Directories cannot have extensions.
|
||||
|
||||
A boot configuration file (SYSTEM.CNF) or executable (PSX.EXE) must
|
||||
be present in the root directory. Due to BIOS limitations the root
|
||||
directory cannot hold more than 30 files or directories, and the
|
||||
entire disc must contain 45 directories or less. Subdirectories can
|
||||
contain any number of files.
|
||||
-->
|
||||
<directory_tree>
|
||||
<file name="SYSTEM.CNF" type="data" source="${PROJECT_SOURCE_DIR}/system.cnf" />
|
||||
<file name="TEMPLATE.EXE" type="data" source="template.exe" />
|
||||
<!--
|
||||
This file is only required if you are using dynamic linking
|
||||
(see the system/dynlink example). It contains the executable's
|
||||
symbol map and can be used to obtain the address of a function
|
||||
or global variable by its name.
|
||||
-->
|
||||
<!--<file name="TEMPLATE.MAP" type="data" source="template.map" />-->
|
||||
|
||||
<dummy sectors="1024"/>
|
||||
</directory_tree>
|
||||
</track>
|
||||
|
||||
<!--
|
||||
CD-DA tracks can be added to the CD image by using one or more <track>
|
||||
tags. The source attribute must be a path to an audio file in WAV, FLAC
|
||||
or MP3 format (using WAV or FLAC is highly recommended to preserve
|
||||
audio quality if you have a lossless copy of the source track).
|
||||
-->
|
||||
<!--<track type="audio" source="${PROJECT_SOURCE_DIR}/track2.wav" />-->
|
||||
</iso_project>
|
4
misc/ps1/system.cnf
Normal file
4
misc/ps1/system.cnf
Normal file
@ -0,0 +1,4 @@
|
||||
BOOT=cdrom:\template.exe;1
|
||||
TCB=4
|
||||
EVENT=10
|
||||
STACK=801FFFF0
|
13
src/Core.h
13
src/Core.h
@ -118,6 +118,7 @@ typedef cc_uint8 cc_bool;
|
||||
#endif
|
||||
|
||||
|
||||
#define CC_BUILD_NETWORKING
|
||||
#define CC_BUILD_FREETYPE
|
||||
#ifndef CC_BUILD_FLATPAK
|
||||
#define CC_BUILD_RESOURCES
|
||||
@ -329,6 +330,7 @@ typedef cc_uint8 cc_bool;
|
||||
#define CC_BUILD_CONSOLE
|
||||
#undef CC_BUILD_FREETYPE
|
||||
#undef CC_BUILD_RESOURCES
|
||||
#undef CC_BUILD_NETWORKING
|
||||
#elif defined PLAT_PS2
|
||||
#define CC_BUILD_PS2
|
||||
#define CC_BUILD_OPENAL
|
||||
@ -368,6 +370,17 @@ typedef cc_uint8 cc_bool;
|
||||
#define CC_BUILD_GLES
|
||||
#define CC_BUILD_EGL
|
||||
#undef CC_BUILD_FREETYPE
|
||||
#elif defined PLAT_PS1
|
||||
#define CC_BUILD_PS1
|
||||
#define CC_BUILD_HTTPCLIENT
|
||||
#define CC_BUILD_COOPTHREADED
|
||||
#define CC_BUILD_LOWMEM
|
||||
#define CC_BUILD_CONSOLE
|
||||
#define CC_BUILD_NOMUSIC
|
||||
#define CC_BUILD_NOSOUNDS
|
||||
#undef CC_BUILD_FREETYPE
|
||||
#undef CC_BUILD_RESOURCES
|
||||
#undef CC_BUILD_NETWORKING
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -4,8 +4,20 @@
|
||||
/* For abs(x) function */
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifndef __GNUC__
|
||||
#if defined PLAT_PS1
|
||||
#include <psxgte.h>
|
||||
float Math_AbsF(float x) { return __builtin_fabsf(x); }
|
||||
|
||||
float Math_SqrtF(float x) {
|
||||
int fp_x = (int)(x * (1 << 12));
|
||||
fp_x = SquareRoot12(fp_x);
|
||||
return (float)fp_x / (1 << 12);
|
||||
}
|
||||
#elif defined __GNUC__
|
||||
/* Defined in .h using builtins */
|
||||
#else
|
||||
#include <math.h>
|
||||
|
||||
float Math_AbsF(float x) { return fabsf(x); /* MSVC intrinsic */ }
|
||||
float Math_SqrtF(float x) { return sqrtf(x); /* MSVC intrinsic */ }
|
||||
#endif
|
||||
|
@ -14,7 +14,7 @@
|
||||
#define Math_Deg2Packed(x) ((cc_uint8)((x) * 256.0f / 360.0f))
|
||||
#define Math_Packed2Deg(x) ((x) * 360.0f / 256.0f)
|
||||
|
||||
#ifdef __GNUC__
|
||||
#if defined __GNUC__ && !defined CC_PLAT_PS1
|
||||
/* fabsf/sqrtf are single intrinsic instructions in gcc/clang */
|
||||
/* (sqrtf is only when -fno-math-errno though) */
|
||||
#define Math_AbsF(x) __builtin_fabsf(x)
|
||||
|
558
src/Graphics_PS1.c
Normal file
558
src/Graphics_PS1.c
Normal file
@ -0,0 +1,558 @@
|
||||
#include "Core.h"
|
||||
#if defined CC_BUILD_PS1
|
||||
#include "_GraphicsBase.h"
|
||||
#include "Errors.h"
|
||||
#include "Window.h"
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <psxgpu.h>
|
||||
#include <psxgte.h>
|
||||
#include <psxpad.h>
|
||||
#include <psxapi.h>
|
||||
#include <psxetc.h>
|
||||
#include <inline_c.h>
|
||||
// Based off https://github.com/Lameguy64/PSn00bSDK/blob/master/examples/beginner/hello/main.c
|
||||
|
||||
|
||||
// Length of the ordering table, i.e. the range Z coordinates can have, 0-15 in
|
||||
// this case. Larger values will allow for more granularity with depth (useful
|
||||
// when drawing a complex 3D scene) at the expense of RAM usage and performance.
|
||||
#define OT_LENGTH 1024
|
||||
|
||||
// Size of the buffer GPU commands and primitives are written to. If the program
|
||||
// crashes due to too many primitives being drawn, increase this value.
|
||||
#define BUFFER_LENGTH 8192
|
||||
|
||||
typedef struct {
|
||||
DISPENV disp_env;
|
||||
DRAWENV draw_env;
|
||||
|
||||
cc_uint32 ot[OT_LENGTH];
|
||||
cc_uint8 buffer[BUFFER_LENGTH];
|
||||
} RenderBuffer;
|
||||
|
||||
static RenderBuffer buffers[2];
|
||||
static cc_uint8* next_packet;
|
||||
static int active_buffer;
|
||||
static RenderBuffer* buffer;
|
||||
|
||||
static void OnBufferUpdated(void) {
|
||||
buffer = &buffers[active_buffer];
|
||||
next_packet = buffer->buffer;
|
||||
ClearOTagR(buffer->ot, OT_LENGTH);
|
||||
}
|
||||
|
||||
static void SetupContexts(int w, int h, int r, int g, int b) {
|
||||
SetDefDrawEnv(&buffers[0].draw_env, 0, 0, w, h);
|
||||
SetDefDispEnv(&buffers[0].disp_env, 0, 0, w, h);
|
||||
SetDefDrawEnv(&buffers[1].draw_env, 0, h, w, h);
|
||||
SetDefDispEnv(&buffers[1].disp_env, 0, h, w, h);
|
||||
|
||||
setRGB0(&buffers[0].draw_env, r, g, b);
|
||||
setRGB0(&buffers[1].draw_env, r, g, b);
|
||||
buffers[0].draw_env.isbg = 1;
|
||||
buffers[1].draw_env.isbg = 1;
|
||||
|
||||
active_buffer = 0;
|
||||
OnBufferUpdated();
|
||||
}
|
||||
|
||||
static void FlipBuffers(void) {
|
||||
DrawSync(0);
|
||||
VSync(0);
|
||||
|
||||
RenderBuffer* draw_buffer = &buffers[active_buffer];
|
||||
RenderBuffer* disp_buffer = &buffers[active_buffer ^ 1];
|
||||
|
||||
PutDispEnv(&disp_buffer->disp_env);
|
||||
DrawOTagEnv(&draw_buffer->ot[OT_LENGTH - 1], &draw_buffer->draw_env);
|
||||
|
||||
active_buffer ^= 1;
|
||||
OnBufferUpdated();
|
||||
}
|
||||
|
||||
static void* new_primitive(int size) {
|
||||
RenderBuffer* buffer = &buffers[active_buffer];
|
||||
uint8_t* prim = next_packet;
|
||||
|
||||
next_packet += size;
|
||||
|
||||
assert(next_packet <= &buffer->buffer[BUFFER_LENGTH]);
|
||||
return (void*)prim;
|
||||
}
|
||||
|
||||
void Gfx_RestoreState(void) {
|
||||
InitDefaultResources();
|
||||
}
|
||||
|
||||
void Gfx_FreeState(void) {
|
||||
FreeDefaultResources();
|
||||
}
|
||||
|
||||
void Gfx_Create(void) {
|
||||
Gfx.MaxTexWidth = 128;
|
||||
Gfx.MaxTexHeight = 128;
|
||||
Gfx.Created = true;
|
||||
|
||||
Gfx_RestoreState();
|
||||
ResetGraph(0);
|
||||
|
||||
SetupContexts(Window_Main.Width, Window_Main.Height, 63, 0, 127);
|
||||
SetDispMask(1);
|
||||
|
||||
InitGeom();
|
||||
//gte_SetGeomOffset(Window_Main.Width / 2, Window_Main.Height / 2);
|
||||
// Set screen depth (basically FOV control, W/2 works best)
|
||||
//gte_SetGeomScreen(Window_Main.Width / 2);
|
||||
}
|
||||
|
||||
void Gfx_Free(void) {
|
||||
Gfx_FreeState();
|
||||
}
|
||||
|
||||
|
||||
/*########################################################################################################################*
|
||||
*---------------------------------------------------------Textures--------------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
static GfxResourceID Gfx_AllocTexture(struct Bitmap* bmp, cc_uint8 flags, cc_bool mipmaps) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void Gfx_BindTexture(GfxResourceID texId) {
|
||||
}
|
||||
|
||||
void Gfx_DeleteTexture(GfxResourceID* texId) {
|
||||
GfxResourceID data = *texId;
|
||||
if (data) Mem_Free(data);
|
||||
*texId = NULL;
|
||||
}
|
||||
|
||||
void Gfx_UpdateTexture(GfxResourceID texId, int x, int y, struct Bitmap* part, int rowWidth, cc_bool mipmaps) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void Gfx_UpdateTexturePart(GfxResourceID texId, int x, int y, struct Bitmap* part, cc_bool mipmaps) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void Gfx_EnableMipmaps(void) { }
|
||||
void Gfx_DisableMipmaps(void) { }
|
||||
|
||||
|
||||
/*########################################################################################################################*
|
||||
*------------------------------------------------------State management---------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
void Gfx_SetFog(cc_bool enabled) { }
|
||||
void Gfx_SetFogCol(PackedCol col) { }
|
||||
void Gfx_SetFogDensity(float value) { }
|
||||
void Gfx_SetFogEnd(float value) { }
|
||||
void Gfx_SetFogMode(FogFunc func) { }
|
||||
|
||||
void Gfx_SetFaceCulling(cc_bool enabled) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void Gfx_SetAlphaTest(cc_bool enabled) {
|
||||
}
|
||||
|
||||
void Gfx_SetAlphaBlending(cc_bool enabled) {
|
||||
}
|
||||
|
||||
void Gfx_SetAlphaArgBlend(cc_bool enabled) { }
|
||||
|
||||
void Gfx_ClearBuffers(GfxBuffers buffers) {
|
||||
}
|
||||
|
||||
void Gfx_ClearColor(PackedCol color) {
|
||||
int r = PackedCol_R(color);
|
||||
int g = PackedCol_G(color);
|
||||
int b = PackedCol_B(color);
|
||||
|
||||
setRGB0(&buffers[0].draw_env, r, g, b);
|
||||
setRGB0(&buffers[1].draw_env, r, g, b);
|
||||
}
|
||||
|
||||
void Gfx_SetDepthTest(cc_bool enabled) {
|
||||
}
|
||||
|
||||
void Gfx_SetDepthWrite(cc_bool enabled) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
static void SetColorWrite(cc_bool r, cc_bool g, cc_bool b, cc_bool a) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void Gfx_DepthOnlyRendering(cc_bool depthOnly) {
|
||||
cc_bool enabled = !depthOnly;
|
||||
SetColorWrite(enabled & gfx_colorMask[0], enabled & gfx_colorMask[1],
|
||||
enabled & gfx_colorMask[2], enabled & gfx_colorMask[3]);
|
||||
}
|
||||
|
||||
|
||||
/*########################################################################################################################*
|
||||
*-------------------------------------------------------Index buffers-----------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
GfxResourceID Gfx_CreateIb2(int count, Gfx_FillIBFunc fillFunc, void* obj) {
|
||||
return (void*)1;
|
||||
}
|
||||
|
||||
void Gfx_BindIb(GfxResourceID ib) { }
|
||||
void Gfx_DeleteIb(GfxResourceID* ib) { }
|
||||
|
||||
|
||||
/*########################################################################################################################*
|
||||
*-------------------------------------------------------Vertex buffers----------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
static void* gfx_vertices;
|
||||
|
||||
static GfxResourceID Gfx_AllocStaticVb(VertexFormat fmt, int count) {
|
||||
return Mem_TryAlloc(count, strideSizes[fmt]);
|
||||
}
|
||||
|
||||
void Gfx_BindVb(GfxResourceID vb) { gfx_vertices = vb; }
|
||||
|
||||
void Gfx_DeleteVb(GfxResourceID* vb) {
|
||||
GfxResourceID data = *vb;
|
||||
if (data) Mem_Free(data);
|
||||
*vb = 0;
|
||||
}
|
||||
|
||||
void* Gfx_LockVb(GfxResourceID vb, VertexFormat fmt, int count) {
|
||||
return vb;
|
||||
}
|
||||
|
||||
void Gfx_UnlockVb(GfxResourceID vb) {
|
||||
gfx_vertices = vb;
|
||||
}
|
||||
|
||||
|
||||
static GfxResourceID Gfx_AllocDynamicVb(VertexFormat fmt, int maxVertices) {
|
||||
return Mem_TryAlloc(maxVertices, strideSizes[fmt]);
|
||||
}
|
||||
|
||||
void Gfx_BindDynamicVb(GfxResourceID vb) { Gfx_BindVb(vb); }
|
||||
|
||||
void* Gfx_LockDynamicVb(GfxResourceID vb, VertexFormat fmt, int count) {
|
||||
return vb;
|
||||
}
|
||||
|
||||
void Gfx_UnlockDynamicVb(GfxResourceID vb) {
|
||||
gfx_vertices = vb;
|
||||
}
|
||||
|
||||
void Gfx_DeleteDynamicVb(GfxResourceID* vb) { Gfx_DeleteVb(vb); }
|
||||
|
||||
|
||||
/*########################################################################################################################*
|
||||
*---------------------------------------------------------Matrices--------------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
static struct Matrix _view, _proj, mvp;
|
||||
#define ToFixed(v) (int)(v * (1 << 12))
|
||||
|
||||
static void LoadTransformMatrix(struct Matrix* src) {
|
||||
// https://math.stackexchange.com/questions/237369/given-this-transformation-matrix-how-do-i-decompose-it-into-translation-rotati
|
||||
MATRIX mtx;
|
||||
|
||||
mtx.t[0] = 0;
|
||||
mtx.t[1] = 0;
|
||||
mtx.t[2] = 0;
|
||||
|
||||
//Platform_Log3("X: %f3, Y: %f3, Z: %f3", &src->row1.x, &src->row1.y, &src->row1.z);
|
||||
//Platform_Log3("X: %f3, Y: %f3, Z: %f3", &src->row2.x, &src->row2.y, &src->row2.z);
|
||||
//Platform_Log3("X: %f3, Y: %f3, Z: %f3", &src->row3.x, &src->row3.y, &src->row3.z);
|
||||
//Platform_Log3("X: %f3, Y: %f3, Z: %f3", &src->row4.x, &src->row4.y, &src->row4.z);
|
||||
//Platform_LogConst("====");
|
||||
|
||||
float len1 = Math_SqrtF(src->row1.x + src->row1.y + src->row1.z);
|
||||
float len2 = Math_SqrtF(src->row2.x + src->row2.y + src->row2.z);
|
||||
float len3 = Math_SqrtF(src->row3.x + src->row3.y + src->row3.z);
|
||||
|
||||
mtx.m[0][0] = ToFixed(1);
|
||||
mtx.m[0][1] = 0;
|
||||
mtx.m[0][2] = 0;
|
||||
|
||||
mtx.m[1][0] = 0;
|
||||
mtx.m[1][1] = ToFixed(1);
|
||||
mtx.m[1][2] = 0;
|
||||
|
||||
mtx.m[2][0] = 0;
|
||||
mtx.m[2][1] = ToFixed(1);
|
||||
mtx.m[2][2] = 1;
|
||||
|
||||
gte_SetRotMatrix(&mtx);
|
||||
gte_SetTransMatrix(&mtx);
|
||||
}
|
||||
|
||||
/*static void LoadTransformMatrix(struct Matrix* src) {
|
||||
// https://math.stackexchange.com/questions/237369/given-this-transformation-matrix-how-do-i-decompose-it-into-translation-rotati
|
||||
MATRIX mtx;
|
||||
|
||||
mtx.t[0] = ToFixed(src->row4.x);
|
||||
mtx.t[1] = ToFixed(src->row4.y);
|
||||
mtx.t[2] = ToFixed(src->row4.z);
|
||||
|
||||
Platform_Log3("X: %f3, Y: %f3, Z: %f3", &src->row1.x, &src->row1.y, &src->row1.z);
|
||||
Platform_Log3("X: %f3, Y: %f3, Z: %f3", &src->row2.x, &src->row2.y, &src->row2.z);
|
||||
Platform_Log3("X: %f3, Y: %f3, Z: %f3", &src->row3.x, &src->row3.y, &src->row3.z);
|
||||
Platform_Log3("X: %f3, Y: %f3, Z: %f3", &src->row4.x, &src->row4.y, &src->row4.z);
|
||||
Platform_LogConst("====");
|
||||
|
||||
float len1 = Math_SqrtF(src->row1.x + src->row1.y + src->row1.z);
|
||||
float len2 = Math_SqrtF(src->row2.x + src->row2.y + src->row2.z);
|
||||
float len3 = Math_SqrtF(src->row3.x + src->row3.y + src->row3.z);
|
||||
|
||||
mtx.m[0][0] = ToFixed(src->row1.x / len1);
|
||||
mtx.m[0][1] = ToFixed(src->row1.y / len1);
|
||||
mtx.m[0][2] = ToFixed(src->row1.z / len1);
|
||||
|
||||
mtx.m[1][0] = ToFixed(src->row2.x / len2);
|
||||
mtx.m[1][1] = ToFixed(src->row2.y / len2);
|
||||
mtx.m[1][2] = ToFixed(src->row2.z / len2);
|
||||
|
||||
mtx.m[2][0] = ToFixed(src->row3.x / len3);
|
||||
mtx.m[2][1] = ToFixed(src->row3.y / len3);
|
||||
mtx.m[2][2] = ToFixed(src->row3.z / len3);
|
||||
|
||||
gte_SetRotMatrix(&mtx);
|
||||
gte_SetTransMatrix(&mtx);
|
||||
}*/
|
||||
|
||||
void Gfx_LoadMatrix(MatrixType type, const struct Matrix* matrix) {
|
||||
if (type == MATRIX_VIEW) _view = *matrix;
|
||||
if (type == MATRIX_PROJECTION) _proj = *matrix;
|
||||
|
||||
Matrix_Mul(&mvp, &_view, &_proj);
|
||||
LoadTransformMatrix(&mvp);
|
||||
}
|
||||
|
||||
void Gfx_LoadIdentityMatrix(MatrixType type) {
|
||||
Gfx_LoadMatrix(type, &Matrix_Identity);
|
||||
}
|
||||
|
||||
void Gfx_EnableTextureOffset(float x, float y) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void Gfx_DisableTextureOffset(void) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void Gfx_CalcOrthoMatrix(struct Matrix* matrix, float width, float height, float zNear, float zFar) {
|
||||
/* Source https://learn.microsoft.com/en-us/windows/win32/direct3d9/d3dxmatrixorthooffcenterrh */
|
||||
/* The simplified calculation below uses: L = 0, R = width, T = 0, B = height */
|
||||
/* NOTE: This calculation is shared with Direct3D 11 backend */
|
||||
*matrix = Matrix_Identity;
|
||||
|
||||
matrix->row1.x = 2.0f / width;
|
||||
matrix->row2.y = -2.0f / height;
|
||||
matrix->row3.z = 1.0f / (zNear - zFar);
|
||||
|
||||
matrix->row4.x = -1.0f;
|
||||
matrix->row4.y = 1.0f;
|
||||
matrix->row4.z = zNear / (zNear - zFar);
|
||||
}
|
||||
|
||||
static double Cotangent(double x) { return Math_Cos(x) / Math_Sin(x); }
|
||||
void Gfx_CalcPerspectiveMatrix(struct Matrix* matrix, float fov, float aspect, float zFar) {
|
||||
float zNear = 0.01f;
|
||||
/* Source https://learn.microsoft.com/en-us/windows/win32/direct3d9/d3dxmatrixperspectivefovrh */
|
||||
float c = (float)Cotangent(0.5f * fov);
|
||||
*matrix = Matrix_Identity;
|
||||
|
||||
matrix->row1.x = c / aspect;
|
||||
matrix->row2.y = c;
|
||||
matrix->row3.z = zFar / (zNear - zFar);
|
||||
matrix->row3.w = -1.0f;
|
||||
matrix->row4.z = (zNear * zFar) / (zNear - zFar);
|
||||
matrix->row4.w = 0.0f;
|
||||
}
|
||||
|
||||
|
||||
/*########################################################################################################################*
|
||||
*---------------------------------------------------------Rendering-------------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
void Gfx_SetVertexFormat(VertexFormat fmt) {
|
||||
gfx_format = fmt;
|
||||
gfx_stride = strideSizes[fmt];
|
||||
}
|
||||
|
||||
void Gfx_DrawVb_Lines(int verticesCount) {
|
||||
|
||||
}
|
||||
|
||||
static void Transform(Vec3* result, struct VertexTextured* a, const struct Matrix* mat) {
|
||||
/* a could be pointing to result - therefore can't directly assign X/Y/Z */
|
||||
float x = a->x * mat->row1.x + a->y * mat->row2.x + a->z * mat->row3.x + mat->row4.x;
|
||||
float y = a->x * mat->row1.y + a->y * mat->row2.y + a->z * mat->row3.y + mat->row4.y;
|
||||
float z = a->x * mat->row1.z + a->y * mat->row2.z + a->z * mat->row3.z + mat->row4.z;
|
||||
|
||||
result->x = x * (320/2) + (320/2);
|
||||
result->y = y * -(240/2) + (240/2);
|
||||
result->z = z * OT_LENGTH;
|
||||
}
|
||||
|
||||
cc_bool VERTEX_LOGGING;
|
||||
static void DrawQuads(int verticesCount, int startVertex) {
|
||||
for (int i = 0; i < verticesCount; i += 4)
|
||||
{
|
||||
struct VertexTextured* v = (struct VertexTextured*)gfx_vertices + startVertex + i;
|
||||
|
||||
POLY_F4* poly = new_primitive(sizeof(POLY_F4));
|
||||
setPolyF4(poly);
|
||||
|
||||
Vec3 coords[4];
|
||||
Transform(&coords[0], &v[0], &mvp);
|
||||
Transform(&coords[1], &v[1], &mvp);
|
||||
Transform(&coords[2], &v[2], &mvp);
|
||||
Transform(&coords[3], &v[3], &mvp);
|
||||
|
||||
poly->x0 = coords[1].x; poly->y0 = coords[1].y;
|
||||
poly->x1 = coords[0].x; poly->y1 = coords[0].y;
|
||||
poly->x2 = coords[2].x; poly->y2 = coords[2].y;
|
||||
poly->x3 = coords[3].x; poly->y3 = coords[3].y;
|
||||
|
||||
int X = v[0].x, Y = v[0].y, Z = v[0].z;
|
||||
if (VERTEX_LOGGING) Platform_Log3("IN: %i, %i, %i", &X, &Y, &Z);
|
||||
X = poly->x1; Y = poly->y1, Z = coords[0].z;
|
||||
|
||||
poly->r0 = PackedCol_R(v->Col);
|
||||
poly->g0 = PackedCol_G(v->Col);
|
||||
poly->b0 = PackedCol_B(v->Col);
|
||||
|
||||
int p = (coords[0].z + coords[1].z + coords[2].z + coords[3].z) / 4;
|
||||
if (VERTEX_LOGGING) Platform_Log4("OUT: %i, %i, %i (%i)", &X, &Y, &Z, &p);
|
||||
|
||||
if (p < 0 || p >= OT_LENGTH) continue;
|
||||
addPrim(&buffer->ot[p >> 2], poly);
|
||||
}
|
||||
}
|
||||
|
||||
/*static void DrawQuads(int verticesCount, int startVertex) {
|
||||
for (int i = 0; i < verticesCount; i += 4)
|
||||
{
|
||||
struct VertexTextured* v = (struct VertexTextured*)gfx_vertices + startVertex + i;
|
||||
|
||||
POLY_F4* poly = new_primitive(sizeof(POLY_F4));
|
||||
setPolyF4(poly);
|
||||
|
||||
SVECTOR coords[4];
|
||||
coords[0].vx = v[0].x; coords[0].vy = v[0].y; coords[0].vz = v[0].z;
|
||||
coords[1].vx = v[1].x; coords[1].vy = v[1].y; coords[1].vz = v[1].z;
|
||||
coords[2].vx = v[2].x; coords[2].vy = v[2].y; coords[2].vz = v[1].z;
|
||||
coords[3].vx = v[3].x; coords[3].vy = v[3].y; coords[3].vz = v[3].z;
|
||||
|
||||
int X = coords[0].vx, Y = coords[0].vy, Z = coords[0].vz;
|
||||
//Platform_Log3("IN: %i, %i, %i", &X, &Y, &Z);
|
||||
gte_ldv3(&coords[0], &coords[1], &coords[2]);
|
||||
gte_rtpt();
|
||||
gte_stsxy0(&poly->x0);
|
||||
|
||||
int p;
|
||||
gte_avsz3();
|
||||
gte_stotz( &p );
|
||||
|
||||
X = poly->x0; Y = poly->y0, Z = p;
|
||||
//Platform_Log3("OUT: %i, %i, %i", &X, &Y, &Z);
|
||||
if (((p >> 2) >= OT_LENGTH) || ((p >> 2) < 0))
|
||||
continue;
|
||||
|
||||
gte_ldv0(&coords[3]);
|
||||
gte_rtps();
|
||||
gte_stsxy3(&poly->x1, &poly->x2, &poly->x3);
|
||||
|
||||
//poly->x0 = v[1].x; poly->y0 = v[1].y;
|
||||
//poly->x1 = v[0].x; poly->y1 = v[0].y;
|
||||
//poly->x2 = v[2].x; poly->y2 = v[2].y;
|
||||
//poly->x3 = v[3].x; poly->y3 = v[3].y;
|
||||
|
||||
poly->r0 = PackedCol_R(v->Col);
|
||||
poly->g0 = PackedCol_G(v->Col);
|
||||
poly->b0 = PackedCol_B(v->Col);
|
||||
|
||||
addPrim(&buffer->ot[p >> 2], poly);
|
||||
}
|
||||
}*/
|
||||
|
||||
/*static void DrawQuads(int verticesCount, int startVertex) {
|
||||
for (int i = 0; i < verticesCount; i += 4)
|
||||
{
|
||||
struct VertexTextured* v = (struct VertexTextured*)gfx_vertices + startVertex + i;
|
||||
|
||||
POLY_F4* poly = new_primitive(sizeof(POLY_F4));
|
||||
setPolyF4(poly);
|
||||
|
||||
poly->x0 = v[1].x; poly->y0 = v[1].y;
|
||||
poly->x1 = v[0].x; poly->y1 = v[0].y;
|
||||
poly->x2 = v[2].x; poly->y2 = v[2].y;
|
||||
poly->x3 = v[3].x; poly->y3 = v[3].y;
|
||||
|
||||
poly->r0 = PackedCol_R(v->Col);
|
||||
poly->g0 = PackedCol_G(v->Col);
|
||||
poly->b0 = PackedCol_B(v->Col);
|
||||
|
||||
int p = 0;
|
||||
addPrim(&buffer->ot[p >> 2], poly);
|
||||
}
|
||||
}*/
|
||||
|
||||
void Gfx_DrawVb_IndexedTris_Range(int verticesCount, int startVertex) {
|
||||
if (gfx_format == VERTEX_FORMAT_COLOURED) return;
|
||||
DrawQuads(verticesCount, startVertex);
|
||||
}
|
||||
|
||||
void Gfx_DrawVb_IndexedTris(int verticesCount) {
|
||||
if (gfx_format == VERTEX_FORMAT_COLOURED) return;
|
||||
DrawQuads(verticesCount, 0);
|
||||
}
|
||||
|
||||
void Gfx_DrawIndexedTris_T2fC4b(int verticesCount, int startVertex) {
|
||||
DrawQuads(verticesCount, startVertex);
|
||||
}
|
||||
|
||||
|
||||
/*########################################################################################################################*
|
||||
*---------------------------------------------------------Other/Misc------------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
cc_result Gfx_TakeScreenshot(struct Stream* output) {
|
||||
return ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
cc_bool Gfx_WarnIfNecessary(void) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void Gfx_BeginFrame(void) {
|
||||
// Draw the square by allocating a TILE (i.e. untextured solid color
|
||||
// rectangle) primitive at Z = 1.
|
||||
TILE *tile = (TILE *)new_primitive(sizeof(TILE));
|
||||
|
||||
setTile(tile);
|
||||
setXY0 (tile, 40, 40);
|
||||
setWH (tile, 64, 64);
|
||||
setRGB0(tile, 255, 255, 0);
|
||||
addPrim(&buffer->ot[1 >> 2], tile);
|
||||
}
|
||||
|
||||
void Gfx_EndFrame(void) {
|
||||
FlipBuffers();
|
||||
if (gfx_minFrameMs) LimitFPS();
|
||||
}
|
||||
|
||||
void Gfx_SetFpsLimit(cc_bool vsync, float minFrameMs) {
|
||||
gfx_minFrameMs = minFrameMs;
|
||||
gfx_vsync = vsync;
|
||||
}
|
||||
|
||||
void Gfx_OnWindowResize(void) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void Gfx_GetApiInfo(cc_string* info) {
|
||||
String_AppendConst(info, "-- Using PS1 --\n");
|
||||
PrintMaxTextureInfo(info);
|
||||
}
|
||||
|
||||
cc_bool Gfx_TryRestoreContext(void) { return true; }
|
||||
#endif
|
228
src/Platform_PS1.c
Normal file
228
src/Platform_PS1.c
Normal file
@ -0,0 +1,228 @@
|
||||
#include "Core.h"
|
||||
#if defined PLAT_PS1
|
||||
|
||||
#include "_PlatformBase.h"
|
||||
#include "Stream.h"
|
||||
#include "ExtMath.h"
|
||||
#include "Funcs.h"
|
||||
#include "Window.h"
|
||||
#include "Utils.h"
|
||||
#include "Errors.h"
|
||||
#include "PackedCol.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <psxetc.h>
|
||||
#include <psxapi.h>
|
||||
#include <psxgpu.h>
|
||||
#include <hwregs_c.h>
|
||||
void exit(int code) { } // TODO how to fix
|
||||
#include "_PlatformConsole.h"
|
||||
|
||||
const cc_result ReturnCode_FileShareViolation = 1000000000; // not used
|
||||
const cc_result ReturnCode_FileNotFound = 99999;
|
||||
const cc_result ReturnCode_DirectoryExists = 99999;
|
||||
|
||||
const cc_result ReturnCode_SocketInProgess = -1;
|
||||
const cc_result ReturnCode_SocketWouldBlock = -1;
|
||||
const char* Platform_AppNameSuffix = " PS1";
|
||||
|
||||
|
||||
/*########################################################################################################################*
|
||||
*------------------------------------------------------Logging/Time-------------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
void Platform_Log(const char* msg, int len) {
|
||||
char tmp[2048 + 1];
|
||||
len = min(len, 2048);
|
||||
Mem_Copy(tmp, msg, len); tmp[len] = '\0';
|
||||
|
||||
printf("%s\n", tmp);
|
||||
}
|
||||
|
||||
#define UnixTime_TotalMS(time) ((cc_uint64)time.tv_sec * 1000 + UNIX_EPOCH + (time.tv_usec / 1000))
|
||||
TimeMS DateTime_CurrentUTC_MS(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DateTime_CurrentLocal(struct DateTime* t) {
|
||||
Mem_Set(t, 0, sizeof(struct DateTime));
|
||||
}
|
||||
|
||||
|
||||
/*########################################################################################################################*
|
||||
*--------------------------------------------------------Stopwatch--------------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
static volatile cc_uint32 irq_count;
|
||||
|
||||
cc_uint64 Stopwatch_Measure(void) {
|
||||
return irq_count;
|
||||
}
|
||||
|
||||
cc_uint64 Stopwatch_ElapsedMicroseconds(cc_uint64 beg, cc_uint64 end) {
|
||||
if (end < beg) return 0;
|
||||
return (end - beg) * 1000;
|
||||
}
|
||||
|
||||
static void timer2_handler(void) { irq_count++; }
|
||||
|
||||
static void Stopwatch_Init(void) {
|
||||
TIMER_CTRL(2) = 0x0258; // CLK/8 input, IRQ on reload
|
||||
TIMER_RELOAD(2) = (F_CPU / 8) / 1000; // 1000 Hz
|
||||
|
||||
EnterCriticalSection();
|
||||
InterruptCallback(IRQ_TIMER2, &timer2_handler);
|
||||
ExitCriticalSection();
|
||||
}
|
||||
|
||||
|
||||
/*########################################################################################################################*
|
||||
*-----------------------------------------------------Directory/File------------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
cc_result Directory_Create(const cc_string* path) {
|
||||
return ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
int File_Exists(const cc_string* path) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
cc_result Directory_Enum(const cc_string* dirPath, void* obj, Directory_EnumCallback callback) {
|
||||
return ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
cc_result File_Open(cc_file* file, const cc_string* path) {
|
||||
return ERR_NOT_SUPPORTED;
|
||||
}
|
||||
cc_result File_Create(cc_file* file, const cc_string* path) {
|
||||
return ERR_NOT_SUPPORTED;
|
||||
}
|
||||
cc_result File_OpenOrCreate(cc_file* file, const cc_string* path) {
|
||||
return ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
cc_result File_Read(cc_file file, void* data, cc_uint32 count, cc_uint32* bytesRead) {
|
||||
return ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
cc_result File_Write(cc_file file, const void* data, cc_uint32 count, cc_uint32* bytesWrote) {
|
||||
return ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
cc_result File_Close(cc_file file) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
cc_result File_Seek(cc_file file, int offset, int seekType) {
|
||||
return ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
cc_result File_Position(cc_file file, cc_uint32* pos) {
|
||||
return ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
cc_result File_Length(cc_file file, cc_uint32* len) {
|
||||
return ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
|
||||
/*########################################################################################################################*
|
||||
*--------------------------------------------------------Threading--------------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
void Thread_Sleep(cc_uint32 milliseconds) {
|
||||
// TODO sleep a bit
|
||||
VSync(0);
|
||||
}
|
||||
|
||||
void Thread_Run(void** handle, Thread_StartFunc func, int stackSize, const char* name) {
|
||||
*handle = NULL;
|
||||
}
|
||||
|
||||
void Thread_Detach(void* handle) {
|
||||
}
|
||||
|
||||
void Thread_Join(void* handle) {
|
||||
}
|
||||
|
||||
void* Mutex_Create(void) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void Mutex_Free(void* handle) {
|
||||
}
|
||||
|
||||
void Mutex_Lock(void* handle) {
|
||||
}
|
||||
|
||||
void Mutex_Unlock(void* handle) {
|
||||
}
|
||||
|
||||
void* Waitable_Create(void) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void Waitable_Free(void* handle) {
|
||||
}
|
||||
|
||||
void Waitable_Signal(void* handle) {
|
||||
}
|
||||
|
||||
void Waitable_Wait(void* handle) {
|
||||
}
|
||||
|
||||
void Waitable_WaitFor(void* handle, cc_uint32 milliseconds) {
|
||||
}
|
||||
|
||||
|
||||
/*########################################################################################################################*
|
||||
*---------------------------------------------------------Socket----------------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
cc_result Socket_ParseAddress(const cc_string* address, int port, cc_sockaddr* addrs, int* numValidAddrs) {
|
||||
return ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
cc_result Socket_Connect(cc_socket* s, cc_sockaddr* addr, cc_bool nonblocking) {
|
||||
return ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
cc_result Socket_Read(cc_socket s, cc_uint8* data, cc_uint32 count, cc_uint32* modified) {
|
||||
return ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
cc_result Socket_Write(cc_socket s, const cc_uint8* data, cc_uint32 count, cc_uint32* modified) {
|
||||
return ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
void Socket_Close(cc_socket s) {
|
||||
}
|
||||
|
||||
cc_result Socket_CheckReadable(cc_socket s, cc_bool* readable) {
|
||||
return ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
cc_result Socket_CheckWritable(cc_socket s, cc_bool* writable) {
|
||||
return ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
|
||||
/*########################################################################################################################*
|
||||
*--------------------------------------------------------Platform---------------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
void Platform_Init(void) {
|
||||
ResetGraph( 0 );
|
||||
Stopwatch_Init();
|
||||
}
|
||||
|
||||
void Platform_Free(void) { }
|
||||
|
||||
cc_bool Platform_DescribeError(cc_result res, cc_string* dst) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/*########################################################################################################################*
|
||||
*-------------------------------------------------------Encryption--------------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
static cc_result GetMachineID(cc_uint32* key) {
|
||||
return ERR_NOT_SUPPORTED;
|
||||
}
|
||||
#endif
|
@ -1,9 +1,10 @@
|
||||
#include "Protocol.h"
|
||||
#include "Game.h"
|
||||
#ifdef CC_BUILD_NETWORKING
|
||||
#include "String.h"
|
||||
#include "Deflate.h"
|
||||
#include "Server.h"
|
||||
#include "Stream.h"
|
||||
#include "Game.h"
|
||||
#include "Entity.h"
|
||||
#include "Platform.h"
|
||||
#include "Screens.h"
|
||||
@ -1872,6 +1873,13 @@ static void OnReset(void) {
|
||||
Protocol_Reset();
|
||||
FreeMapStates();
|
||||
}
|
||||
#else
|
||||
void CPE_SendPlayerClick(int button, cc_bool pressed, cc_uint8 targetId, struct RayTracer* t) { }
|
||||
|
||||
static void OnInit(void) { }
|
||||
|
||||
static void OnReset(void) { }
|
||||
#endif
|
||||
|
||||
struct IGameComponent Protocol_Component = {
|
||||
OnInit, /* Init */
|
||||
|
17
src/Server.c
17
src/Server.c
@ -128,7 +128,7 @@ static void SPConnection_BeginConnect(void) {
|
||||
Random_SeedFromCurrentTime(&rnd);
|
||||
World_NewMap();
|
||||
|
||||
#if defined CC_BUILD_NDS
|
||||
#if defined CC_BUILD_NDS || defined CC_BUILD_PS1
|
||||
World_SetDimensions(16, 16, 16);
|
||||
#elif defined CC_BUILD_LOWMEM
|
||||
World_SetDimensions(64, 64, 64);
|
||||
@ -136,7 +136,7 @@ static void SPConnection_BeginConnect(void) {
|
||||
World_SetDimensions(128, 64, 128);
|
||||
#endif
|
||||
|
||||
#if defined CC_BUILD_N64 || defined CC_BUILD_NDS
|
||||
#if defined CC_BUILD_N64 || defined CC_BUILD_NDS || defined CC_BUILD_PS1
|
||||
Gen_Active = &FlatgrassGen;
|
||||
#else
|
||||
Gen_Active = &NotchyGen;
|
||||
@ -223,10 +223,12 @@ static void SPConnection_Init(void) {
|
||||
*--------------------------------------------------Multiplayer connection-------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
static cc_socket net_socket = -1;
|
||||
static cc_result net_writeFailure;
|
||||
static void OnClose(void);
|
||||
|
||||
#ifdef CC_BUILD_NETWORKING
|
||||
static cc_uint8 net_readBuffer[4096 * 5];
|
||||
static cc_uint8* net_readCurrent;
|
||||
|
||||
static cc_result net_writeFailure;
|
||||
static double net_lastPacket;
|
||||
static cc_uint8 lastOpcode;
|
||||
|
||||
@ -234,7 +236,6 @@ static cc_bool net_connecting;
|
||||
static double net_connectTimeout;
|
||||
#define NET_TIMEOUT_SECS 15
|
||||
|
||||
static void OnClose(void);
|
||||
static void MPConnection_FinishConnect(void) {
|
||||
net_connecting = false;
|
||||
Event_RaiseVoid(&NetEvents.Connected);
|
||||
@ -475,8 +476,14 @@ static void MPConnection_Init(void) {
|
||||
Server.SendData = MPConnection_SendData;
|
||||
net_readCurrent = net_readBuffer;
|
||||
}
|
||||
#else
|
||||
static void MPConnection_Init(void) { SPConnection_Init(); }
|
||||
#endif
|
||||
|
||||
|
||||
/*########################################################################################################################*
|
||||
*---------------------------------------------------Component interface---------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
static void OnNewMap(void) {
|
||||
int i;
|
||||
if (Server.IsSinglePlayer) return;
|
||||
|
198
src/Window_PS1.c
Normal file
198
src/Window_PS1.c
Normal file
@ -0,0 +1,198 @@
|
||||
#include "Core.h"
|
||||
#if defined CC_BUILD_PS1
|
||||
#include "Window.h"
|
||||
#include "Platform.h"
|
||||
#include "Input.h"
|
||||
#include "Event.h"
|
||||
#include "Graphics.h"
|
||||
#include "String.h"
|
||||
#include "Funcs.h"
|
||||
#include "Bitmap.h"
|
||||
#include "Errors.h"
|
||||
#include "ExtMath.h"
|
||||
#include "Logger.h"
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <psxapi.h>
|
||||
#include <psxetc.h>
|
||||
#include <psxgte.h>
|
||||
#include <psxgpu.h>
|
||||
#include <psxpad.h>
|
||||
|
||||
#define SCREEN_XRES 320
|
||||
#define SCREEN_YRES 240
|
||||
|
||||
static cc_bool launcherMode;
|
||||
static char pad_buff[2][34];
|
||||
|
||||
struct _DisplayData DisplayInfo;
|
||||
struct _WindowData WindowInfo;
|
||||
|
||||
void Window_Init(void) {
|
||||
DisplayInfo.Width = SCREEN_XRES;
|
||||
DisplayInfo.Height = SCREEN_YRES;
|
||||
DisplayInfo.Depth = 4; // 32 bit
|
||||
DisplayInfo.ScaleX = 0.5f;
|
||||
DisplayInfo.ScaleY = 0.5f;
|
||||
|
||||
Window_Main.Width = DisplayInfo.Width;
|
||||
Window_Main.Height = DisplayInfo.Height;
|
||||
Window_Main.Focused = true;
|
||||
Window_Main.Exists = true;
|
||||
|
||||
Input.Sources = INPUT_SOURCE_GAMEPAD;
|
||||
DisplayInfo.ContentOffsetX = 10;
|
||||
DisplayInfo.ContentOffsetY = 10;
|
||||
|
||||
// http://lameguy64.net/tutorials/pstutorials/chapter1/4-controllers.html
|
||||
InitPAD(&pad_buff[0][0], 34, &pad_buff[1][0], 34);
|
||||
pad_buff[0][0] = pad_buff[0][1] = 0xff;
|
||||
pad_buff[1][0] = pad_buff[1][1] = 0xff;
|
||||
StartPAD();
|
||||
ChangeClearPAD(0);
|
||||
}
|
||||
|
||||
void Window_Free(void) { }
|
||||
|
||||
void Window_Create3D(int width, int height) {
|
||||
launcherMode = false;
|
||||
}
|
||||
|
||||
void Window_SetTitle(const cc_string* title) { }
|
||||
void Clipboard_GetText(cc_string* value) { }
|
||||
void Clipboard_SetText(const cc_string* value) { }
|
||||
|
||||
int Window_GetWindowState(void) { return WINDOW_STATE_FULLSCREEN; }
|
||||
cc_result Window_EnterFullscreen(void) { return 0; }
|
||||
cc_result Window_ExitFullscreen(void) { return 0; }
|
||||
int Window_IsObscured(void) { return 0; }
|
||||
|
||||
void Window_Show(void) { }
|
||||
void Window_SetSize(int width, int height) { }
|
||||
|
||||
void Window_RequestClose(void) {
|
||||
Event_RaiseVoid(&WindowEvents.Closing);
|
||||
}
|
||||
|
||||
|
||||
/*########################################################################################################################*
|
||||
*----------------------------------------------------Input processing-----------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
static void HandleButtons(int buttons) {
|
||||
// Confusingly, it seems that when a bit is on, it means the button is NOT pressed
|
||||
// So just flip the bits to make more sense
|
||||
buttons = ~buttons;
|
||||
|
||||
Input_SetNonRepeatable(CCPAD_A, buttons & PAD_TRIANGLE);
|
||||
Input_SetNonRepeatable(CCPAD_B, buttons & PAD_SQUARE);
|
||||
Input_SetNonRepeatable(CCPAD_X, buttons & PAD_CROSS);
|
||||
Input_SetNonRepeatable(CCPAD_Y, buttons & PAD_CIRCLE);
|
||||
|
||||
Input_SetNonRepeatable(CCPAD_START, buttons & PAD_START);
|
||||
Input_SetNonRepeatable(CCPAD_SELECT, buttons & PAD_SELECT);
|
||||
|
||||
Input_SetNonRepeatable(CCPAD_LEFT, buttons & PAD_LEFT);
|
||||
Input_SetNonRepeatable(CCPAD_RIGHT, buttons & PAD_RIGHT);
|
||||
Input_SetNonRepeatable(CCPAD_UP, buttons & PAD_UP);
|
||||
Input_SetNonRepeatable(CCPAD_DOWN, buttons & PAD_DOWN);
|
||||
|
||||
Input_SetNonRepeatable(CCPAD_L, buttons & PAD_L1);
|
||||
Input_SetNonRepeatable(CCPAD_R, buttons & PAD_R1);
|
||||
Input_SetNonRepeatable(CCPAD_ZL, buttons & PAD_L2);
|
||||
Input_SetNonRepeatable(CCPAD_ZR, buttons & PAD_R2);
|
||||
}
|
||||
|
||||
static void ProcessPadInput(PADTYPE* pad, double delta) {
|
||||
HandleButtons(pad->btn);
|
||||
}
|
||||
|
||||
void Window_ProcessEvents(double delta) {
|
||||
PADTYPE* pad = (PADTYPE*)&pad_buff[0][0];
|
||||
if (pad->stat == 0) ProcessPadInput(pad, delta);
|
||||
}
|
||||
|
||||
void Cursor_SetPosition(int x, int y) { } // Makes no sense for PS Vita
|
||||
|
||||
void Window_EnableRawMouse(void) { Input.RawMode = true; }
|
||||
void Window_UpdateRawMouse(void) { }
|
||||
void Window_DisableRawMouse(void) { Input.RawMode = false; }
|
||||
|
||||
|
||||
/*########################################################################################################################*
|
||||
*------------------------------------------------------Framebuffer--------------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
void Window_Create2D(int width, int height) {
|
||||
launcherMode = true;
|
||||
}
|
||||
|
||||
static DISPENV disp;
|
||||
static cc_uint16* fb;
|
||||
|
||||
void Window_AllocFramebuffer(struct Bitmap* bmp) {
|
||||
SetDefDispEnv(&disp, 0, 0, SCREEN_XRES, SCREEN_YRES);
|
||||
disp.isinter = 1;
|
||||
|
||||
PutDispEnv(&disp);
|
||||
SetDispMask(1);
|
||||
|
||||
bmp->scan0 = (BitmapCol*)Mem_Alloc(bmp->width * bmp->height, 4, "window pixels");
|
||||
fb = Mem_Alloc(bmp->width * bmp->height, 2, "real surface");
|
||||
}
|
||||
|
||||
#define BGRA8_to_PS1(src) \
|
||||
((src[2] & 0xF8) >> 3) | ((src[1] & 0xF8) << 2) | ((src[0] & 0xF8) << 7) | 0x8000
|
||||
|
||||
void Window_DrawFramebuffer(Rect2D r, struct Bitmap* bmp) {
|
||||
RECT rect;
|
||||
rect.x = 0;
|
||||
rect.y = 0;
|
||||
rect.w = SCREEN_XRES;
|
||||
rect.h = SCREEN_YRES;
|
||||
|
||||
for (int y = r.y; y < r.y + r.Height; y++)
|
||||
{
|
||||
cc_uint32* src = bmp->scan0 + y * bmp->width;
|
||||
cc_uint16* dst = fb + y * bmp->width;
|
||||
|
||||
for (int x = r.x; x < r.x + r.Width; x++) {
|
||||
cc_uint8* color = (cc_uint8*)&src[x];
|
||||
dst[x] = BGRA8_to_PS1(color);
|
||||
}
|
||||
}
|
||||
|
||||
LoadImage(&rect, fb);
|
||||
DrawSync(0);
|
||||
}
|
||||
|
||||
void Window_FreeFramebuffer(struct Bitmap* bmp) {
|
||||
Mem_Free(bmp->scan0);
|
||||
Mem_Free(fb);
|
||||
}
|
||||
|
||||
|
||||
/*########################################################################################################################*
|
||||
*------------------------------------------------------Soft keyboard------------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
void Window_OpenKeyboard(struct OpenKeyboardArgs* args) { /* TODO implement */ }
|
||||
void Window_SetKeyboardText(const cc_string* text) { }
|
||||
void Window_CloseKeyboard(void) { /* TODO implement */ }
|
||||
|
||||
|
||||
/*########################################################################################################################*
|
||||
*-------------------------------------------------------Misc/Other--------------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
void Window_ShowDialog(const char* title, const char* msg) {
|
||||
/* TODO implement */
|
||||
Platform_LogConst(title);
|
||||
Platform_LogConst(msg);
|
||||
}
|
||||
|
||||
cc_result Window_OpenFileDialog(const struct OpenFileDialogArgs* args) {
|
||||
return ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
cc_result Window_SaveFileDialog(const struct SaveFileDialogArgs* args) {
|
||||
return ERR_NOT_SUPPORTED;
|
||||
}
|
||||
#endif
|
@ -71,6 +71,11 @@ int Platform_GetCommandLineArgs(int argc, STRING_REF char** argv, cc_string* arg
|
||||
// (e.g. when running via some emulators)
|
||||
if (!argc) return 0;
|
||||
|
||||
#ifdef CC_BUILD_PS1
|
||||
// When running in DuckStation at least, argv was a five element array of empty strings ???
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
argc--; argv++; // skip executable path argument
|
||||
|
||||
int count = min(argc, GAME_MAX_CMDARGS);
|
||||
|
Loading…
x
Reference in New Issue
Block a user