enable_fpexcept();
#endif
+#ifdef GFX_SW
+ gaw_sw_init();
+#endif
+
load_options("retroray.cfg");
app_resize(opt.xres, opt.yres);
app_vsync(opt.vsync);
destroy_font(uifont);
free(uifont);
+#ifdef GFX_SW
+ gaw_sw_destroy();
+#endif
+
cleanup_logger();
}
int numpix = x * y;
int prev_numpix = win_width * win_height;
- if(numpix > prev_numpix) {
+ printf("reshape(%d, %d)\n", x, y);
+
+ if(!framebuf || numpix > prev_numpix) {
void *tmp;
if(!(tmp = realloc(framebuf, numpix * sizeof *framebuf))) {
errormsg("failed to resize framebuffer to %dx%d\n", x, y);
--- /dev/null
+/*
+Deep Runner - 6dof shooter game for the SGI O2.
+Copyright (C) 2023 John Tsiombikas <nuclear@mutantstargoat.com>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <https://www.gnu.org/licenses/>.
+*/
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "darray.h"
+#include "util.h"
+
+
+/* The array descriptor keeps auxilliary information needed to manipulate
+ * the dynamic array. It's allocated adjacent to the array buffer.
+ */
+struct arrdesc {
+ int nelem, szelem;
+ int max_elem;
+ int bufsz; /* not including the descriptor */
+};
+
+#define DESC(x) ((struct arrdesc*)((char*)(x) - sizeof(struct arrdesc)))
+
+void *darr_alloc(int elem, int szelem)
+{
+ struct arrdesc *desc;
+
+ desc = malloc_nf(elem * szelem + sizeof *desc);
+ desc->nelem = desc->max_elem = elem;
+ desc->szelem = szelem;
+ desc->bufsz = elem * szelem;
+ return (char*)desc + sizeof *desc;
+}
+
+void darr_free(void *da)
+{
+ if(da) {
+ free(DESC(da));
+ }
+}
+
+void *darr_resize_impl(void *da, int elem)
+{
+ int newsz;
+ struct arrdesc *desc;
+
+ if(!da) return 0;
+ desc = DESC(da);
+
+ newsz = desc->szelem * elem;
+ desc = realloc_nf(desc, newsz + sizeof *desc);
+
+ desc->nelem = desc->max_elem = elem;
+ desc->bufsz = newsz;
+ return (char*)desc + sizeof *desc;
+}
+
+int darr_empty(void *da)
+{
+ return DESC(da)->nelem ? 0 : 1;
+}
+
+int darr_size(void *da)
+{
+ return DESC(da)->nelem;
+}
+
+
+void *darr_clear_impl(void *da)
+{
+ return darr_resize_impl(da, 0);
+}
+
+/* stack semantics */
+void *darr_push_impl(void *da, void *item)
+{
+ struct arrdesc *desc;
+ int nelem;
+
+ desc = DESC(da);
+ nelem = desc->nelem;
+
+ if(nelem >= desc->max_elem) {
+ /* need to resize */
+ int newsz = desc->max_elem ? desc->max_elem * 2 : 1;
+
+ da = darr_resize_impl(da, newsz);
+ desc = DESC(da);
+ desc->nelem = nelem;
+ }
+
+ if(item) {
+ memcpy((char*)da + desc->nelem * desc->szelem, item, desc->szelem);
+ }
+ desc->nelem++;
+ return da;
+}
+
+void *darr_pop_impl(void *da)
+{
+ struct arrdesc *desc;
+ int nelem;
+
+ desc = DESC(da);
+ nelem = desc->nelem;
+
+ if(!nelem) return da;
+
+ if(nelem <= desc->max_elem / 3) {
+ /* reclaim space */
+ int newsz = desc->max_elem / 2;
+
+ da = darr_resize_impl(da, newsz);
+ desc = DESC(da);
+ desc->nelem = nelem;
+ }
+ desc->nelem--;
+
+ return da;
+}
+
+void *darr_finalize(void *da)
+{
+ struct arrdesc *desc = DESC(da);
+ memmove(desc, da, desc->bufsz);
+ return desc;
+}
--- /dev/null
+/*
+Deep Runner - 6dof shooter game for the SGI O2.
+Copyright (C) 2023 John Tsiombikas <nuclear@mutantstargoat.com>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <https://www.gnu.org/licenses/>.
+*/
+#ifndef DYNAMIC_ARRAY_H_
+#define DYNAMIC_ARRAY_H_
+
+void *darr_alloc(int elem, int szelem);
+void darr_free(void *da);
+void *darr_resize_impl(void *da, int elem);
+#define darr_resize(da, elem) do { (da) = darr_resize_impl(da, elem); } while(0)
+
+int darr_empty(void *da);
+int darr_size(void *da);
+
+void *darr_clear_impl(void *da);
+#define darr_clear(da) do { (da) = darr_clear_impl(da); } while(0)
+
+/* stack semantics */
+void *darr_push_impl(void *da, void *item);
+#define darr_push(da, item) do { (da) = darr_push_impl(da, item); } while(0)
+void *darr_pop_impl(void *da);
+#define darr_pop(da) do { (da) = darr_pop_impl(da); } while(0)
+
+/* Finalize the array. No more resizing is possible after this call.
+ * Use free() instead of dynarr_free() to deallocate a finalized array.
+ * Returns pointer to the finalized array.
+ * Complexity: O(n)
+ */
+void *darr_finalize(void *da);
+
+/* utility macros to push characters to a string. assumes and maintains
+ * the invariant that the last element is always a zero
+ */
+#define darr_strpush(da, c) \
+ do { \
+ char cnull = 0, ch = (char)(c); \
+ (da) = dynarr_pop_impl(da); \
+ (da) = dynarr_push_impl((da), &ch); \
+ (da) = dynarr_push_impl((da), &cnull); \
+ } while(0)
+
+#define darr_strpop(da) \
+ do { \
+ char cnull = 0; \
+ (da) = dynarr_pop_impl(da); \
+ (da) = dynarr_pop_impl(da); \
+ (da) = dynarr_push_impl((da), &cnull); \
+ } while(0)
+
+
+#endif /* DYNAMIC_ARRAY_H_ */
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
+#include <stdio.h>
#include <string.h>
#include "gaw.h"
#include "gawswtnl.h"
for(i=0; i<vnum; i++) {
/* viewport transformation */
v[i].x = (v[i].x * 0.5f + 0.5f) * (float)ST->vport[2] + ST->vport[0];
- v[i].y = (v[i].y * 0.5f + 0.5f) * (float)ST->vport[3] + ST->vport[1];
- v[i].y = pfill_fb.height - v[i].y - 1;
+ v[i].y = (v[i].y * -0.5f + 0.5f) * (float)ST->vport[3] + ST->vport[1] - 1;
/* convert pos to 24.8 fixed point */
pv[i].x = cround64(v[i].x * 256.0f);
break;
case GAW_LINES:
+ draw_line(pv);
break;
default:
/*
-Deep Runner - 6dof shooter game for the SGI O2.
+RetroRay - integrated standalone vintage modeller/renderer
Copyright (C) 2023 John Tsiombikas <nuclear@mutantstargoat.com>
This program is free software: you can redistribute it and/or modify
if(!vnum) continue;
for(i=0; i<vnum; i++) {
- if(v[i].w != 0.0f) {
- v[i].x /= v[i].w;
- v[i].y /= v[i].w;
- if(st.opt & (1 << GAW_DEPTH_TEST)) {
- v[i].z /= v[i].w;
- }
+ float oow = 1.0f / v[i].w;
+ v[i].x *= oow;
+ v[i].y *= oow;
+ if(st.opt & (1 << GAW_DEPTH_TEST)) {
+ v[i].z *= oow;
}
}
void gaw_begin(int prim)
{
st.imm_prim = prim;
- st.imm_pcount = prim;
+ st.imm_pcount = prim_vcount[st.imm_prim];
st.imm_numv = 0;
}
void gaw_vertex3f(float x, float y, float z)
{
gaw_vertex4f(x, y, z, 1);
+}
void gaw_vertex4f(float x, float y, float z, float w)
{
#include "polytmpl.h"
#undef POLYFILL
+
+void draw_line(struct pvertex *verts)
+{
+ int32_t x0, y0, x1, y1;
+ int i, dx, dy, x_inc, y_inc, error;
+ uint32_t *fb = pfill_fb.pixels;
+ uint32_t color = PACK_RGB(verts[0].r, verts[0].g, verts[0].b);
+
+ x0 = verts[0].x >> 8;
+ y0 = verts[0].y >> 8;
+ x1 = verts[1].x >> 8;
+ y1 = verts[1].y >> 8;
+
+ fb += y0 * pfill_fb.width + x0;
+
+ dx = x1 - x0;
+ dy = y1 - y0;
+
+ if(dx >= 0) {
+ x_inc = 1;
+ } else {
+ x_inc = -1;
+ dx = -dx;
+ }
+ if(dy >= 0) {
+ y_inc = pfill_fb.width;
+ } else {
+ y_inc = -pfill_fb.width;
+ dy = -dy;
+ }
+
+ if(dx > dy) {
+ error = dy * 2 - dx;
+ for(i=0; i<=dx; i++) {
+ *fb = color;
+ if(error >= 0) {
+ error -= dx * 2;
+ fb += y_inc;
+ }
+ error += dy * 2;
+ fb += x_inc;
+ }
+ } else {
+ error = dx * 2 - dy;
+ for(i=0; i<=dy; i++) {
+ *fb = color;
+ if(error >= 0) {
+ error -= dy * 2;
+ fb += x_inc;
+ }
+ error += dx * 2;
+ fb += y_inc;
+ }
+ }
+}
typedef uint32_t gaw_pixel;
#define PACK_RGB(r, g, b) \
- (((r) << 16) | ((g) << 8) | (b))
+ (0xff000000 | ((r) << 16) | ((g) << 8) | (b))
#define PACK_RGBA(r, g, b, a) \
(((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
#define UNPACK_R(pix) ((pix) & 0xff)
void polyfill_add_tex_flat_zbuf(struct pvertex *verts, int nverts);
void polyfill_add_tex_gouraud_zbuf(struct pvertex *verts, int nverts);
+void draw_line(struct pvertex *verts);
+
#endif /* POLYFILL_H_ */
wgl_swap_interval_ext = wglGetProcAddress("wglSwapIntervalEXT");
#endif
- app_reshape(glutGet(GLUT_WINDOW_WIDTH), glutGet(GLUT_WINDOW_HEIGHT));
+ win_width = glutGet(GLUT_WINDOW_WIDTH);
+ win_height = glutGet(GLUT_WINDOW_HEIGHT);
+ win_aspect = (float)win_width / win_height;
if(app_init() == -1) {
return 1;
draw_grid();
- gaw_begin(GAW_QUADS);
- gaw_color3f(1, 0, 0);
- gaw_vertex2f(-1, -1);
- gaw_color3f(0, 1, 0);
- gaw_vertex2f(1, -1);
- gaw_color3f(0, 0, 1);
- gaw_vertex2f(1, 1);
- gaw_color3f(1, 1, 0);
- gaw_vertex2f(-1, 1);
- gaw_end();
-
gaw_viewport(0, 0, win_width, win_height);
}
gaw_begin(GAW_LINES);
gaw_color3f(0.5, 0, 0);
gaw_vertex4f(0, 0, 0, 1);
- gaw_vertex4f(-1, 0, 0, 0);
+ gaw_vertex4f(-100, 0, 0, 1);
gaw_vertex4f(0, 0, 0, 1);
- gaw_vertex4f(1, 0, 0, 0);
+ gaw_vertex4f(100, 0, 0, 1);
gaw_color3f(0, 0.5, 0);
gaw_vertex4f(0, 0, 0, 1);
- gaw_vertex4f(0, 0, -1, 0);
+ gaw_vertex4f(0, 0, -100, 1);
gaw_vertex4f(0, 0, 0, 1);
- gaw_vertex4f(0, 0, 1, 0);
+ gaw_vertex4f(0, 0, 100, 1);
gaw_end();
}