teto pear

This commit is contained in:
Nishi 2026-01-13 04:28:36 +09:00
commit e02687863f
Signed by: nishi
GPG key ID: 27EF69B208EB9343
18 changed files with 3484 additions and 19 deletions

BIN
data/mdl/tetopear.mdl Normal file

Binary file not shown.

View file

@ -17,6 +17,7 @@ GSDECL void GSEngineLoop(GSEngine engine);
GSDECL GSClient GSEngineGetClient(GSEngine engine);
GSDECL GSServer GSEngineGetServer(GSEngine engine);
GSDECL int GSEngineRegisterResource(GSEngine engine, const char* name, const char* path);
GSDECL void GSEngineUnregisterResource(GSEngine engine, const char* name);
#ifdef __cplusplus
}

View file

@ -22,6 +22,8 @@ GSDECL GSI64 GSEndianSwapI64BE(GSI64 in);
GSDECL GSU16 GSEndianSwapU16BE(GSU16 in);
GSDECL GSU32 GSEndianSwapU32BE(GSU32 in);
GSDECL GSU64 GSEndianSwapU64BE(GSU64 in);
GSDECL GSNumber GSEndianSwapNumberBE(GSNumber in);
#else
#define GSEndianSwapI16BE(in) (in)
#define GSEndianSwapI32BE(in) (in)
@ -30,6 +32,8 @@ GSDECL GSU64 GSEndianSwapU64BE(GSU64 in);
#define GSEndianSwapU16BE(in) (in)
#define GSEndianSwapU32BE(in) (in)
#define GSEndianSwapU64BE(in) (in)
#define GSEndianSwapNumberBE(in) (in)
#endif
#ifdef __cplusplus

View file

@ -16,5 +16,6 @@
#include <GearSrc/Endian.h>
#include <GearSrc/SkyBox.h>
#include <GearSrc/CRC.h>
#include <GearSrc/Model.h>
#endif

View file

@ -31,16 +31,22 @@ GSDECL void GSGLShadowDisable(GSGL gl);
GSDECL void GSGLShadowEnable(GSGL gl);
/* gl.c */
GSDECL GSGL GSGLCreate(GSClient client);
GSDECL void GSGLDestroy(GSGL gl);
GSDECL void GSGLClear(GSGL gl);
GSDECL void GSGLIgnoreDepth(GSGL gl);
GSDECL void GSGLCareDepth(GSGL gl);
GSDECL void GSGLSetLight(GSGL gl);
GSDECL void GSGLPolygon(GSGL gl, int pairs, GSVector3* vert, GSVector2* tex, GSVector3 norm);
GSDECL void GSGLPolygon2D(GSGL gl, int pairs, GSVector2* vert, GSVector2* tex);
GSDECL void GSGLBegin2D(GSGL gl);
GSDECL void GSGLEnd2D(GSGL gl);
GSDECL GSGL GSGLCreate(GSClient client);
GSDECL void GSGLDestroy(GSGL gl);
GSDECL void GSGLClear(GSGL gl);
GSDECL void GSGLIgnoreDepth(GSGL gl);
GSDECL void GSGLCareDepth(GSGL gl);
GSDECL void GSGLSetLight(GSGL gl);
GSDECL void GSGLPolygon(GSGL gl, int pairs, GSVector3* vert, GSVector2* tex, GSVector3 norm);
GSDECL void GSGLPolygon2D(GSGL gl, int pairs, GSVector2* vert, GSVector2* tex);
GSDECL void GSGLBegin2D(GSGL gl);
GSDECL void GSGLEnd2D(GSGL gl);
GSDECL void GSGLSetPosition(GSGL gl, GSVector3 pos, GSVector3 rot);
GSDECL void GSGLPushMatrix(GSGL gl);
GSDECL void GSGLPopMatrix(GSGL gl);
GSDECL GLuint GSGLBeginList(GSGL gl);
GSDECL void GSGLEndList(GSGL gl);
GSDECL void GSGLCallList(GSGL gl, GLuint list);
/* gl_camera.c */
GSDECL void GSGLCameraPerspective(GSGL gl, GSNumber width, GSNumber height);

View file

