!ifdef __UNIX__
-obj = src/dos/main.obj src/dos/video.obj src/gamescr.obj src/menuscr.obj &
- src/voxscape.obj src/lut.obj
+obj = src/dos/main.obj src/dos/video.obj src/game.obj src/gamescr.obj &
+ src/menuscr.obj src/voxscape.obj src/lut.obj
!else
-obj = src\dos\main.obj src\dos\video.obj src\gamescr.obj src\menuscr.obj &
- src\voxscape.obj src\lut.obj
+obj = src\dos\main.obj src\dos\video.obj src\game.obj src\gamescr.obj &
+ src\menuscr.obj src\voxscape.obj src\lut.obj
!endif
bin = game.com
int main(void)
{
- if(init_screens() == -1) {
+ if(init_game() == -1) {
return 1;
}
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include "video.h"
#include "game.h"
int gamescr_init(void);
int menuscr_init(void);
+float fov;
+int znear, zfar;
+
struct screen *scrlist[NUM_SCREENS];
struct screen *curscr;
-int init_screens(void)
+int init_game(void)
{
+ fov = 30.0f;
+ znear = 2;
+ zfar = 85;
+
if(menuscr_init() == -1) {
return -1;
}
curscr = scr;
return 0;
}
+
+void panic(const char *fmt, ...)
+{
+ va_list ap;
+
+ close_video();
+
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+
+ exit(1);
+}
void (*keypress)(int key);
};
+extern float fov;
+extern int znear, zfar;
+
extern struct screen *scrlist[NUM_SCREENS];
extern struct screen *curscr;
#define FBWIDTH 320
#define FBHEIGHT 200
-int init_screens(void);
+int init_game(void);
int change_screen(struct screen *scr);
void panic(const char *fmt, ...);
+#include <malloc.h>
#include "game.h"
+#include "voxscape.h"
+
+#define VOXSZ 256
static int gamescr_start(void);
static void gamescr_stop(void);
gamescr_keypress
};
+static unsigned char far *hmap;
+static unsigned char far *colmap;
+
int gamescr_init(void)
{
+ scrlist[SCR_GAME] = &gamescr;
return 0;
}
static int gamescr_start(void)
{
+ if(!(hmap = _fmalloc(VOXSZ * VOXSZ))) {
+ panic("failed to allocate %dx%d heightmap", VOXSZ, VOXSZ);
+ }
+ if(!(colmap = _fmalloc(VOXSZ * VOXSZ))) {
+ panic("failed to allocate %dx%d texture", VOXSZ, VOXSZ);
+ }
+ vox_init(VOXSZ, VOXSZ, hmap, colmap);
+ vox_proj(fov, znear, zfar);
return 0;
}
static void gamescr_stop(void)
{
+ _ffree(hmap);
}
static void gamescr_draw(void)
#define NO_LERP
#define XLERP(a, b, t, fp) \
- ((((a) << (fp)) + ((b) - (a)) * (t)) >> fp)
+ ((((int32_t)(a) << (fp)) + (int32_t)((b) - (a)) * (t)) >> (fp))
enum {
SLICELEN = 1
static int32_t vox_x, vox_y, vox_angle;
static int vox_vheight;
/* projection */
-static int vox_fov, vox_znear, vox_zfar;
+static float vox_fov;
+static int vox_znear, vox_zfar;
static int vox_nslices;
static int32_t far *vox_slicelen;
int far *projlut;
-int vox_init(int xsz, int ysz, uint8_t far *himg, uint8_t far *cimg)
+void vox_init(int x, int y, uint8_t far *himg, uint8_t far *cimg)
{
vox_hmap = himg;
vox_color = cimg;
+ xsz = x;
+ ysz = y;
+ xmask = x - 1;
+ ymask = y - 1;
+
+ xshift = 0;
+ while(x > 1) {
+ xshift++;
+ x >>= 1;
+ }
+
vox_fb = 0;
vox_coltop = 0;
vox_horizon = 0;
projlut = 0;
vox_vheight = 80;
-
- return 0;
}
void vox_destroy(void)
return h;
}
-void vox_proj(int fov, int znear, int zfar)
+void vox_proj(float fov, int znear, int zfar)
{
vox_fov = fov;
vox_znear = znear;
_fmemset(vox_coltop, 0, FBWIDTH * sizeof *vox_coltop);
if(!(vox_valid & SLICELEN)) {
- float theta = (float)vox_fov * M_PI / 360.0f; /* half angle */
+ float theta = vox_fov * M_PI / 360.0f; /* half angle */
for(i=0; i<vox_nslices; i++) {
vox_slicelen[i] = (int32_t)((vox_znear + i) * tan(theta) * 4.0f * 65536.0f);
projlut[i] = (hscale << 8) / (vox_znear + i);
/*proj = (HSCALE << 8) / (vox_znear + n);*/
- for(i=0; i<FBWIDTH/2; i++) {
+ for(i=0; i<FBWIDTH; i++) {
col = i << 1;
offs = (((y >> 16) & ymask) << xshift) + ((x >> 16) & xmask);
if(offs == last_offs) {
void vox_sky_grad(uint8_t chor, uint8_t ctop)
{
- int i, j, colheight, t;
- int d = FBHEIGHT - vox_horizon;
+ int i, j, colheight;
+ int32_t t, d = FBHEIGHT - vox_horizon;
uint8_t grad[FBHEIGHT];
uint16_t *fbptr;
for(i=0; i<d; i++) {
- t = (i << 16) / d;
+ t = ((int32_t)i << 16) / d;
grad[i] = XLERP(ctop, chor, t, 16);
}
for(i=d; i<FBHEIGHT; i++) {
}
}
-int vox_height(int x, int y)
-{
- return H(x, y);
-}
-
int vox_check_vis(int32_t x0, int32_t y0, int32_t x1, int32_t y1)
{
/* TODO */
extern int far *projlut;
-int vox_init(int xsz, int ysz, uint8_t far *himg, uint8_t far *cimg);
+void vox_init(int xsz, int ysz, uint8_t far *himg, uint8_t far *cimg);
void vox_destroy(void);
void vox_framebuf(int xres, int yres, void *fb, int horizon);
/* negative height for auto at -h above terrain */
int vox_view(int32_t x, int32_t y, int h, int32_t angle);
-void vox_proj(int fov, int znear, int zfar);
+void vox_proj(float fov, int znear, int zfar);
void vox_render(void);
void vox_sky_solid(uint8_t color);
void vox_sky_grad(uint8_t chor, uint8_t ctop);
-int vox_height(int x, int y);
int vox_check_vis(int32_t x0, int32_t y0, int32_t x1, int32_t y1);
#endif /* VOXSCAPE_H_ */