Faster is_top by way of a depth map
This commit is contained in:
parent
70fa12eaf6
commit
a1a6303bee
@ -53,6 +53,11 @@ clean:
|
||||
@${CC} ${CFLAGS} ${EXTRAFLAGS} ${FREETYPE_INC} -o $@ $< lib/graphics.o lib/list.o lib/window.o ${FREETYPE_LIB} ${ERRORS}
|
||||
@${END} "CC" "$< [w/libs]"
|
||||
|
||||
../hdd/bin/game-win: game-win.c lib/graphics.o lib/list.o lib/window.o
|
||||
@${BEG} "CC" "$< [w/libs]"
|
||||
@${CC} ${CFLAGS} ${EXTRAFLAGS} ${FREETYPE_INC} -o $@ $< lib/graphics.o lib/list.o lib/window.o ${FREETYPE_LIB} ${ERRORS}
|
||||
@${END} "CC" "$< [w/libs]"
|
||||
|
||||
../hdd/bin/drawlines: drawlines.c lib/graphics.o lib/list.o lib/window.o
|
||||
@${BEG} "CC" "$< [w/libs]"
|
||||
@${CC} ${CFLAGS} ${EXTRAFLAGS} ${FREETYPE_INC} -o $@ $< lib/graphics.o lib/list.o lib/window.o ${FREETYPE_LIB} ${ERRORS}
|
||||
|
@ -77,6 +77,8 @@ extern window_t * init_window (process_windows_t * pw, wid_t wid, int32_t x, int
|
||||
extern void free_window (window_t * window);
|
||||
extern void resize_window_buffer (window_t * window, int16_t left, int16_t top, uint16_t width, uint16_t height);
|
||||
|
||||
uint16_t * depth_map = NULL;
|
||||
|
||||
process_windows_t * get_process_windows (uint32_t pid) {
|
||||
foreach(n, process_list) {
|
||||
process_windows_t * pw = (process_windows_t *)n->value;
|
||||
@ -149,6 +151,14 @@ uint8_t is_top(window_t *window, uint16_t x, uint16_t y) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint8_t is_top_fast(window_t * window, uint16_t x, uint16_t y) {
|
||||
if (x >= graphics_width || y >= graphics_height)
|
||||
return 0;
|
||||
if (window->z == depth_map[x + y * graphics_width])
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
window_t * top_at(uint16_t x, uint16_t y) {
|
||||
uint32_t index_top = 0;
|
||||
window_t * window_top = NULL;
|
||||
@ -226,13 +236,8 @@ void redraw_window(window_t *window, uint16_t x, uint16_t y, uint16_t width, uin
|
||||
|
||||
for (uint16_t y = _lo_y; y < _hi_y; ++y) {
|
||||
for (uint16_t x = _lo_x; x < _hi_x; ++x) {
|
||||
if (is_top(window, x, y)) {
|
||||
#if 0
|
||||
assert(0 <= x);
|
||||
assert(x < GFX_W);
|
||||
assert(0 <= y);
|
||||
assert(y < GFX_H);
|
||||
#endif
|
||||
/* XXX MAKE THIS FASTER */
|
||||
if (is_top_fast(window, x, y)) {
|
||||
if (TO_WINDOW_OFFSET(x,y) >= window->width * window->height) continue;
|
||||
GFX(x,y) = ((uint32_t *)window->buffer)[TO_WINDOW_OFFSET(x,y)];
|
||||
}
|
||||
@ -259,6 +264,7 @@ void redraw_region_slow(int32_t x, int32_t y, int32_t width, int32_t height) {
|
||||
window_t * window = top_at(x,y);
|
||||
if (!window) continue;
|
||||
GFX(x,y) = ((uint32_t *)window->buffer)[TO_WINDOW_OFFSET(x,y)];
|
||||
depth_map[x + y * graphics_width] = window->z;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -329,12 +335,16 @@ void process_window_command (int sig) {
|
||||
int max_requests_per_cycle = 3;
|
||||
|
||||
while ((buf.st_size > 0) && (max_requests_per_cycle > 0)) {
|
||||
if (!(buf.st_size > sizeof(wins_packet_t))) {
|
||||
fstat(pw->command_pipe, &buf);
|
||||
continue;
|
||||
}
|
||||
w_window_t wwt;
|
||||
wins_packet_t header;
|
||||
int bytes_read = read(pw->command_pipe, &header, sizeof(wins_packet_t));
|
||||
|
||||
while (header.magic != WINS_MAGIC) {
|
||||
printf("Magic is wrong, expected 0x%x but got 0x%x [read %d bytes of %d]\n", WINS_MAGIC, header.magic, bytes_read, sizeof(header));
|
||||
printf("Magic is wrong from pid %d, expected 0x%x but got 0x%x [read %d bytes of %d]\n", pw->pid, WINS_MAGIC, header.magic, bytes_read, sizeof(header));
|
||||
goto bad_magic;
|
||||
memcpy(&header, (void *)((uintptr_t)&header + 1), (sizeof(header) - 1));
|
||||
read(pw->event_pipe, (char *)((uintptr_t)&header + sizeof(header) - 1), 1);
|
||||
@ -348,6 +358,7 @@ void process_window_command (int sig) {
|
||||
read(pw->command_pipe, &wwt, sizeof(w_window_t));
|
||||
wwt.wid = _next_wid;
|
||||
init_window(pw, _next_wid++, wwt.left, wwt.top, wwt.width, wwt.height, _next_wid + 5); //XXX: an actual index
|
||||
redraw_region_slow(0,0,graphics_width,graphics_height);
|
||||
send_window_event(pw, WE_NEWWINDOW, wwt);
|
||||
break;
|
||||
|
||||
@ -700,6 +711,7 @@ void init_base_windows () {
|
||||
window_draw_sprite(panel, sprites[2], i, 0);
|
||||
}
|
||||
redraw_full_window(panel);
|
||||
redraw_region_slow(0,0,graphics_width,graphics_height);
|
||||
#endif
|
||||
|
||||
init_sprite(3, "/usr/share/arrow.bmp","/usr/share/arrow_alpha.bmp");
|
||||
@ -827,6 +839,8 @@ int main(int argc, char ** argv) {
|
||||
/* Initialize graphics setup */
|
||||
init_graphics_double_buffer();
|
||||
|
||||
depth_map = malloc(sizeof(uint16_t) * graphics_width * graphics_height);
|
||||
|
||||
/* Initialize the client request system */
|
||||
init_request_system();
|
||||
|
||||
|
262
userspace/game-win.c
Normal file
262
userspace/game-win.c
Normal file
@ -0,0 +1,262 @@
|
||||
/*
|
||||
* The ToAru Sample Game
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <syscall.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "lib/window.h"
|
||||
#include "lib/graphics.h"
|
||||
|
||||
sprite_t * sprites[128];
|
||||
window_t * window;
|
||||
|
||||
#define WINDOW_SIZE 224
|
||||
int out_of_bounds(int x, int y) {
|
||||
if (x < graphics_width / 2 - WINDOW_SIZE)
|
||||
return 1;
|
||||
if (x >= graphics_width / 2 + WINDOW_SIZE)
|
||||
return 1;
|
||||
if (y < graphics_height / 2 - WINDOW_SIZE)
|
||||
return 1;
|
||||
if (y >= graphics_height / 2 + WINDOW_SIZE)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* RPG Mapping Bits */
|
||||
struct {
|
||||
int width;
|
||||
int height;
|
||||
char * buffer;
|
||||
int size;
|
||||
} map;
|
||||
|
||||
void load_map(char * filename) {
|
||||
FILE * f = fopen(filename, "r");
|
||||
char tmp[256];
|
||||
fgets(tmp, 255, f);
|
||||
map.width = atoi(tmp);
|
||||
fgets(tmp, 256, f);
|
||||
map.height = atoi(tmp);
|
||||
map.size = map.height * map.width;
|
||||
map.buffer = malloc(map.size);
|
||||
fread(map.buffer, map.size, 1, f);
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
char cell(int x, int y) {
|
||||
if (x < 0 || y < 0 || x >= map.width || y >= map.height) {
|
||||
return 'A'; /* The abyss is trees! */
|
||||
}
|
||||
return (map.buffer[y * map.width + x]);
|
||||
}
|
||||
|
||||
#define VIEW_SIZE 4
|
||||
#define CELL_SIZE 64
|
||||
|
||||
int my_x = 2;
|
||||
int my_y = 2;
|
||||
int direction = 0;
|
||||
int offset_x = 0;
|
||||
int offset_y = 0;
|
||||
int offset_iter = 0;
|
||||
int map_x;
|
||||
int map_y;
|
||||
|
||||
void render_map(int x, int y) {
|
||||
int i = 0;
|
||||
for (int _y = y - VIEW_SIZE; _y <= y + VIEW_SIZE; ++_y) {
|
||||
int j = 0;
|
||||
for (int _x = x - VIEW_SIZE; _x <= x + VIEW_SIZE; ++_x) {
|
||||
char c = cell(_x,_y);
|
||||
int sprite;
|
||||
switch (c) {
|
||||
case '\n':
|
||||
case 'A':
|
||||
sprite = 1;
|
||||
break;
|
||||
case '.':
|
||||
sprite = 2;
|
||||
break;
|
||||
case 'W':
|
||||
sprite = 3;
|
||||
break;
|
||||
default:
|
||||
sprite = 0;
|
||||
break;
|
||||
}
|
||||
draw_sprite(sprites[sprite],
|
||||
map_x + offset_x * offset_iter + j * CELL_SIZE,
|
||||
map_y + offset_y * offset_iter + i * CELL_SIZE);
|
||||
++j;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void display() {
|
||||
render_map(my_x,my_y);
|
||||
draw_sprite(sprites[124 + direction], map_x + CELL_SIZE * 4, map_y + CELL_SIZE * 4);
|
||||
flip();
|
||||
window_redraw_full(window);
|
||||
}
|
||||
|
||||
void transition(int nx, int ny) {
|
||||
if (nx < my_x) {
|
||||
offset_x = 1;
|
||||
offset_y = 0;
|
||||
} else if (ny < my_y) {
|
||||
offset_x = 0;
|
||||
offset_y = 1;
|
||||
} else if (nx > my_x) {
|
||||
offset_x = -1;
|
||||
offset_y = 0;
|
||||
} else if (ny > my_y) {
|
||||
offset_x = 0;
|
||||
offset_y = -1;
|
||||
}
|
||||
for (int i = 0; i < 64; i += 2) {
|
||||
offset_iter = i;
|
||||
display();
|
||||
}
|
||||
offset_iter = 0;
|
||||
offset_x = 0;
|
||||
offset_y = 0;
|
||||
my_x = nx;
|
||||
my_y = ny;
|
||||
}
|
||||
|
||||
void move(int cx, int cy) {
|
||||
int nx = my_x + cx;
|
||||
int ny = my_y + cy;
|
||||
|
||||
if (cx == 1) {
|
||||
if (direction != 1) {
|
||||
direction = 1;
|
||||
return;
|
||||
}
|
||||
} else if (cx == -1) {
|
||||
if (direction != 2) {
|
||||
direction = 2;
|
||||
return;
|
||||
}
|
||||
} else if (cy == 1) {
|
||||
if (direction != 0) {
|
||||
direction = 0;
|
||||
return;
|
||||
}
|
||||
} else if (cy == -1) {
|
||||
if (direction != 3) {
|
||||
direction = 3;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
switch (cell(nx,ny)) {
|
||||
case '_':
|
||||
case '.':
|
||||
transition(nx,ny);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* woah */
|
||||
char font_buffer[400000];
|
||||
sprite_t alpha_tmp;
|
||||
|
||||
void init_sprite(int i, char * filename, char * alpha) {
|
||||
sprites[i] = malloc(sizeof(sprite_t));
|
||||
load_sprite(sprites[i], filename);
|
||||
if (alpha) {
|
||||
sprites[i]->alpha = 1;
|
||||
load_sprite(&alpha_tmp, alpha);
|
||||
sprites[i]->masks = alpha_tmp.bitmap;
|
||||
} else {
|
||||
sprites[i]->alpha = 0;
|
||||
}
|
||||
sprites[i]->blank = 0x0;
|
||||
}
|
||||
|
||||
int main(int argc, char ** argv) {
|
||||
setup_windowing();
|
||||
|
||||
window = window_create(0,0, 2 * WINDOW_SIZE, 2 * WINDOW_SIZE);
|
||||
window_fill(window, rgb(100,100,100));
|
||||
init_graphics_window_double_buffer(window);
|
||||
|
||||
map_x = GFX_W / 2 - (64 * 9) / 2;
|
||||
map_y = GFX_H / 2 - (64 * 9) / 2;
|
||||
printf("Graphics memory is at %p, backbuffer is at %p.\n", gfx_mem, frame_mem);
|
||||
|
||||
printf("Loading sprites...\n");
|
||||
init_sprite(0, "/etc/game/0.bmp", NULL);
|
||||
init_sprite(1, "/etc/game/1.bmp", NULL);
|
||||
init_sprite(2, "/etc/game/2.bmp", NULL);
|
||||
init_sprite(3, "/etc/game/3.bmp", NULL);
|
||||
init_sprite(4, "/etc/game/4.bmp", NULL);
|
||||
init_sprite(5, "/etc/game/5.bmp", NULL);
|
||||
init_sprite(6, "/etc/game/6.bmp", NULL);
|
||||
init_sprite(7, "/etc/game/7.bmp", NULL);
|
||||
init_sprite(124, "/etc/game/remilia.bmp", NULL);
|
||||
init_sprite(125, "/etc/game/remilia_r.bmp", NULL);
|
||||
init_sprite(126, "/etc/game/remilia_l.bmp", NULL);
|
||||
init_sprite(127, "/etc/game/remilia_f.bmp", NULL);
|
||||
load_map("/etc/game/map");
|
||||
printf("%d x %d\n", map.width, map.height);
|
||||
|
||||
int playing = 1;
|
||||
while (playing) {
|
||||
|
||||
display();
|
||||
|
||||
char ch = 0;
|
||||
w_keyboard_t * kbd;
|
||||
do {
|
||||
kbd = poll_keyboard();
|
||||
if (kbd != NULL) {
|
||||
ch = kbd->key;
|
||||
free(kbd);
|
||||
}
|
||||
} while (kbd != NULL);
|
||||
|
||||
if (ch) {
|
||||
printf("Key press: '%c'\n", ch);
|
||||
}
|
||||
|
||||
switch (ch) {
|
||||
case 'q':
|
||||
playing = 0;
|
||||
break;
|
||||
case 'a':
|
||||
move(-1,0);
|
||||
/* left */
|
||||
break;
|
||||
case 'd':
|
||||
move(1,0);
|
||||
/* right */
|
||||
break;
|
||||
case 's':
|
||||
move(0,1);
|
||||
/* Down */
|
||||
break;
|
||||
case 'w':
|
||||
move(0,-1);
|
||||
/* Up */
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
teardown_windowing();
|
||||
|
||||
return 0;
|
||||
}
|
@ -253,6 +253,9 @@ void wins_send_command (wid_t wid, int16_t left, int16_t top, uint16_t width, ui
|
||||
LOCK(wins_command_lock);
|
||||
wins_command_recvd = 0xFF; // XXX: Will this work?
|
||||
|
||||
if (command == WC_NEWWINDOW) {
|
||||
fprintf(stderr, "> Creating a window. Sending a packet of size %d+%d\n", sizeof(wins_packet_t), sizeof(w_window_t));
|
||||
}
|
||||
write(process_windows->command_pipe, &header, sizeof(wins_packet_t));
|
||||
write(process_windows->command_pipe, &packet, sizeof(w_window_t));
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user