Finally snake.c draws something. Deadlin is in 2 hours and we are still making babysteps, great
This commit is contained in:
parent
554f16cc7d
commit
308bc589c0
5
Makefile
5
Makefile
@ -108,7 +108,7 @@ debug-nox: image.bin
|
|||||||
-ex "break _start" \
|
-ex "break _start" \
|
||||||
-ex "continue"
|
-ex "continue"
|
||||||
|
|
||||||
USERPROGS=./user/false ./user/greet ./user/div0 ./user/shout ./user/badputs ./user/bss ./user/snake ./user/player
|
USERPROGS=./user/false ./user/greet ./user/div0 ./user/shout ./user/badputs ./user/bss ./user/player ./snake/snake
|
||||||
|
|
||||||
fs.img: ./kernel.bin ./tools/mkfs $(USERPROGS)
|
fs.img: ./kernel.bin ./tools/mkfs $(USERPROGS)
|
||||||
./tools/mkfs $@ $< $(USERPROGS)
|
./tools/mkfs $@ $< $(USERPROGS)
|
||||||
@ -118,6 +118,9 @@ LDFLAGS=-m elf_i386
|
|||||||
user/%: user/%.o user/crt.o
|
user/%: user/%.o user/crt.o
|
||||||
$(LD) $(LDFLAGS) -o $@ -Ttext 0x401000 $^
|
$(LD) $(LDFLAGS) -o $@ -Ttext 0x401000 $^
|
||||||
|
|
||||||
|
snake/snake: snake/snake.o user/crt.o
|
||||||
|
$(LD) $(LDFLAGS) -o $@ -Ttext 0x401000 $^
|
||||||
|
|
||||||
kernel.bin: $(OBJECTS)
|
kernel.bin: $(OBJECTS)
|
||||||
$(LD) $(LDFLAGS) $(LDKERNELFLAGS) -o $@ -Ttext 0x80009000 $^
|
$(LD) $(LDFLAGS) $(LDKERNELFLAGS) -o $@ -Ttext 0x80009000 $^
|
||||||
|
|
||||||
|
|||||||
184
snake/map_data.h
Normal file
184
snake/map_data.h
Normal file
@ -0,0 +1,184 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "maps.h"
|
||||||
|
|
||||||
|
static const MapList map_list = {
|
||||||
|
.maps = {
|
||||||
|
/* CLUSTERTRACT.png */
|
||||||
|
[0] = {
|
||||||
|
.name = "CLUSTERTRACT",
|
||||||
|
.map = {
|
||||||
|
[0] = { tile_wall_t, tile_wall_lr, tile_wall_lr, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lr, tile_wall_lr, tile_wall_b },
|
||||||
|
[1] = { tile_wall_rb, tile_wall_lt, tile_wall_lr, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lr, tile_wall_lb, tile_wall_rt },
|
||||||
|
[2] = { tile_wall_lr, tile_wall_rb, tile_wall_lt, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lb, tile_wall_rt, tile_wall_lr },
|
||||||
|
[3] = { tile_wall_lr, tile_wall_lr, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lr, tile_wall_lr },
|
||||||
|
[4] = { tile_wall_lr, tile_wall_lr, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lr, tile_wall_lr },
|
||||||
|
[5] = { tile_wall_lr, tile_wall_lr, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_b, tile_wall_lrt, tile_wall_lr },
|
||||||
|
[6] = { tile_wall_lr, tile_wall_lr, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lr, tile_wall_lr },
|
||||||
|
[7] = { tile_wall_lr, tile_wall_lrb, tile_wall_rt, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lr, tile_wall_lr },
|
||||||
|
[8] = { tile_wall_lr, tile_wall_lrb, tile_wall_lt, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_rb, tile_wall_lrt, tile_wall_lr },
|
||||||
|
[9] = { tile_wall_lr, tile_wall_lr, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lb, tile_wall_lrt, tile_wall_lr },
|
||||||
|
[10] = { tile_wall_lr, tile_wall_lr, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lr, tile_wall_lr },
|
||||||
|
[11] = { tile_wall_lr, tile_wall_lrb, tile_wall_t, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lr, tile_wall_lr },
|
||||||
|
[12] = { tile_wall_lr, tile_wall_lr, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lr, tile_wall_lr },
|
||||||
|
[13] = { tile_wall_lr, tile_wall_lr, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lr, tile_wall_lr },
|
||||||
|
[14] = { tile_wall_lr, tile_wall_lb, tile_wall_rt, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_rb, tile_wall_lt, tile_wall_lr },
|
||||||
|
[15] = { tile_wall_lb, tile_wall_rt, tile_wall_lr, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lr, tile_wall_rb, tile_wall_lt },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
/* EMPTY.png */
|
||||||
|
[1] = {
|
||||||
|
.name = "EMPTY",
|
||||||
|
.map = {
|
||||||
|
[0] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty },
|
||||||
|
[1] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty },
|
||||||
|
[2] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty },
|
||||||
|
[3] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty },
|
||||||
|
[4] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty },
|
||||||
|
[5] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty },
|
||||||
|
[6] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty },
|
||||||
|
[7] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty },
|
||||||
|
[8] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty },
|
||||||
|
[9] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty },
|
||||||
|
[10] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty },
|
||||||
|
[11] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty },
|
||||||
|
[12] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty },
|
||||||
|
[13] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty },
|
||||||
|
[14] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty },
|
||||||
|
[15] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
/* GREEN DAYS.png */
|
||||||
|
[2] = {
|
||||||
|
.name = "GREEN DAYS",
|
||||||
|
.map = {
|
||||||
|
[0] = { tile_wall_rb, tile_wall_tb, tile_wall_tb, tile_wall_t, tile_empty, tile_empty, tile_wall_b, tile_wall_tb, tile_wall_tb, tile_wall_rt },
|
||||||
|
[1] = { tile_wall_lr, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lr },
|
||||||
|
[2] = { tile_wall_lr, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lr },
|
||||||
|
[3] = { tile_wall_l, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_l },
|
||||||
|
[4] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty },
|
||||||
|
[5] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty },
|
||||||
|
[6] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty },
|
||||||
|
[7] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty },
|
||||||
|
[8] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty },
|
||||||
|
[9] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty },
|
||||||
|
[10] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty },
|
||||||
|
[11] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty },
|
||||||
|
[12] = { tile_wall_r, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_r },
|
||||||
|
[13] = { tile_wall_lr, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lr },
|
||||||
|
[14] = { tile_wall_lr, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lr },
|
||||||
|
[15] = { tile_wall_lb, tile_wall_tb, tile_wall_tb, tile_wall_t, tile_empty, tile_empty, tile_wall_b, tile_wall_tb, tile_wall_tb, tile_wall_lt },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
/* QUARTERHOUSE.png */
|
||||||
|
[3] = {
|
||||||
|
.name = "QUARTERHOUSE",
|
||||||
|
.map = {
|
||||||
|
[0] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty },
|
||||||
|
[1] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty },
|
||||||
|
[2] = { tile_empty, tile_empty, tile_empty, tile_wall_b, tile_wall_rtb, tile_wall_tb, tile_wall_t, tile_empty, tile_empty, tile_empty },
|
||||||
|
[3] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lr, tile_wall, tile_empty, tile_empty, tile_empty, tile_empty },
|
||||||
|
[4] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lr, tile_wall, tile_empty, tile_empty, tile_empty, tile_empty },
|
||||||
|
[5] = { tile_wall_rt, tile_empty, tile_empty, tile_empty, tile_wall_lb, tile_wall_rt, tile_empty, tile_empty, tile_empty, tile_wall_rb },
|
||||||
|
[6] = { tile_wall_lrt, tile_empty, tile_empty, tile_empty, tile_wall, tile_wall_lr, tile_empty, tile_empty, tile_empty, tile_wall_lrb },
|
||||||
|
[7] = { tile_wall_lrt, tile_wall, tile_wall_rb, tile_wall_tb, tile_wall_rtb, tile_wall_lrtb, tile_wall_tb, tile_wall_rt, tile_wall, tile_wall_lrb },
|
||||||
|
[8] = { tile_wall_lrtb, tile_wall_tb, tile_wall_lt, tile_wall, tile_wall_lrb, tile_wall_lt, tile_wall, tile_wall_lb, tile_wall_tb, tile_wall_lrtb },
|
||||||
|
[9] = { tile_wall_lrt, tile_empty, tile_empty, tile_empty, tile_wall_lr, tile_wall, tile_empty, tile_empty, tile_empty, tile_wall_lrb },
|
||||||
|
[10] = { tile_wall_lt, tile_empty, tile_empty, tile_empty, tile_wall_lb, tile_wall_rt, tile_empty, tile_empty, tile_empty, tile_wall_lb },
|
||||||
|
[11] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_wall, tile_wall_lr, tile_empty, tile_empty, tile_empty, tile_empty },
|
||||||
|
[12] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_wall, tile_wall_lr, tile_empty, tile_empty, tile_empty, tile_empty },
|
||||||
|
[13] = { tile_empty, tile_empty, tile_empty, tile_wall_b, tile_wall_tb, tile_wall_ltb, tile_wall_t, tile_empty, tile_empty, tile_empty },
|
||||||
|
[14] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty },
|
||||||
|
[15] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
/* SERPENTINE STRUTS.png */
|
||||||
|
[4] = {
|
||||||
|
.name = "SERPENTINE STRUTS",
|
||||||
|
.map = {
|
||||||
|
[0] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty },
|
||||||
|
[1] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_r, tile_empty, tile_empty, tile_wall_r, tile_empty, tile_empty },
|
||||||
|
[2] = { tile_empty, tile_empty, tile_empty, tile_wall_b, tile_wall_lrtb, tile_wall_tb, tile_wall_tb, tile_wall_lrtb, tile_wall_t, tile_empty },
|
||||||
|
[3] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_l, tile_empty, tile_empty, tile_wall_l, tile_empty, tile_empty },
|
||||||
|
[4] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty },
|
||||||
|
[5] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty },
|
||||||
|
[6] = { tile_empty, tile_empty, tile_empty, tile_wall_r, tile_empty, tile_empty, tile_wall_r, tile_empty, tile_empty, tile_empty },
|
||||||
|
[7] = { tile_empty, tile_empty, tile_wall_b, tile_wall_lrtb, tile_wall_tb, tile_wall_tb, tile_wall_lrtb, tile_wall_t, tile_empty, tile_empty },
|
||||||
|
[8] = { tile_empty, tile_empty, tile_empty, tile_wall_l, tile_empty, tile_empty, tile_wall_l, tile_empty, tile_empty, tile_empty },
|
||||||
|
[9] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty },
|
||||||
|
[10] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty },
|
||||||
|
[11] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty },
|
||||||
|
[12] = { tile_empty, tile_empty, tile_wall_r, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_r, tile_empty, tile_empty },
|
||||||
|
[13] = { tile_empty, tile_wall_b, tile_wall_lrtb, tile_wall_tb, tile_wall_tb, tile_wall_tb, tile_wall_tb, tile_wall_lrtb, tile_wall_t, tile_empty },
|
||||||
|
[14] = { tile_empty, tile_empty, tile_wall_l, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_l, tile_empty, tile_empty },
|
||||||
|
[15] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
/* SHEER GIRTH.png */
|
||||||
|
[5] = {
|
||||||
|
.name = "SHEER GIRTH",
|
||||||
|
.map = {
|
||||||
|
[0] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty },
|
||||||
|
[1] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty },
|
||||||
|
[2] = { tile_empty, tile_wall_rb, tile_wall_rtb, tile_wall_rtb, tile_wall_rtb, tile_wall_rtb, tile_wall_rtb, tile_wall_rtb, tile_wall_rt, tile_empty },
|
||||||
|
[3] = { tile_empty, tile_wall_lrb, tile_wall_lrtb, tile_wall_lrtb, tile_wall_lrtb, tile_wall_lrtb, tile_wall_lrtb, tile_wall_lrtb, tile_wall_lrt, tile_empty },
|
||||||
|
[4] = { tile_empty, tile_wall_lb, tile_wall_ltb, tile_wall_ltb, tile_wall_ltb, tile_wall_ltb, tile_wall_ltb, tile_wall_ltb, tile_wall_lt, tile_empty },
|
||||||
|
[5] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty },
|
||||||
|
[6] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty },
|
||||||
|
[7] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty },
|
||||||
|
[8] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty },
|
||||||
|
[9] = { tile_empty, tile_wall_rb, tile_wall_rtb, tile_wall_rt, tile_empty, tile_empty, tile_wall_rb, tile_wall_rtb, tile_wall_rt, tile_empty },
|
||||||
|
[10] = { tile_empty, tile_wall_lrb, tile_wall_lrtb, tile_wall_lrt, tile_empty, tile_empty, tile_wall_lrb, tile_wall_lrtb, tile_wall_lrt, tile_empty },
|
||||||
|
[11] = { tile_empty, tile_wall_lrb, tile_wall_lrtb, tile_wall_lrt, tile_empty, tile_empty, tile_wall_lrb, tile_wall_lrtb, tile_wall_lrt, tile_empty },
|
||||||
|
[12] = { tile_empty, tile_wall_lrb, tile_wall_lrtb, tile_wall_lrt, tile_empty, tile_empty, tile_wall_lrb, tile_wall_lrtb, tile_wall_lrt, tile_empty },
|
||||||
|
[13] = { tile_empty, tile_wall_lb, tile_wall_ltb, tile_wall_lt, tile_empty, tile_empty, tile_wall_lb, tile_wall_ltb, tile_wall_lt, tile_empty },
|
||||||
|
[14] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty },
|
||||||
|
[15] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
/* VAULT.png */
|
||||||
|
[6] = {
|
||||||
|
.name = "VAULT",
|
||||||
|
.map = {
|
||||||
|
[0] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty },
|
||||||
|
[1] = { tile_empty, tile_empty, tile_empty, tile_wall_rb, tile_wall_tb, tile_wall_tb, tile_wall_tb, tile_wall_tb, tile_wall_rt, tile_empty },
|
||||||
|
[2] = { tile_empty, tile_empty, tile_empty, tile_wall_lr, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lr, tile_empty },
|
||||||
|
[3] = { tile_empty, tile_empty, tile_empty, tile_wall_lr, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lr, tile_empty },
|
||||||
|
[4] = { tile_empty, tile_empty, tile_empty, tile_wall_lr, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lr, tile_empty },
|
||||||
|
[5] = { tile_empty, tile_empty, tile_empty, tile_wall_lr, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lr, tile_empty },
|
||||||
|
[6] = { tile_empty, tile_empty, tile_empty, tile_wall_lb, tile_wall_t, tile_empty, tile_empty, tile_wall_b, tile_wall_lrt, tile_empty },
|
||||||
|
[7] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lr, tile_empty },
|
||||||
|
[8] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lr, tile_empty },
|
||||||
|
[9] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lr, tile_empty },
|
||||||
|
[10] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lr, tile_empty },
|
||||||
|
[11] = { tile_empty, tile_empty, tile_wall_rb, tile_wall_t, tile_empty, tile_empty, tile_wall_b, tile_wall_tb, tile_wall_lrt, tile_empty },
|
||||||
|
[12] = { tile_empty, tile_empty, tile_wall_lr, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lr, tile_empty },
|
||||||
|
[13] = { tile_empty, tile_empty, tile_wall_lr, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_wall_lr, tile_empty },
|
||||||
|
[14] = { tile_empty, tile_empty, tile_wall_lb, tile_wall_tb, tile_wall_tb, tile_wall_tb, tile_wall_tb, tile_wall_tb, tile_wall_lt, tile_empty },
|
||||||
|
[15] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
/* WALLS.png */
|
||||||
|
[7] = {
|
||||||
|
.name = "WALLS",
|
||||||
|
.map = {
|
||||||
|
[0] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty },
|
||||||
|
[1] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty },
|
||||||
|
[2] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty },
|
||||||
|
[3] = { tile_wall_tb, tile_wall_t, tile_empty, tile_empty, tile_wall_b, tile_wall_tb, tile_wall_tb, tile_wall_tb, tile_wall_tb, tile_wall_tb },
|
||||||
|
[4] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty },
|
||||||
|
[5] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty },
|
||||||
|
[6] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty },
|
||||||
|
[7] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty },
|
||||||
|
[8] = { tile_wall_tb, tile_wall_tb, tile_wall_tb, tile_wall_tb, tile_wall_t, tile_empty, tile_empty, tile_wall_b, tile_wall_tb, tile_wall_tb },
|
||||||
|
[9] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty },
|
||||||
|
[10] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty },
|
||||||
|
[11] = { tile_wall_t, tile_empty, tile_empty, tile_wall_b, tile_wall_tb, tile_wall_tb, tile_wall_tb, tile_wall_tb, tile_wall_tb, tile_wall_tb },
|
||||||
|
[12] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty },
|
||||||
|
[13] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty },
|
||||||
|
[14] = { tile_wall_tb, tile_wall_tb, tile_wall_tb, tile_wall_tb, tile_wall_tb, tile_wall_tb, tile_wall_t, tile_empty, tile_empty, tile_wall_b },
|
||||||
|
[15] = { tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty, tile_empty },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
72
snake/maps.h
Normal file
72
snake/maps.h
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "misc_utils.h"
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
tile_empty = 0,
|
||||||
|
tile_apple = 1,
|
||||||
|
tile_wall = 2,
|
||||||
|
tile_wall_lr = 3,
|
||||||
|
tile_wall_l = 4,
|
||||||
|
tile_wall_r = 5,
|
||||||
|
tile_wall_lrt = 6,
|
||||||
|
tile_wall_lt = 7,
|
||||||
|
tile_wall_rt = 8,
|
||||||
|
tile_wall_lrb = 9,
|
||||||
|
tile_wall_lb = 10,
|
||||||
|
tile_wall_rb = 11,
|
||||||
|
tile_wall_lrtb = 12,
|
||||||
|
tile_wall_ltb = 13,
|
||||||
|
tile_wall_rtb = 14,
|
||||||
|
tile_wall_t = 15,
|
||||||
|
tile_wall_b = 16,
|
||||||
|
tile_wall_tb = 17,
|
||||||
|
|
||||||
|
tile_snake_l = 18,
|
||||||
|
tile_snake_r = 19,
|
||||||
|
tile_snake_t = 20,
|
||||||
|
tile_snake_b = 21,
|
||||||
|
tile_snake_bl = 22,
|
||||||
|
tile_snake_br = 23,
|
||||||
|
tile_snake_lb = 24,
|
||||||
|
tile_snake_rb = 25,
|
||||||
|
tile_snake_tl = 26,
|
||||||
|
tile_snake_tr = 27,
|
||||||
|
tile_snake_lt = 28,
|
||||||
|
tile_snake_rt = 29,
|
||||||
|
|
||||||
|
tile_pupa_m2_l = 30,
|
||||||
|
tile_pupa_m2_r = 31,
|
||||||
|
tile_pupa_m1_l = 32,
|
||||||
|
tile_pupa_m1_r = 33,
|
||||||
|
tile_pupa_0_l = 34,
|
||||||
|
tile_pupa_0_r = 35,
|
||||||
|
tile_pupa_p1_l = 36,
|
||||||
|
tile_pupa_p1_r = 37,
|
||||||
|
tile_pupa_p2_l = 38,
|
||||||
|
tile_pupa_p2_r = 39,
|
||||||
|
tile_pupa_m2_t = 40,
|
||||||
|
tile_pupa_m1_t = 41,
|
||||||
|
tile_pupa_0_t = 42,
|
||||||
|
tile_pupa_p1_t = 43,
|
||||||
|
tile_pupa_p2_t = 44,
|
||||||
|
tile_pupa_m2_b = 45,
|
||||||
|
tile_pupa_m1_b = 46,
|
||||||
|
tile_pupa_0_b = 47,
|
||||||
|
tile_pupa_p1_b = 48,
|
||||||
|
tile_pupa_p2_b = 49,
|
||||||
|
} tile_t;
|
||||||
|
|
||||||
|
#define WORLD_WIDTH 16
|
||||||
|
#define WORLD_HEIGHT 10
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const char* name;
|
||||||
|
tile_t map[WORLD_WIDTH][WORLD_HEIGHT];
|
||||||
|
} MapConfig;
|
||||||
|
|
||||||
|
#define PLAYABLE_MAPS_COUNT 8
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
MapConfig maps[PLAYABLE_MAPS_COUNT];
|
||||||
|
} MapList;
|
||||||
86
snake/misc_utils.h
Normal file
86
snake/misc_utils.h
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../syscall.h"
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
void _Noreturn panic(const char* message) {
|
||||||
|
syscall(SYS_switch_to_text, 0); // ???
|
||||||
|
syscall(SYS_puts, (uintptr_t)message);
|
||||||
|
syscall(SYS_exit, 1);
|
||||||
|
__builtin_unreachable();
|
||||||
|
}
|
||||||
|
|
||||||
|
#define check(expr) if (!(expr)){ panic( "Assertion failed at " __FILE__ ": " #expr); }
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int x, y;
|
||||||
|
} ivec2;
|
||||||
|
|
||||||
|
void* memcpy(void* dst, const void* src, uint32_t size) {
|
||||||
|
uint8_t* d = (uint8_t*)dst;
|
||||||
|
const uint8_t* s = (const uint8_t*)src;
|
||||||
|
for (uint32_t i = 0; i < size; i++) {
|
||||||
|
d[i] = s[i];
|
||||||
|
}
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* memset(void* dst, int value, uint32_t size) {
|
||||||
|
uint8_t* d = (uint8_t*)dst;
|
||||||
|
uint8_t byte = (uint8_t)value;
|
||||||
|
for (uint32_t i = 0; i < size; i++) {
|
||||||
|
d[i] = byte;
|
||||||
|
}
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define STRING_BUILDER_CAPACITY 150
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char buf[STRING_BUILDER_CAPACITY];
|
||||||
|
int len;
|
||||||
|
} StringBuilder;
|
||||||
|
|
||||||
|
void StringBuilder_putc(StringBuilder* self, char ch) {
|
||||||
|
if (self->len + 1 > STRING_BUILDER_CAPACITY) {
|
||||||
|
panic("string builder\n");
|
||||||
|
}
|
||||||
|
self->buf[self->len++] = ch;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StringBuilder_append_cstr(StringBuilder* self, const char* str) {
|
||||||
|
for (const char* p = str; *p; p++) {
|
||||||
|
StringBuilder_putc(self, *p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void StringBuilder_append_u32(StringBuilder* self, uint32_t x) {
|
||||||
|
char b[11];
|
||||||
|
int len = 0;
|
||||||
|
|
||||||
|
if (x == 0) {
|
||||||
|
b[len++] = '0';
|
||||||
|
} else {
|
||||||
|
while (x > 0) {
|
||||||
|
b[len++] = (char)('0' + (x % 10));
|
||||||
|
x /= 10;
|
||||||
|
}
|
||||||
|
int i = 0, j = len - 1;
|
||||||
|
while (i < j) {
|
||||||
|
char tmp = b[i];
|
||||||
|
b[i] = b[j];
|
||||||
|
b[j] = tmp;
|
||||||
|
i++;
|
||||||
|
j--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
b[len] = 0;
|
||||||
|
StringBuilder_append_cstr(self, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* StringBuilder_get_cstr(StringBuilder* self) {
|
||||||
|
StringBuilder_putc(self, 0);
|
||||||
|
return self->buf;
|
||||||
|
}
|
||||||
26
snake/pause_effect.h
Normal file
26
snake/pause_effect.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
static const uint8_t VGA_GRAY_LUT[256] = {
|
||||||
|
16, 17, 23, 24, 20, 21, 23, 27, 22, 23, 28, 29, 25, 27, 30, 31,
|
||||||
|
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
||||||
|
18, 19, 21, 22, 23, 23, 23, 22, 22, 24, 26, 28, 30, 29, 28, 27,
|
||||||
|
26, 27, 27, 27, 28, 26, 23, 21, 26, 26, 27, 27, 28, 28, 27, 27,
|
||||||
|
27, 28, 29, 30, 30, 30, 30, 29, 29, 29, 29, 29, 30, 29, 28, 27,
|
||||||
|
28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 30, 30, 31, 30, 30, 30,
|
||||||
|
30, 30, 30, 30, 30, 30, 29, 29, 17, 17, 18, 18, 19, 19, 19, 18,
|
||||||
|
18, 19, 21, 22, 23, 23, 22, 21, 21, 21, 21, 22, 22, 21, 19, 18,
|
||||||
|
20, 21, 21, 21, 22, 22, 22, 21, 21, 22, 23, 23, 24, 23, 23, 23,
|
||||||
|
22, 23, 23, 23, 23, 22, 22, 21, 22, 22, 22, 23, 23, 23, 23, 23,
|
||||||
|
23, 23, 23, 23, 24, 24, 23, 23, 23, 23, 23, 23, 23, 23, 23, 22,
|
||||||
|
16, 17, 17, 17, 18, 17, 17, 17, 17, 18, 18, 19, 20, 20, 19, 19,
|
||||||
|
18, 19, 19, 19, 19, 18, 17, 17, 18, 18, 19, 19, 19, 19, 19, 19,
|
||||||
|
19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 19, 19, 19,
|
||||||
|
19, 19, 19, 20, 20, 20, 20, 20, 19, 20, 20, 20, 21, 20, 20, 20,
|
||||||
|
20, 20, 20, 20, 20, 20, 20, 19, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline uint8_t vga_to_gray(uint8_t color){
|
||||||
|
return VGA_GRAY_LUT[color];
|
||||||
|
}
|
||||||
4
snake/random.h
Normal file
4
snake/random.h
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
BIN
snake/snake
Executable file
BIN
snake/snake
Executable file
Binary file not shown.
262
snake/snake.c
Normal file
262
snake/snake.c
Normal file
@ -0,0 +1,262 @@
|
|||||||
|
#include "../drivers/vga.h"
|
||||||
|
#include "../syscall.h"
|
||||||
|
|
||||||
|
#include "sprites.h"
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "misc_utils.h"
|
||||||
|
#include "pause_effect.h"
|
||||||
|
|
||||||
|
#include "sprites.h"
|
||||||
|
#include "sprite_data.h"
|
||||||
|
#include "maps.h"
|
||||||
|
#include "map_data.h"
|
||||||
|
|
||||||
|
#define FRAME_SIZE (VGA_GRAPHICS_WIDTH * VGA_GRAPHICS_HEIGHT)
|
||||||
|
|
||||||
|
#define HUD_OFFSET 3
|
||||||
|
#define GLYPH_SPACING 3
|
||||||
|
|
||||||
|
#define FONT_SPACE_INDEX 0
|
||||||
|
#define FONT_DIGIT_BASE 1
|
||||||
|
#define FONT_LETTER_BASE (FONT_DIGIT_BASE + 10)
|
||||||
|
|
||||||
|
uint8_t frame[FRAME_SIZE] = { 1 };
|
||||||
|
|
||||||
|
#define SNAKE_GAMEMODE_MAX_APPLES 10
|
||||||
|
#define SNAKE_GAMEMODE_DEFAULT_APPLES 5
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
game_screen_gaming,
|
||||||
|
game_screen_pause,
|
||||||
|
game_screen_select_map,
|
||||||
|
game_screen_select_apple_count,
|
||||||
|
} GameScreen;
|
||||||
|
|
||||||
|
|
||||||
|
#define SNAKE_START_Y 2
|
||||||
|
#define SNAKE_START_HEAD_X 4
|
||||||
|
#define SNAKE_START_PUPA_X 6
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
snake_direction_left = 0,
|
||||||
|
snake_direction_right = 1,
|
||||||
|
snake_direction_top = 2,
|
||||||
|
snake_direction_bottom = 3,
|
||||||
|
} SnakeDirection;
|
||||||
|
|
||||||
|
#define WALKING_ANIM_TIME_SLOW 500
|
||||||
|
#define HATCHING_ANIM_TIME_SLOW 200
|
||||||
|
#define WALKING_ANIM_TIME_FAST 200
|
||||||
|
#define HATCHING_ANIM_TIME_FAST 80
|
||||||
|
|
||||||
|
struct Snake {
|
||||||
|
GameScreen game_screen;
|
||||||
|
bool have_game;
|
||||||
|
/* from 0 to PLAYABLE_MAPS_COUNT - 1 */
|
||||||
|
int selected_map_index;
|
||||||
|
/* from 1 to SNAKE_GAMEMODE_MAX_APPLES, default is SNAKE_GAMEMODE_DEFAULT_APPLES */
|
||||||
|
int gamemode_apples_count;
|
||||||
|
|
||||||
|
tile_t world[WORLD_WIDTH][WORLD_HEIGHT];
|
||||||
|
uint8_t ghost_apples[WORLD_WIDTH][WORLD_HEIGHT];
|
||||||
|
ivec2 snake_head;
|
||||||
|
ivec2 snake_pupa;
|
||||||
|
bool is_time_sped_up;
|
||||||
|
SnakeDirection cur_snake_direction;
|
||||||
|
SnakeDirection new_snake_direction;
|
||||||
|
/* If we are about to make a step into a wall, we start dying,
|
||||||
|
* we enter into dying mode, where we keep making steps, but the head
|
||||||
|
* just disappears after walking, moving back.
|
||||||
|
* When the pupa disappears this way, we enter is_dead state, where
|
||||||
|
* nothing moves.
|
||||||
|
* If we are about to hit ourselves, we don't even move,
|
||||||
|
* we immediately draw one small splash and enter is_dead state.
|
||||||
|
* There is no winning state, you just raise your score until you are dead.
|
||||||
|
*/
|
||||||
|
bool is_dying;
|
||||||
|
bool is_dead;
|
||||||
|
int score;
|
||||||
|
|
||||||
|
} snake = {1};
|
||||||
|
|
||||||
|
void init_snake() {
|
||||||
|
snake.game_screen = game_screen_pause;
|
||||||
|
snake.have_game = false;
|
||||||
|
snake.selected_map_index = 0;
|
||||||
|
snake.gamemode_apples_count = SNAKE_GAMEMODE_DEFAULT_APPLES;
|
||||||
|
/* snake_head and snake_pupa and snake.world
|
||||||
|
* and other gameplay-related variables will be initialized during
|
||||||
|
* map loading */
|
||||||
|
}
|
||||||
|
|
||||||
|
void start_snake_game() {
|
||||||
|
snake.have_game = true;
|
||||||
|
snake.game_screen = game_screen_gaming;
|
||||||
|
const MapConfig* map_config = &map_list.maps[snake.selected_map_index];
|
||||||
|
memcpy(&snake.world[0][0], &map_config->map[0][0], sizeof(tile_t) * WORLD_WIDTH * WORLD_HEIGHT);
|
||||||
|
memset(&snake.ghost_apples, 0, sizeof(snake.ghost_apples));
|
||||||
|
for (int tx = SNAKE_START_HEAD_X; tx < SNAKE_START_PUPA_X; tx++) {
|
||||||
|
snake.world[tx][SNAKE_START_Y] = tile_snake_l;
|
||||||
|
}
|
||||||
|
snake.world[SNAKE_START_PUPA_X][SNAKE_START_Y] = tile_pupa_0_l;
|
||||||
|
snake.new_snake_direction = snake.cur_snake_direction = snake_direction_left;
|
||||||
|
snake.is_dying = false;
|
||||||
|
snake.is_dead = false;
|
||||||
|
snake.score = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t time_ms(void) {
|
||||||
|
return (uint32_t)syscall(SYS_time_ms, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear_frame(uint8_t color) {
|
||||||
|
for (uint32_t i = 0; i < FRAME_SIZE; i++) {
|
||||||
|
frame[i] = color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void put_pixel(int x, int y, uint8_t color) {
|
||||||
|
if (x < 0 || x >= VGA_GRAPHICS_WIDTH || y < 0 || y >= VGA_GRAPHICS_HEIGHT) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
frame[y * VGA_GRAPHICS_WIDTH + x] = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw_sprite(
|
||||||
|
int dst_x, int dst_y, int sprite_width, int sprite_height,
|
||||||
|
const uint8_t* sprite) {
|
||||||
|
for (int x = 0; x < sprite_width; x++) {
|
||||||
|
for (int y = 0; y < sprite_height; y++) {
|
||||||
|
uint8_t color = sprite[x * sprite_height + y];
|
||||||
|
if (color != TRANSPARENCY_COLOR) {
|
||||||
|
put_pixel(dst_x + x, dst_y + y, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool font_index_for_char(char ch, int *out_index) {
|
||||||
|
if (ch == ' ') {
|
||||||
|
*out_index = FONT_SPACE_INDEX;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (ch >= '0' && ch <= '9') {
|
||||||
|
*out_index = FONT_DIGIT_BASE + (ch - '0');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (ch >= 'A' && ch <= 'Z') {
|
||||||
|
*out_index = FONT_LETTER_BASE + (ch - 'A');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw_hud(const char *text) {
|
||||||
|
// int lines_count = 1;
|
||||||
|
int y0 = HUD_OFFSET;
|
||||||
|
for (const char* line_start = text; *line_start;) {
|
||||||
|
int glyph_count = 0;
|
||||||
|
const char* p = line_start;
|
||||||
|
for (; *p != '\n' && *p != 0; p++) {
|
||||||
|
glyph_count++;
|
||||||
|
}
|
||||||
|
if (glyph_count > 0) {
|
||||||
|
const int text_width = glyph_count * FONT_WIDTH + (glyph_count - 1) * GLYPH_SPACING;
|
||||||
|
int x0 = VGA_GRAPHICS_WIDTH - HUD_OFFSET - text_width;
|
||||||
|
for (const char* q = line_start; q != p; q++) {
|
||||||
|
int glyph_index;
|
||||||
|
check(font_index_for_char(*q, &glyph_index));
|
||||||
|
draw_sprite(x0, y0, FONT_WIDTH, FONT_HEIGHT,
|
||||||
|
&sprite_data.font[glyph_index].tex[0][0]);
|
||||||
|
x0 += FONT_WIDTH + GLYPH_SPACING;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (*p == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
line_start = p + 1;
|
||||||
|
y0 += FONT_HEIGHT + GLYPH_SPACING;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw_game_world() {
|
||||||
|
if (!snake.have_game)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (int tx = 0; tx < WORLD_WIDTH; tx++) {
|
||||||
|
for (int ty = 0; ty < WORLD_HEIGHT; ty++) {
|
||||||
|
tile_t tt = snake.world[tx][ty];
|
||||||
|
if (tt == tile_empty)
|
||||||
|
continue;
|
||||||
|
check((uint8_t)tt < TILE_SPRITES);
|
||||||
|
draw_sprite(TILE_WIDTH * tx, TILE_WIDTH * ty - TILE_HEIGHT_OFFSET,
|
||||||
|
TILE_WIDTH, TILE_HEIGHT, &sprite_data.tile[tt].tex[0][0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (snake.game_screen != game_screen_gaming) {
|
||||||
|
for (uint32_t pix = 0; pix < FRAME_SIZE; pix++) {
|
||||||
|
frame[pix] = vga_to_gray(frame[pix]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw_frame() {
|
||||||
|
clear_frame(0);
|
||||||
|
draw_game_world();
|
||||||
|
|
||||||
|
StringBuilder hud = { 0 };
|
||||||
|
if (snake.game_screen == game_screen_gaming) {
|
||||||
|
StringBuilder_append_u32(&hud, snake.score);
|
||||||
|
} else if (snake.game_screen == game_screen_pause) {
|
||||||
|
if (snake.have_game) {
|
||||||
|
StringBuilder_append_cstr(&hud, "PAUSED");
|
||||||
|
}
|
||||||
|
StringBuilder_append_cstr(&hud, "PRESS 1 FOR NEW GAME");
|
||||||
|
if (snake.have_game) {
|
||||||
|
StringBuilder_append_cstr(&hud, "PRESS 2 TO CONTINUE");
|
||||||
|
}
|
||||||
|
StringBuilder_append_cstr(&hud, "PRESS Q TO QUIT");
|
||||||
|
} else if (snake.game_screen == game_screen_select_map) {
|
||||||
|
StringBuilder_append_cstr(&hud, "SELECT LEVEL\nCURRENTLY SELECTED:\n");
|
||||||
|
check(snake.selected_map_index < PLAYABLE_MAPS_COUNT);
|
||||||
|
StringBuilder_append_cstr(&hud, map_list.maps[snake.selected_map_index].name);
|
||||||
|
} else if (snake.game_screen == game_screen_select_apple_count) {
|
||||||
|
StringBuilder_append_cstr(&hud, "SELECT DIFFICULTY\n"
|
||||||
|
"HOW MANY APPLES ON MAP\nCURRENTLY SELECTED:\n");
|
||||||
|
StringBuilder_append_u32(&hud, snake.gamemode_apples_count);
|
||||||
|
}
|
||||||
|
draw_hud(StringBuilder_get_cstr(&hud));
|
||||||
|
}
|
||||||
|
|
||||||
|
void wait_until(uint32_t deadline_ms) {
|
||||||
|
while ((int32_t)(time_ms() - deadline_ms) < 0) {
|
||||||
|
syscall(SYS_halt, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
init_snake();
|
||||||
|
syscall(SYS_switch_to_graphics, 0);
|
||||||
|
|
||||||
|
snake.selected_map_index = 3;
|
||||||
|
start_snake_game();
|
||||||
|
|
||||||
|
uint32_t next_frame_ms = time_ms();
|
||||||
|
while (1) {
|
||||||
|
// while (true) {
|
||||||
|
// int ch = syscall(SYS_getc, 0);
|
||||||
|
// if (ch < 0)
|
||||||
|
// break;
|
||||||
|
// uint8_t keycode = (uint8_t)ch;
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
draw_frame();
|
||||||
|
|
||||||
|
syscall(SYS_swap_frame, (uintptr_t)frame);
|
||||||
|
|
||||||
|
next_frame_ms += 500;
|
||||||
|
wait_until(next_frame_ms);
|
||||||
|
}
|
||||||
|
}
|
||||||
2027
snake/sprite_data.h
Normal file
2027
snake/sprite_data.h
Normal file
File diff suppressed because it is too large
Load Diff
38
snake/sprites.h
Normal file
38
snake/sprites.h
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define TRANSPARENCY_COLOR 47
|
||||||
|
|
||||||
|
#define TILE_WIDTH 20
|
||||||
|
#define TILE_HEIGHT 32
|
||||||
|
#define TILE_HEIGHT_OFFSET 12
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t tex[TILE_WIDTH][TILE_HEIGHT];
|
||||||
|
} TileSprite;
|
||||||
|
|
||||||
|
#define FONT_WIDTH 12
|
||||||
|
#define FONT_HEIGHT 21
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t tex[FONT_WIDTH][FONT_HEIGHT];
|
||||||
|
} FontSprite;
|
||||||
|
|
||||||
|
#define PUDDLE_WIDTH 40
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t tex[PUDDLE_WIDTH][PUDDLE_WIDTH];
|
||||||
|
} PuddleSprite;
|
||||||
|
|
||||||
|
#define TILE_SPRITES 50
|
||||||
|
#define FONT_SPRITES (1+10+26)
|
||||||
|
#define PUDDLE_SPRITES 5
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
TileSprite tile[TILE_SPRITES];
|
||||||
|
FontSprite font[FONT_SPRITES];
|
||||||
|
PuddleSprite puddle[PUDDLE_SPRITES];
|
||||||
|
} SpriteData;
|
||||||
|
|
||||||
61
user/snake.c
61
user/snake.c
@ -1,61 +0,0 @@
|
|||||||
#include "../syscall.h"
|
|
||||||
#include "../drivers/vga.h"
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
enum {
|
|
||||||
FRAME_SIZE = VGA_GRAPHICS_WIDTH * VGA_GRAPHICS_HEIGHT,
|
|
||||||
BLOCK_WIDTH = 270,
|
|
||||||
BLOCK_HEIGHT = 100,
|
|
||||||
BLOCK_X = 10,
|
|
||||||
BLOCK_Y = 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Non-zero initializer keeps the framebuffer in the program image, which this
|
|
||||||
// loader maps more reliably than a large BSS object.
|
|
||||||
static uint8_t frame[FRAME_SIZE] = { 1 };
|
|
||||||
|
|
||||||
static uint32_t time_ms(void) {
|
|
||||||
return (uint32_t)syscall(SYS_time_ms, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void clear_frame(uint8_t color) {
|
|
||||||
for (uint32_t i = 0; i < FRAME_SIZE; i++) {
|
|
||||||
frame[i] = color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void put_pixel(int x, int y, uint8_t color) {
|
|
||||||
if (x < 0 || x >= VGA_GRAPHICS_WIDTH || y < 0 || y >= VGA_GRAPHICS_HEIGHT) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
frame[y * VGA_GRAPHICS_WIDTH + x] = color;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void draw_demo(void) {
|
|
||||||
clear_frame(0x01);
|
|
||||||
|
|
||||||
for (int y = 0; y < BLOCK_HEIGHT; y++) {
|
|
||||||
for (int x = 0; x < BLOCK_WIDTH; x++) {
|
|
||||||
int screen_x = BLOCK_X + x;
|
|
||||||
int screen_y = BLOCK_Y + y;
|
|
||||||
uint8_t color = (uint8_t)((x + 2 * y) & 0x3f);
|
|
||||||
|
|
||||||
if (x < 3 || y < 3 || x >= BLOCK_WIDTH - 3 || y >= BLOCK_HEIGHT - 3) {
|
|
||||||
color = 0x3f;
|
|
||||||
}
|
|
||||||
put_pixel(screen_x, screen_y, color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(void) {
|
|
||||||
syscall(SYS_switch_to_graphics, 0);
|
|
||||||
draw_demo();
|
|
||||||
syscall(SYS_swap_frame, (uintptr_t)frame);
|
|
||||||
|
|
||||||
uint32_t start = time_ms();
|
|
||||||
while ((uint32_t)(time_ms() - start) < 2000) {
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
Loading…
x
Reference in New Issue
Block a user