@ -0,0 +1,19 @@
#ifndef __GEARSRC_MODEL_H__
#define __GEARSRC_MODEL_H__
#include <GearSrc/MachDep.h>
#include <GearSrc/TypeDefs.h>
#ifdef __cplusplus
extern "C" {
#endif
GSDECL GSModel GSModelOpen(GSEngine engine, const char* path);
GSDECL void GSModelDraw(GSModel model, GSVector3 pos, GSVector3 rot);
GSDECL void GSModelClose(GSModel model);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -48,6 +48,9 @@ typedef struct _GSFile* GSFile;
typedef struct _GSResource* GSResource;
typedef struct _GSGL* GSGL;
typedef struct _GSSkyBox* GSSkyBox;
typedef struct _GSModel* GSModel;
typedef struct _GSModelFace GSModelFace;
#else
typedef void* GSClient;
typedef void* GSServer;
@ -56,6 +59,7 @@ typedef void* GSFile;
typedef void* GSResource;
typedef void* GSGL;
typedef void* GSSkyBox;
typedef void* GSModel;
#endif
typedef float GSNumber;
typedef GSNumber GSVector2[2];
@ -110,6 +114,24 @@ struct _GSSkyBox {
GLuint down;
};
struct _GSModelFace {
int count;
GSVector3 normal;
GSVector3* vertex;
GSVector2* texcoord;
};
struct _GSModel {
GSEngine engine;
GLuint texture;
GLuint call_list;
float* vertex;
float* texcoord;
GSModelFace* face;
};
struct _GSServer {
GSEngine engine;
};

View file

@ -4,6 +4,7 @@
#include <GearSrc/GL.h>
#include <GearSrc/SkyBox.h>
#include <GearSrc/Math.h>
#include <GearSrc/Model.h>
GSClient GSClientCreate(GSEngine engine) {
GSClient client = malloc(sizeof(*client));
@ -12,12 +13,12 @@ GSClient GSClientCreate(GSEngine engine) {
client->engine = engine;
client->camera[0] = 5;
client->camera[1] = 0;
client->camera[0] = 0;
client->camera[1] = 1;
client->camera[2] = 5;
client->look_at[0] = 0;
client->look_at[1] = 1;
client->look_at[1] = 0;
client->look_at[2] = 0;
client->light0[0] = 2.5;
@ -42,7 +43,28 @@ void GSClientDestroy(GSClient client) {
GSLog(GSLogInfo, "Destroyed client");
}
GSModel m = NULL;
static void scene(GSClient client) {
static double r = 0;
GSVector3 pos = {0, 0, 0};
GSVector3 rot = {0, 0, 0};
int i;
int a = 1;
if(m == NULL) m = GSModelOpen(client->engine, "game:/mdl/tetopear.mdl");
rot[1] = r;
for(i = -a; i <= a; i++) {
int j;
pos[0] = i * 2;
for(j = -a; j <= a; j++) {
pos[2] = j * 2;
GSModelDraw(m, pos, rot);
}
}
r++;
}
void GSClientStep(GSClient client) {

View file

@ -22,12 +22,26 @@ int GSEngineRegisterResource(GSEngine engine, const char* name, const char* path
if((resource = GSResourceOpen(engine, path)) != NULL) {
shput(engine->resource, name, resource);
GSLog(GSLogInfo, "Registered resource %s as %s", path, name);
return 1;
}
return 0;
}
void GSEngineUnregisterResource(GSEngine engine, const char* name) {
int ind = shgeti(engine->resource, name);
if(ind != -1) {
GSResourceClose(engine->resource[ind].value);
GSLog(GSLogInfo, "Unregistered resource %s", name);
shdel(engine->resource, name);
}
}
GSEngine GSEngineCreate(GSEngineParam* param) {
GSEngine engine = malloc(sizeof(*engine));
@ -121,8 +135,8 @@ void GSEngineLoop(GSEngine engine) {
if(wait_actually) {
int diff = (engine->param->get_tick() - t);
if ( wait > diff )
engine->param->sleep(wait-diff);
if(wait > diff)
engine->param->sleep(wait - diff);
t = engine->param->get_tick();
}

View file

@ -61,4 +61,12 @@ GSU64 GSEndianSwapU64BE(GSU64 in) {
return out;
}
GSNumber GSEndianSwapNumberBE(GSNumber in) {
GSNumber out;
SWAP(in, out);
return out;
}
#endif

View file

@ -110,3 +110,35 @@ void GSGLEnd2D(GSGL gl) {
GSGLShadowEnable(gl);
GSGLCareDepth(gl);
}
void GSGLSetPosition(GSGL gl, GSVector3 pos, GSVector3 rot) {
glTranslatef(pos[0], pos[1], pos[2]);
glRotatef(rot[0], 1, 0, 0);
glRotatef(rot[1], 0, 1, 0);
glRotatef(rot[2], 0, 0, 1);
}
void GSGLPushMatrix(GSGL gl) {
glPushMatrix();
}
void GSGLPopMatrix(GSGL gl) {
glPopMatrix();
}
GLuint GSGLBeginList(GSGL gl) {
GLuint list;
list = glGenLists(1);
glNewList(list, GL_COMPILE);
return list;
}
void GSGLEndList(GSGL gl) {
glEndList();
}
void GSGLCallList(GSGL gl, GLuint list) {
glCallList(list);
}

256
engine/src/model.c Normal file
View file

@ -0,0 +1,256 @@
#include <GearSrc/Model.h>
#include <GearSrc/GL.h>
#include <GearSrc/Core.h>
#include <GearSrc/File.h>
#include <GearSrc/Log.h>
#include <GearSrc/Math.h>
#include <stb_ds.h>
static void parse_obj(GSModel model, char* txt) {
char* f = txt;
float lm = 0; /* leftmost */
float rm = 0; /* rightmost */
float um = 0; /* upmost */
float dm = 0; /* downmost */
float fm = 0; /* frontmost */
float bm = 0; /* backmost */
while(1) {
char* s = strchr(f, '\n');
if(s != NULL) s[0] = 0;
if(strlen(f) > 0 && f[0] != '#') {
char* arg;
if(f[strlen(f) - 1] == '\n') f[strlen(f) - 1] = 0;
if((arg = strchr(f, ' ')) != NULL) {
arg[0] = 0;
arg++;
if(strcmp(f, "v") == 0) {
float v0, v1, v2;
sscanf(arg, "%f %f %f", &v0, &v1, &v2);
if(lm > v0) lm = v0;
if(rm < v0) rm = v0;
if(dm > v1) dm = v1;
if(um < v1) um = v1;
if(bm > v2) bm = v2;
if(fm < v2) fm = v2;
arrput(model->vertex, v0);
arrput(model->vertex, v1);
arrput(model->vertex, v2);
} else if(strcmp(f, "vt") == 0) {
float t0, t1;
sscanf(arg, "%f %f", &t0, &t1);
arrput(model->texcoord, t0);
arrput(model->texcoord, t1);
} else if(strcmp(f, "f") == 0) {
int i;
int c = 1;
int sl = 0;
GSModelFace face;
int varr[4];
int tarr[4];
float sc = 0;
float lr = fabs(lm - rm);
float ud = fabs(um - dm);
float bf = fabs(bm - fm);
if(sc < lr) sc = lr;
if(sc < ud) sc = ud;
if(sc < bf) sc = bf;
sc /= 2;
memset(&face, 0, sizeof(face));
for(i = 0; arg[i] != 0; i++) {
if(c == 1 && arg[i] == '/') {
sl++;
}
if(arg[i] == ' ') c++;
}
face.count = c;
face.vertex = malloc(sizeof(*face.vertex) * face.count);
face.texcoord = malloc(sizeof(*face.texcoord) * face.count);
if(c == 3) {
int v0, v1, v2;
int t0, t1, t2;
int n0, n1, n2;
if(sl == 2) {
sscanf(arg, "%d/%d/%d %d/%d/%d %d/%d/%d", &v0, &t0, &n0, &v1, &t1, &n1, &v2, &t2, &n2);
} else {
sscanf(arg, "%d/%d %d/%d %d/%d", &v0, &t0, &v1, &t1, &v2, &t2);
}
varr[0] = v0 - 1;
varr[1] = v1 - 1;
varr[2] = v2 - 1;
tarr[0] = t0 - 1;
tarr[1] = t1 - 1;
tarr[2] = t2 - 1;
} else if(c == 4) {
int v0, v1, v2, v3;
int t0, t1, t2, t3;
int n0, n1, n2, n3;
if(sl == 2) {
sscanf(arg, "%d/%d/%d %d/%d/%d %d/%d/%d %d/%d/%d", &v0, &t0, &n0, &v1, &t1, &n1, &v2, &t2, &n2, &v3, &t3, &n3);
} else {
sscanf(arg, "%d/%d %d/%d %d/%d %d/%d", &v0, &t0, &v1, &t1, &v2, &t2, &v3, &t3);
}
varr[0] = v0 - 1;
varr[1] = v1 - 1;
varr[2] = v2 - 1;
varr[3] = v3 - 1;
tarr[0] = t0 - 1;
tarr[1] = t1 - 1;
tarr[2] = t2 - 1;
tarr[3] = t3 - 1;
}
if(c == 3 || c == 4) {
for(i = 0; i < c; i++) {
if(arrlen(model->vertex) > varr[i] * 3) {
face.vertex[i][0] = model->vertex[varr[i] * 3 + 0] / sc;
face.vertex[i][1] = (model->vertex[varr[i] * 3 + 1] + dm) / sc;
face.vertex[i][2] = model->vertex[varr[i] * 3 + 2] / sc;
}
if(arrlen(model->texcoord) > tarr[i] * 2) {
face.texcoord[i][0] = model->texcoord[tarr[i] * 2 + 0];
face.texcoord[i][1] = 1 - model->texcoord[tarr[i] * 2 + 1];
}
}
}
if(c == 3) GSMathNormal3x3(face.normal, face.vertex[0], face.vertex[1], face.vertex[2]);
if(c == 4) GSMathNormal3x4(face.normal, face.vertex[0], face.vertex[1], face.vertex[2], face.vertex[3]);
arrput(model->face, face);
}
}
}
if(s == NULL) break;
f = s + 1;
}
}
GSModel GSModelOpen(GSEngine engine, const char* path) {
GSModel model = malloc(sizeof(*model));
GSFile f;
char* buffer;
unsigned int size;
int w, h;
GSGL gl = NULL;
if(engine->client != NULL) gl = engine->client->gl;
memset(model, 0, sizeof(*model));
model->engine = engine;
if(!GSEngineRegisterResource(engine, "model-ws", path)) {
GSModelClose(model);
return NULL;
}
if((f = GSFileOpen(engine, "model-ws:/model.obj")) == NULL) {
GSEngineUnregisterResource(engine, "model-ws");
GSModelClose(model);
return NULL;
}
if(gl != NULL) {
if(GSGLTextureLoadFile(gl, &model->texture, &w, &h, "model-ws:/model.png")) {
} else if(GSGLTextureLoadFile(gl, &model->texture, &w, &h, "model-ws:/model.bmp")) {
} else if(GSGLTextureLoadFile(gl, &model->texture, &w, &h, "model-ws:/model.jpg")) {
} else if(GSGLTextureLoadFile(gl, &model->texture, &w, &h, "model-ws:/model.jpeg")) {
}
}
size = GSFileSize(f);
buffer = malloc(size + 1);
buffer[size] = 0;
GSFileRead(f, buffer, size);
GSFileClose(f);
parse_obj(model, buffer);
free(buffer);
GSEngineUnregisterResource(engine, "model-ws");
GSLog(GSLogInfo, "Opened model %s, %d vertexes, %d faces", path, arrlen(model->vertex), arrlen(model->face));
/* TODO: check for animation */
if(gl != NULL) {
GSVector3 pos = {0, 0, 0};
GSVector3 rot = {0, 0, 0};
GLuint list = GSGLBeginList(gl);
GSModelDraw(model, pos, rot);
GSGLEndList(gl);
model->call_list = list;
}
return model;
}
void GSModelDraw(GSModel model, GSVector3 pos, GSVector3 rot) {
GSGL gl = model->engine->client->gl;
int i;
GSGLPushMatrix(gl);
GSGLSetPosition(gl, pos, rot);
if(model->call_list == 0) {
GSGLTextureSet(gl, model->texture);
for(i = 0; i < arrlen(model->face); i++) {
GSGLPolygon(gl, model->face[i].count, model->face[i].vertex, model->face[i].texcoord, model->face[i].normal);
}
GSGLTextureSet(gl, 0);
} else {
GSGLCallList(gl, model->call_list);
}
GSGLPopMatrix(gl);
}
void GSModelClose(GSModel model) {
int i;
for(i = 0; i < arrlen(model->face); i++) {
if(model->face[i].vertex != NULL) free(model->face[i].vertex);
if(model->face[i].texcoord != NULL) free(model->face[i].texcoord);
}
arrfree(model->face);
arrfree(model->vertex);
arrfree(model->texcoord);
if(model->texture != 0) GSGLTextureDelete(model->engine->client->gl, model->texture);
free(model);
}

View file

@ -76,7 +76,7 @@ void GSSkyBoxDraw(GSSkyBox skybox) {
GSVector3 v[4];
GSVector2 t[4];
GSVector3 n = {0, 0, 0};
GSNumber s = 0.0001;
GSNumber s = 0.001;
t[0][0] = 0, t[0][1] = 0;

View file

@ -1,11 +1,11 @@
#include <stb_image_write.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <GearSrc/File.h>
#include <stb_image_write.h>
#define CHECK(s) ((linelen > strlen(s)) && memcmp(line, s, strlen(s)) == 0)
int main() {

View file

@ -1,5 +1,6 @@
#include <stb_ds.h>
#include <lz4.h>
#ifdef _WIN32
#include <windows.h>
#else
@ -254,7 +255,7 @@ static void recursive(file_t* parent) {
}
int main(int argc, char** argv) {
unsigned char dat[128];
unsigned char dat[4];
printf("GearSrc Engine resource packer\n");
if(argc >= 2) {

File diff suppressed because it is too large Load diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 890 KiB

View file

@ -13,5 +13,9 @@ if [ ! "x$WINE" = "x" ]; then
E=.exe
fi
ls -d ../resource/model/* | while read a; do
N=`echo $a | rev | cut -d/ -f1 | rev`
$W ./engine/tools/gs_makepak$E ../data/mdl/$N.mdl ../resource/model/$N
done
$W ./engine/tools/gs_makepak$E base.pak ../engine/data
$W ./engine/tools/gs_makepak$E game.pak ../data