[userspace] really simple second compositor built on shm
This commit is contained in:
parent
45903b204b
commit
d28726fae7
@ -2,6 +2,7 @@ CC = i686-pc-toaru-gcc
|
||||
CPP = i686-pc-toaru-g++
|
||||
CFLAGS = -march=core2 -std=c99 -O3 -m32 -Wa,--32 -Xlinker --eh-frame-hdr
|
||||
CPPFLAGS = -march=core2 -O3 -m32 -Wa,--32
|
||||
EXTRAFLAGS = -g
|
||||
EXECUTABLES = $(patsubst %.c,%.o,$(wildcard lib/*.c)) $(patsubst %.c,../hdd/bin/%,$(wildcard *.c)) $(patsubst %.cpp,../hdd/bin/%,$(wildcard *.cpp))
|
||||
|
||||
BEG = ../util/mk-beg
|
||||
@ -29,50 +30,50 @@ clean:
|
||||
|
||||
../hdd/bin/freetype_test: freetype_test.c
|
||||
@${BEG} "CC" "$< [freetype]"
|
||||
@${CC} ${CFLAGS} -s ${FREETYPE_INC} -o $@ $< ${FREETYPE_LIB} ${ERRORS}
|
||||
@${CC} ${CFLAGS} ${EXTRAFLAGS} ${FREETYPE_INC} -o $@ $< ${FREETYPE_LIB} ${ERRORS}
|
||||
@${END} "CC" "$< [freetype]"
|
||||
|
||||
../hdd/bin/terminal: terminal.c lib/utf8_decode.o
|
||||
@${BEG} "CC" "$< [freetype]"
|
||||
@${CC} ${CFLAGS} -s ${FREETYPE_INC} -o $@ $< ${FREETYPE_LIB} lib/utf8_decode.o ${ERRORS}
|
||||
@${CC} ${CFLAGS} ${EXTRAFLAGS} ${FREETYPE_INC} -o $@ $< ${FREETYPE_LIB} lib/utf8_decode.o ${ERRORS}
|
||||
@${END} "CC" "$< [freetype]"
|
||||
|
||||
../hdd/bin/login: login.c lib/sha2.o
|
||||
@${BEG} "CC" "$< [w/libs]"
|
||||
@${CC} ${CFLAGS} -s -o $@ $< lib/sha2.o ${ERRORS}
|
||||
@${CC} ${CFLAGS} ${EXTRAFLAGS} -o $@ $< lib/sha2.o ${ERRORS}
|
||||
@${END} "CC" "$< [w/libs]"
|
||||
|
||||
../hdd/bin/compositor: compositor.c lib/graphics.o lib/list.o
|
||||
@${BEG} "CC" "$< [w/libs]"
|
||||
@${CC} ${CFLAGS} -s ${FREETYPE_INC} -o $@ $< lib/graphics.o lib/list.o ${FREETYPE_LIB} ${ERRORS}
|
||||
@${CC} ${CFLAGS} ${EXTRAFLAGS} ${FREETYPE_INC} -o $@ $< lib/graphics.o lib/list.o ${FREETYPE_LIB} ${ERRORS}
|
||||
@${END} "CC" "$< [w/libs]"
|
||||
|
||||
../hdd/bin/solver: solver.c lib/list.o
|
||||
@${BEG} "CC" "$< [w/libs]"
|
||||
@${CC} ${CFLAGS} -s -o $@ $< lib/list.o ${ERRORS}
|
||||
@${CC} ${CFLAGS} ${EXTRAFLAGS} -o $@ $< lib/list.o ${ERRORS}
|
||||
@${END} "CC" "$< [w/libs]"
|
||||
|
||||
../hdd/bin/donu%: donu%.c
|
||||
@${BEG} "CC" "$< [w/libs]"
|
||||
@${CC} ${CFLAGS} -g -o $@ $< ${LIBM} ${ERRORS}
|
||||
@${CC} ${CFLAGS} ${EXTRAFLAGS} -o $@ $< ${LIBM} ${ERRORS}
|
||||
@${END} "CC" "$< [w/libs]"
|
||||
|
||||
../hdd/bin/%: %.cpp
|
||||
@${BEG} "CPP" "$<"
|
||||
@${CPP} ${CPPFLAGS} -s -o $@ $< ${ERRORS}
|
||||
@${CPP} ${CPPFLAGS} ${EXTRAFLAGS} -o $@ $< ${ERRORS}
|
||||
@${END} "CPP" "$<"
|
||||
|
||||
../hdd/bin/ld: ld.c
|
||||
@${BEG} "CC" "$< [-fPIC]"
|
||||
@${CC} ${CFLAGS} -s -fPIC -o $@ $< ${ERRORS}
|
||||
@${CC} ${CFLAGS} ${EXTRAFLAGS} -fPIC -o $@ $< ${ERRORS}
|
||||
@${END} "CC" "$< [-fPIC]"
|
||||
|
||||
../hdd/bin/%: %.c
|
||||
@${BEG} "CC" "$<"
|
||||
@${CC} ${CFLAGS} -s -o $@ $< ${ERRORS}
|
||||
@${CC} ${CFLAGS} ${EXTRAFLAGS} -o $@ $< ${ERRORS}
|
||||
@${END} "CC" "$<"
|
||||
|
||||
%.o: %.c
|
||||
@${BEG} "CC" "$< [lib]"
|
||||
@${CC} ${CFLAGS} -c -s -o $@ $< ${ERRORS}
|
||||
@${CC} ${CFLAGS} -c ${EXTRAFLAGS} -o $@ $< ${ERRORS}
|
||||
@${END} "CC" "$< [lib]"
|
||||
|
100
userspace/compositor2.c
Normal file
100
userspace/compositor2.c
Normal file
@ -0,0 +1,100 @@
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <syscall.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include "lib/graphics.c"
|
||||
|
||||
#define BUFW 800
|
||||
#define BUFH 800
|
||||
#define BUFD 4
|
||||
#define SIZE BUFW * BUFH * BUFD
|
||||
#define WIDTH "800"
|
||||
#define HEIGHT "800"
|
||||
#define DEPTH "32"
|
||||
|
||||
#if 0
|
||||
uint16_t graphics_width = 0;
|
||||
uint16_t graphics_height = 0;
|
||||
uint16_t graphics_depth = 0;
|
||||
|
||||
#define GFX_W graphics_width
|
||||
#define GFX_H graphics_height
|
||||
#define GFX_D graphics_depth
|
||||
#define GFX_B (graphics_depth / 8) /* Display byte depth */
|
||||
#define GFX(x,y) *((uint32_t *)&frame_mem[(GFX_W * (y) + (x)) * GFX_B])
|
||||
#endif
|
||||
#define BUF(buf,x,y) *((uint32_t *)&buf[(BUFW * (y) + (x)) * BUFD])
|
||||
|
||||
/*
|
||||
DEFN_SYSCALL0(getgraphicsaddress, 11);
|
||||
DEFN_SYSCALL1(setgraphicsoffset, 16, int);
|
||||
DEFN_SYSCALL0(getgraphicswidth, 18);
|
||||
DEFN_SYSCALL0(getgraphicsheight, 19);
|
||||
DEFN_SYSCALL0(getgraphicsdepth, 20);
|
||||
*/
|
||||
DEFN_SYSCALL2(shm_obtain, 35, char *, int)
|
||||
DEFN_SYSCALL1(shm_release, 36, char *)
|
||||
|
||||
|
||||
void composite (char * buf, uint16_t x_off, uint16_t y_off) {
|
||||
for (int y = 0; y < BUFH; y++) {
|
||||
int ytrue = y + y_off;
|
||||
if (ytrue > GFX_H) {
|
||||
break;
|
||||
}
|
||||
|
||||
for (int x = 0; x < BUFW; x++) {
|
||||
int xtrue = x + x_off;
|
||||
if (xtrue > GFX_W) {
|
||||
break;
|
||||
}
|
||||
|
||||
GFX(xtrue,ytrue) = BUF(buf,x,y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main (int argc, char ** argv) {
|
||||
|
||||
/* graphics_width = syscall_getgraphicswidth();
|
||||
graphics_height = syscall_getgraphicsheight();
|
||||
graphics_depth = syscall_getgraphicsdepth();
|
||||
int map_x = GFX_W / 2 - (64 * 9) / 2;
|
||||
int map_y = GFX_H / 2 - (64 * 9) / 2;
|
||||
int flip_offset = GFX_H;
|
||||
gfx_mem = (void *)syscall_getgraphicsaddress();
|
||||
frame_mem = (void *)((uintptr_t)gfx_mem + sizeof(uint32_t) * GFX_W * GFX_H);*/
|
||||
|
||||
init_graphics_double_buffer();
|
||||
|
||||
char * julia_window_key = "julia2.windowbuffer";
|
||||
char * game_window_key = "game2.windowbuffer";
|
||||
|
||||
char * julia_window = (char *)syscall_shm_obtain(julia_window_key, SIZE);
|
||||
char * game_window = (char *)syscall_shm_obtain(game_window_key, SIZE);
|
||||
memset(julia_window, 0, SIZE);
|
||||
memset(game_window, 0, SIZE);
|
||||
|
||||
/* Fork off two children */
|
||||
if (!fork()) {
|
||||
char * args[] = {"/bin/julia2", WIDTH, HEIGHT, DEPTH, julia_window_key, NULL};
|
||||
execve(args[0], args, NULL);
|
||||
}
|
||||
if (!fork()) {
|
||||
char * args[] = {"/bin/game2", WIDTH, HEIGHT, DEPTH, game_window_key, NULL};
|
||||
execve(args[0], args, NULL);
|
||||
}
|
||||
|
||||
/* write loop */
|
||||
while (1) {
|
||||
composite(julia_window, 0, 0);
|
||||
composite(game_window, 100, 100);
|
||||
flip();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
418
userspace/game2.c
Normal file
418
userspace/game2.c
Normal file
@ -0,0 +1,418 @@
|
||||
/*
|
||||
* The ToAru Sample Game
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <syscall.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
DEFN_SYSCALL1(kbd_mode, 12, int);
|
||||
DEFN_SYSCALL0(kbd_get, 13);
|
||||
DEFN_SYSCALL2(shm_obtain, 35, char *, int)
|
||||
DEFN_SYSCALL1(shm_release, 36, char *)
|
||||
|
||||
typedef struct sprite {
|
||||
uint16_t width;
|
||||
uint16_t height;
|
||||
uint32_t * bitmap;
|
||||
uint32_t * masks;
|
||||
uint32_t blank;
|
||||
uint8_t alpha;
|
||||
} sprite_t;
|
||||
|
||||
uint16_t graphics_width = 0;
|
||||
uint16_t graphics_height = 0;
|
||||
uint16_t graphics_depth = 0;
|
||||
|
||||
#define GFX_W graphics_width
|
||||
#define GFX_H graphics_height
|
||||
#define GFX_B (graphics_depth / 8) /* Display byte depth */
|
||||
#define GFX(x,y) *((uint32_t *)&frame_mem[(GFX_W * (y) + (x)) * GFX_B])
|
||||
#define SPRITE(sprite,x,y) sprite->bitmap[sprite->width * (y) + (x)]
|
||||
#define SMASKS(sprite,x,y) sprite->masks[sprite->width * (y) + (x)]
|
||||
|
||||
uint8_t * gfx_mem;
|
||||
uint8_t * frame_mem;
|
||||
uint32_t gfx_size;
|
||||
sprite_t * sprites[128];
|
||||
|
||||
|
||||
void * malloc_(size_t size)
|
||||
{
|
||||
void * ret = malloc(size);
|
||||
if (!ret) {
|
||||
printf("[WARNING!] malloc_(%d) returned NULL!\n", size);
|
||||
while ((ret = malloc(size)) == NULL) {
|
||||
printf(".");
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
uint32_t rgb(uint8_t r, uint8_t g, uint8_t b) {
|
||||
return (r * 0x10000) + (g * 0x100) + (b * 0x1);
|
||||
}
|
||||
|
||||
uint32_t flip_offset;
|
||||
|
||||
void flip() {
|
||||
memcpy(gfx_mem, frame_mem, gfx_size);
|
||||
memset(frame_mem, 0, GFX_H * GFX_W * GFX_B);
|
||||
}
|
||||
|
||||
void
|
||||
load_sprite(sprite_t * sprite, char * filename) {
|
||||
/* Open the requested binary */
|
||||
FILE * image = fopen(filename, "r");
|
||||
size_t image_size= 0;
|
||||
|
||||
fseek(image, 0, SEEK_END);
|
||||
image_size = ftell(image);
|
||||
fseek(image, 0, SEEK_SET);
|
||||
|
||||
/* Alright, we have the length */
|
||||
char * bufferb = malloc_(image_size);
|
||||
fread(bufferb, image_size, 1, image);
|
||||
uint16_t x = 0; /* -> 212 */
|
||||
uint16_t y = 0; /* -> 68 */
|
||||
/* Get the width / height of the image */
|
||||
signed int *bufferi = (signed int *)((uintptr_t)bufferb + 2);
|
||||
uint32_t width = bufferi[4];
|
||||
uint32_t height = bufferi[5];
|
||||
uint16_t bpp = bufferi[6] / 0x10000;
|
||||
uint32_t row_width = (bpp * width + 31) / 32 * 4;
|
||||
/* Skip right to the important part */
|
||||
size_t i = bufferi[2];
|
||||
|
||||
sprite->width = width;
|
||||
sprite->height = height;
|
||||
sprite->bitmap = malloc_(sizeof(uint32_t) * width * height);
|
||||
|
||||
for (y = 0; y < height; ++y) {
|
||||
for (x = 0; x < width; ++x) {
|
||||
if (i > image_size) return;
|
||||
/* Extract the color */
|
||||
uint32_t color;
|
||||
if (bpp == 24) {
|
||||
color = bufferb[i + 3 * x] +
|
||||
bufferb[i+1 + 3 * x] * 0x100 +
|
||||
bufferb[i+2 + 3 * x] * 0x10000;
|
||||
} else if (bpp == 32) {
|
||||
color = bufferb[i + 4 * x] * 0x1000000 +
|
||||
bufferb[i+1 + 4 * x] * 0x100 +
|
||||
bufferb[i+2 + 4 * x] * 0x10000 +
|
||||
bufferb[i+3 + 4 * x] * 0x1;
|
||||
}
|
||||
/* Set our point */
|
||||
sprite->bitmap[(height - y - 1) * width + x] = color;
|
||||
}
|
||||
i += row_width;
|
||||
}
|
||||
free(bufferb);
|
||||
}
|
||||
|
||||
#define _RED(color) ((color & 0x00FF0000) / 0x10000)
|
||||
#define _GRE(color) ((color & 0x0000FF00) / 0x100)
|
||||
#define _BLU(color) ((color & 0x000000FF) / 0x1)
|
||||
|
||||
uint32_t alpha_blend(uint32_t bottom, uint32_t top, uint32_t mask) {
|
||||
float a = _RED(mask) / 256.0;
|
||||
uint8_t red = _RED(bottom) * (1.0 - a) + _RED(top) * a;
|
||||
uint8_t gre = _GRE(bottom) * (1.0 - a) + _GRE(top) * a;
|
||||
uint8_t blu = _BLU(bottom) * (1.0 - a) + _BLU(top) * a;
|
||||
return rgb(red,gre,blu);
|
||||
}
|
||||
|
||||
void draw_sprite(sprite_t * sprite, uint16_t x, uint16_t y) {
|
||||
for (uint16_t _y = 0; _y < sprite->height; ++_y) {
|
||||
for (uint16_t _x = 0; _x < sprite->width; ++_x) {
|
||||
if (sprite->alpha) {
|
||||
GFX(x + _x, y + _y) = alpha_blend(GFX(x + _x, y + _y), SPRITE(sprite, _x, _y), SMASKS(sprite, _x, _y));
|
||||
} else {
|
||||
if (SPRITE(sprite,_x,_y) != sprite->blank) {
|
||||
GFX(x + _x, y + _y) = SPRITE(sprite, _x, _y);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void waitabit() {
|
||||
int x = time(NULL);
|
||||
while (time(NULL) < x + 1) {
|
||||
// Do nothing.
|
||||
}
|
||||
}
|
||||
|
||||
void draw_line(uint16_t x0, uint16_t x1, uint16_t y0, uint16_t y1, uint32_t color) {
|
||||
int deltax = abs(x1 - x0);
|
||||
int deltay = abs(y1 - y0);
|
||||
int sx = (x0 < x1) ? 1 : -1;
|
||||
int sy = (y0 < y1) ? 1 : -1;
|
||||
int error = deltax - deltay;
|
||||
while (1) {
|
||||
GFX(x0, y0) = color;
|
||||
if (x0 == x1 && y0 == y1) break;
|
||||
int e2 = 2 * error;
|
||||
if (e2 > -deltay) {
|
||||
error -= deltay;
|
||||
x0 += sx;
|
||||
}
|
||||
if (e2 < deltax) {
|
||||
error += deltax;
|
||||
y0 += sy;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 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();
|
||||
}
|
||||
|
||||
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 += 1) {
|
||||
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) {
|
||||
if (argc < 5) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
graphics_width = atoi(argv[1]);
|
||||
graphics_height = atoi(argv[2]);
|
||||
graphics_depth = atoi(argv[3]);
|
||||
if (!graphics_width || !graphics_height || !graphics_depth) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
int buf_size = (graphics_width * graphics_depth * graphics_depth);
|
||||
gfx_mem = (void *)syscall_shm_obtain(argv[4], buf_size);
|
||||
if (!gfx_mem) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
map_x = GFX_W / 2 - (64 * 9) / 2;
|
||||
map_y = GFX_H / 2 - (64 * 9) / 2;
|
||||
flip_offset = GFX_H;
|
||||
gfx_size = GFX_H * GFX_W * GFX_B;
|
||||
|
||||
printf("game: w=%d, h=%d, d=%d, buf=0x%x\n", GFX_W, GFX_H, graphics_depth, gfx_mem);
|
||||
|
||||
frame_mem = malloc_(gfx_size);
|
||||
|
||||
printf("Graphics memory is at %p, backbuffer is at %p.\n", gfx_mem, frame_mem);
|
||||
|
||||
if (!frame_mem) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
printf("\033[J\n");
|
||||
|
||||
syscall_kbd_mode(1);
|
||||
|
||||
int playing = 1;
|
||||
while (playing) {
|
||||
|
||||
display();
|
||||
|
||||
char ch = 0;
|
||||
ch = syscall_kbd_get();
|
||||
switch (ch) {
|
||||
case 16:
|
||||
playing = 0;
|
||||
break;
|
||||
case 30:
|
||||
move(-1,0);
|
||||
/* left */
|
||||
break;
|
||||
case 32:
|
||||
move(1,0);
|
||||
/* right */
|
||||
break;
|
||||
case 31:
|
||||
move(0,1);
|
||||
/* Down */
|
||||
break;
|
||||
case 17:
|
||||
move(0,-1);
|
||||
/* Up */
|
||||
break;
|
||||
case 18:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
syscall_kbd_mode(0);
|
||||
|
||||
return 0;
|
||||
}
|
202
userspace/julia2.c
Normal file
202
userspace/julia2.c
Normal file
@ -0,0 +1,202 @@
|
||||
/*
|
||||
* Julia Fractal Generator
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <syscall.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/*
|
||||
* Some of the system calls for the graphics
|
||||
* functionality.
|
||||
*/
|
||||
DEFN_SYSCALL1(kbd_mode, 12, int);
|
||||
DEFN_SYSCALL0(kbd_get, 13);
|
||||
DEFN_SYSCALL2(shm_obtain, 35, char *, int)
|
||||
DEFN_SYSCALL1(shm_release, 36, char *)
|
||||
|
||||
uint16_t graphics_width = 0;
|
||||
uint16_t graphics_height = 0;
|
||||
uint16_t graphics_depth = 0;
|
||||
|
||||
#define GFX_W graphics_width /* Display width */
|
||||
#define GFX_H graphics_height /* Display height */
|
||||
#define GFX_B (graphics_depth / 8) /* Display byte depth */
|
||||
|
||||
/*
|
||||
* Macros make verything easier.
|
||||
*/
|
||||
#define GFX(x,y) *((uint32_t *)&gfx_mem[(GFX_W * (y) + (x)) * GFX_B])
|
||||
#define SPRITE(sprite,x,y) sprite->bitmap[sprite->width * (y) + (x)]
|
||||
|
||||
/* Pointer to graphics memory */
|
||||
uint8_t * gfx_mem;
|
||||
|
||||
/* Julia fractals elements */
|
||||
float conx = -0.74; /* real part of c */
|
||||
float cony = 0.1; /* imag part of c */
|
||||
float Maxx = 2; /* X bounds */
|
||||
float Minx = -2;
|
||||
float Maxy = 1; /* Y bounds */
|
||||
float Miny = -1;
|
||||
float initer = 1000; /* Iteration levels */
|
||||
float pixcorx; /* Internal values */
|
||||
float pixcory;
|
||||
|
||||
int newcolor; /* Color we're placing */
|
||||
int lastcolor; /* Last color we placed */
|
||||
int no_repeat = 0; /* Repeat colors? */
|
||||
|
||||
/*
|
||||
* Color table
|
||||
* These are orange/red shades from the Ubuntu platte.
|
||||
*/
|
||||
int colors[] = {
|
||||
0xeec73e,
|
||||
0xf0a513,
|
||||
0xfb8b00,
|
||||
0xf44800,
|
||||
0xffff99,
|
||||
0xffff00,
|
||||
0xfdca01,
|
||||
0x986601,
|
||||
0xf44800,
|
||||
0xfd3301,
|
||||
0xd40000,
|
||||
0x980101,
|
||||
};
|
||||
|
||||
void julia(int xpt, int ypt) {
|
||||
long double x = xpt * pixcorx + Minx;
|
||||
long double y = Maxy - ypt * pixcory;
|
||||
long double xnew = 0;
|
||||
long double ynew = 0;
|
||||
|
||||
int k = 0;
|
||||
for (k = 0; k <= initer; k++) {
|
||||
xnew = x * x - y * y + conx;
|
||||
ynew = 2 * x * y + cony;
|
||||
x = xnew;
|
||||
y = ynew;
|
||||
if ((x * x + y * y) > 4)
|
||||
break;
|
||||
}
|
||||
|
||||
int color;
|
||||
if (no_repeat) {
|
||||
color = 12 * k / initer;
|
||||
} else {
|
||||
color = k;
|
||||
if (color > 11) {
|
||||
color = color % 12;
|
||||
}
|
||||
}
|
||||
if (k >= initer) {
|
||||
GFX(xpt, ypt) = 0;
|
||||
} else {
|
||||
GFX(xpt, ypt) = colors[color];
|
||||
}
|
||||
newcolor = color;
|
||||
}
|
||||
|
||||
int main(int argc, char ** argv) {
|
||||
if (argc < 5) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
graphics_width = atoi(argv[1]);
|
||||
graphics_height = atoi(argv[2]);
|
||||
graphics_depth = atoi(argv[3]);
|
||||
|
||||
if (!graphics_width || !graphics_height || !graphics_depth) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
int buf_size = (GFX_W * GFX_H * GFX_B);
|
||||
gfx_mem = (void *)syscall_shm_obtain(argv[4], buf_size);
|
||||
if (!gfx_mem) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("julia2: w=%d, h=%d, d=%d, buf=0x%x\n", GFX_W, GFX_H, GFX_B, gfx_mem);
|
||||
#if 0
|
||||
if (argc > 1) {
|
||||
/* Read some arguments */
|
||||
int index, c;
|
||||
while ((c = getopt(argc, argv, "ni:x:X:c:C:")) != -1) {
|
||||
switch (c) {
|
||||
case 'n':
|
||||
no_repeat = 1;
|
||||
break;
|
||||
case 'i':
|
||||
initer = atof(optarg);
|
||||
break;
|
||||
case 'x':
|
||||
Minx = atof(optarg);
|
||||
break;
|
||||
case 'X':
|
||||
Maxx = atof(optarg);
|
||||
break;
|
||||
case 'c':
|
||||
conx = atof(optarg);
|
||||
break;
|
||||
case 'C':
|
||||
cony = atof(optarg);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if 0
|
||||
printf("initer: %f\n", initer);
|
||||
printf("X: %f %f\n", Minx, Maxx);
|
||||
#endif
|
||||
float _x = Maxx - Minx;
|
||||
float _y = _x / GFX_W * GFX_H;
|
||||
Miny = 0 - _y / 2;
|
||||
Maxy = _y / 2;
|
||||
#if 0
|
||||
printf("Y: %f %f\n", Miny, Maxy);
|
||||
printf("conx: %f cony: %f\n", conx, cony);
|
||||
#endif
|
||||
|
||||
pixcorx = (Maxx - Minx) / GFX_W;
|
||||
pixcory = (Maxy - Miny) / GFX_H;
|
||||
int j = 0;
|
||||
do {
|
||||
int i = 1;
|
||||
do {
|
||||
julia(i,j);
|
||||
if (lastcolor != newcolor) julia(i-1,j);
|
||||
else if (i > 0) GFX(i-1,j) = colors[lastcolor];
|
||||
newcolor = lastcolor;
|
||||
i+= 2;
|
||||
} while ( i < GFX_W );
|
||||
++j;
|
||||
} while ( j < GFX_H );
|
||||
|
||||
syscall_kbd_mode(1);
|
||||
|
||||
int playing = 1;
|
||||
while (playing) {
|
||||
char ch = 0;
|
||||
ch = syscall_kbd_get();
|
||||
switch (ch) {
|
||||
case 16:
|
||||
playing = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
syscall_kbd_mode(0);
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user