Disabled external gits

This commit is contained in:
2022-04-07 18:46:57 +02:00
parent 88cb3426ad
commit 15e7120d6d
5316 changed files with 4563444 additions and 6 deletions

1386
ee310-mes/source/engine.c Normal file

File diff suppressed because it is too large Load Diff

174
ee310-mes/source/engine.h Normal file
View File

@@ -0,0 +1,174 @@
#pragma once
/**
* @file engine.h
* @author C. Hölzl
* @brief engine header file
*/
#ifdef __cplusplus
extern "C" {
#endif
#include <nds.h>
#include <string.h>
#include "utils.h"
/*
* Macros
*/
/*
* Type definitions
*/
typedef enum {
QUIT = -1, // QUIT GAME
RUN = 0, // RUNNING GAME
CONNECT, //CONNECTION TO SERVER
WAIT, // WAITING FOR SERVER // WAITING FOR ????
DEADLOCK, //SERVER BROKEN ????
LOAD, // LOADING LEVEL // WAITING FOR GEN
TIMEOUT, // TIMEOUT FROM SERVER
FINISHED //LOCAL GAME
} gs_t;
typedef enum {END = -1, START, MENU, SOLO, MULTI, GUIDE, CREDITS, RANKING} gt_t; //game state type
typedef enum {UNKNOWN = -1, UP, DOWN, LEFT, RIGHT,
INTERACT, INTERACT_PICKUP, INTERACT_DROP, INTERACT_EXIT, TAUNT
} action_t;
typedef enum { SWALL = 0b00000000000000000000000000000001,
NWALL = 0b00000000000000000000000000000010,
WWALL = 0b00000000000000000000000000000100,
EWALL = 0b00000000000000000000000000001000,
RTRAP = 0b00000000000000000000000000010000,
RSLOT = 0b00000000111111110000000000000000,
RPART = 0b11111111000000000000000000000000,
REXIT = 0b00000000000000001000000000000000
} room_elements;
#define BOX_ROOM (NWALL | SWALL | EWALL | WWALL | RTRAP | REXIT)
typedef u8 part_t;
typedef u32 room_t;
typedef struct {
room_t *list;
u32 size;
s32 slot_left;
u32 level;
} maze_t ;
#define MAZE_SIZE 1 //Size of Maze To Generate
#define DIFINC 2 //Size of Maze Increase Multiplier (exponential)
#define MAX_MAZE_SIZE 8 //Max Size to Exit
#define FOV 60
#define ROOM_SIZE 11
#define DOOR_SIZE (ROOM_SIZE/4)
#define DOOR_OFFSET ((ROOM_SIZE-DOOR_SIZE)/2)
#define ELEM_SIZE 4
typedef struct {
float32 x;
float32 y;
float32 r;
} position_t;
typedef struct {
s32 x;
s32 y;
position_t pos;
room_t room;
char name[NAME_LEN + 1];
part_t part;
u8 taunt;
} player_t;
typedef struct {
s8 x;
s8 y;
} net_position_t;
typedef struct {
s32 x;
s32 y;
net_position_t pos;
room_t room;
char name[NAME_LEN + 1];
part_t part;
u8 taunt;
} net_player_t;
typedef struct {
maze_t* maze;
player_t* player;
} game_t;
/*
* Functions
*/
u8 check_room_has_element(const room_t room, const room_elements element);
u8 check_player_has_part(const player_t* const player);
part_t get_slot_id(const room_t room);
part_t get_part_id(const room_t room);
void add_element_to_idx(maze_t* const maze, s16 x, s16 y, const room_elements element, const part_t p, const uint8_t c);
room_t* get_room_from_idx(const maze_t* const maze, s32 x, s32 y);
maze_t* maze_init(const s16 size, const u8 pop);
maze_t* maze_init_wr();
void free_maze(maze_t* maze);
maze_t* alloc_maze(s16 size);
void print_maze(maze_t* maze, player_t* player, char* path);
u8 apply_action_pos(maze_t* maze, player_t* player, action_t action, gs_t* status);
//u8 check_room_has_element(room_t room, room_elements element);
room_t* get_player_current_room(const maze_t* const maze, const player_t* const player);
void update_player_room(maze_t* maze, player_t* player);
void move_player_to_random_room(player_t* player, s16 size);
u8 is_wall(const s16 x, const s16 y, const room_t room);
room_elements is_door(const s16 x, const s16 y, const room_t room);
player_t* player_alloc();
player_t* player_init(player_t* player, char* name, u32 maze_size);
game_t* game_alloc();
void game_reset(game_t* game, u32 next_lvl, char* name, gs_t* status);
game_t* game_init(game_t* game, u32 dims, char* name, gs_t* status);
void game_end(game_t* game);
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,107 @@
/**
* @file graphics_engine.c
*/
#include "graphics_engine.h"
void init_graphics()
{
lcdMainOnBottom();
configure_graphics_main();
configure_graphics_sub();
create_palette_main();
create_palette_sub();
create_object_sub();
}
void draw_title()
{
draw_title_main();
draw_title_sub();
}
void draw_menu()
{
draw_menu_main();
draw_title_sub();
}
void switch_mode(gmode_t mode)
{
switch_mode_main(mode);
switch_mode_sub(mode);
}
void draw_game(const game_t* const game, const u32 time)
{
draw_game_main(game, time);
draw_game_sub(&(game->player->pos), *get_player_current_room(game->maze, game->player), game->maze->slot_left);
//draw_game_multi_sub(*get_player_current_room(game->maze, game->player),game->maze->slot_left);
//draw_player_multi_sub(NULL,false);
}
void draw_game_multi(const room_t room, const part_t part, const u32 slot_left, const bool taunt)
{
draw_game_multi_main(room, part, slot_left, taunt);
draw_game_multi_sub(room, slot_left);
}
void draw_loading()
{
clear_main_text();
draw_message_main("Loading...");
draw_title_sub();
}
void draw_connecting()
{
clear_main_text();
draw_message_main("Connecting...");
draw_title_sub();
}
void draw_warning(char* str){
draw_warning_main(str);
}
void draw_message(char* str){
draw_message_main(str);
}
void clear_message(){
clear_message_main();
}
void draw_guide()
{
draw_guide_main();
}
void draw_credits()
{
draw_credits_main();
}
void draw_rank()
{
draw_rank_main();
}
void draw_info(const room_t room, const part_t part, const u32 slot_left)
{
}
void draw_player(const player_t* const player, const u8 same_dim)
{
}

View File

@@ -0,0 +1,43 @@
#pragma once
/**
* @file graphics_engine.h
* @author C. Hölzl
* @brief graphics_engine header file
*/
#ifdef __cplusplus
extern "C" {
#endif
#include "engine.h"
#include "graphics_main.h"
#include "graphics_sub.h"
#include "utils.h"
void init_graphics();
void draw_title();
void draw_menu();
void draw_room(const room_t room, const s16 left);
void draw_info(const room_t room, const part_t part, const u32 slot_left);
void draw_player(const player_t* const player, const u8 same_dim);
void draw_game(const game_t* const game, const u32 time);
void draw_game_multi(const room_t room, const part_t part, const u32 slot_left, const bool taunt);
void draw_loading();
void draw_connecting();
void draw_guide();
void draw_credits();
void draw_rank();
void switch_mode(gmode_t mode);
void draw_message(char* msg);
void draw_warning(char* msg);
void clear_message();
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,298 @@
/**
* @file engine.c
* @brief Graphics engine
*/
#include <stdio.h>
#include "graphics_main.h"
#include "utils.h"
#include "text.h"
#include "title.h"
#include "menu.h"
#define TEXT_TILE_OFFSET_MAIN 7
#define TEXT_TILE_MAP_MAIN BG_MAP_RAM(TEXT_TILE_OFFSET_MAIN)
#define CLEAR_TEXT_TILE_MAP_MAIN() memset(TEXT_TILE_MAP_MAIN,0,32*48);
#define TEXT_RENDERER_SIZE 100
void clear_main_text(){
CLEAR_TEXT_TILE_MAP_MAIN();
}
//PrintConsole cs0;
void configure_graphics_main()
{
videoSetMode(MODE_5_2D);
vramSetBankA(VRAM_A_MAIN_BG_0x06000000);
vramSetBankB(VRAM_B_MAIN_BG_0x06020000);
//consoleInit(&cs0, 0, BgType_Text4bpp, BgSize_T_256x256, 14, 0, true, true);
bgInit(1, BgType_Text8bpp, BgSize_T_256x256, TEXT_TILE_OFFSET_MAIN, 0);
bgInit(2, BgType_Bmp8, BgSize_B8_256x256, 1, 0);
swiCopy(textTiles, BG_TILE_RAM(0), textTilesLen);
CLEAR_TEXT_TILE_MAP_MAIN();
}
void create_palette_main()
{
vramSetBankH(VRAM_E_BG_EXT_PALETTE);
swiCopy(menuPal, BG_PALETTE, menuPalLen);
SET_PERSONAL_PALETTE(BG_PALETTE);
}
void switch_mode_main(gmode_t mode)
{
switch (mode) {
case GGAME_ALT:
case GGAME:
CLEAR_TEXT_TILE_MAP_MAIN();
swiCopy(textPal, BG_PALETTE, textPalLen);
memset(BG_BMP_RAM(1), 0, SCREEN_WIDTH * SCREEN_HEIGHT);
break;
case GMENU:
CLEAR_TEXT_TILE_MAP_MAIN();
swiCopy(menuPal, BG_PALETTE, menuPalLen);
swiCopy(menuBitmap, BG_BMP_RAM(1), menuBitmapLen);
break;
default:
break;
}
}
void draw_text_at_idx(char* str, u32 top, u32 offset, textalign_t ta)
{
u16 start = 0;
switch (ta) {
case TA_LEFT:
start = offset;
break;
case TA_RIGHT:
start = (32 - strlen(str)) - offset;
break;
case TA_CENTER:
start = (16 - strlen(str) / 2) + offset;
break;
}
u16 cc = 0;
for (cc = 0; cc < strlen(str); ++cc) {
TEXT_TILE_MAP_MAIN[top * 32 + start + cc] = char_to_tile(str[cc]);
}
}
void draw_title_main()
{
draw_text_at_idx("> Press Start <", 6, 0, TA_CENTER);
}
void draw_menu_main()
{
}
void draw_guide_main()
{
draw_text_at_idx("You are in a Maze, looking for the EXIT.", 1, 1, TA_LEFT);
draw_text_at_idx("To unlock the EXIT you need to bring KEYS to LOCKS.", 4, 1, TA_LEFT);
draw_text_at_idx("In multiplayer, other players might have a KEY or LOCK matching your LOCK or KEY, use SHARED rooms to exchange KEYS.", 7, 1, TA_LEFT);
draw_text_at_idx("Careful: a room can only have one KEY at a time and you can only carry one... Be smart !", 12, 1, TA_LEFT);
draw_text_at_idx("Good Luck in solving NFH !", 17, 0, TA_CENTER);
draw_text_at_idx("> Press Start <", 20, 0, TA_CENTER);
}
void draw_credits_main()
{
draw_text_at_idx("Made by C. Holzl", 8, 0, TA_CENTER);
draw_text_at_idx("Music 'frozen26.exe'", 12,0, TA_CENTER);
draw_text_at_idx("by roz/rno @ ModArchive.org", 14,0, TA_CENTER);
draw_text_at_idx("> Press Start <", 20, 0, TA_CENTER);
}
void draw_rank_main()
{
u32 i;
char text_renderer[TEXT_RENDERER_SIZE] = {0};
pscore_t* highscore = get_score();
draw_text_at_idx("NAME", 1, 4, TA_LEFT);
draw_text_at_idx("SCORE", 1, 4, TA_RIGHT);
for (i = 0; i < SCORE_TAB_SIZE; ++i) {
if (strnlen(highscore[i].name, NAME_LEN + 1) != 0 && highscore[i].time <= SECTIME_MAX_VALUE) {
snprintf(text_renderer, TEXT_RENDERER_SIZE, "%2s", highscore[i].name);
draw_text_at_idx(text_renderer, 3 + i, 4, TA_LEFT);
snprintf(text_renderer, TEXT_RENDERER_SIZE, "%04u", highscore[i].time);
draw_text_at_idx(text_renderer, 3 + i, 4, TA_RIGHT);
}
}
draw_text_at_idx("> Press Start <", 20, 0, TA_CENTER);
}
void draw_warning_main(char* str)
{
memset(BG_BMP_RAM(1)+12*SCREEN_WIDTH, P_DARK_RED, SCREEN_WIDTH * 18);
draw_text_at_idx("- W A R N I N G -", 3, 0, TA_CENTER);
draw_text_at_idx(str, 4, 0, TA_CENTER);
}
void draw_message_main(char* str)
{
memset(BG_BMP_RAM(1)+12*SCREEN_WIDTH, P_DARK_YELLOW, SCREEN_WIDTH * 18);
draw_text_at_idx("- I N F O -", 3, 0, TA_CENTER);
draw_text_at_idx(str, 4, 0, TA_CENTER);
}
void clear_message_main()
{
memset(BG_BMP_RAM(1)+12*SCREEN_WIDTH, 0, SCREEN_WIDTH * 18);
memset(TEXT_TILE_MAP_MAIN+3*32,0, 32*2);
}
void print_room_content(char* text_renderer, const room_t room, const u16 slot_left, u8 top)
{
u8 empty = true;
if (check_room_has_element(room, REXIT)) {
empty = false;
snprintf(text_renderer, TEXT_RENDERER_SIZE, " EXIT(%02u) ", slot_left);
draw_text_at_idx(text_renderer, top, 0, TA_CENTER);
++top;
}
if (check_room_has_element(room, RPART)) { //INPUT()
empty = false;
snprintf(text_renderer, TEXT_RENDERER_SIZE, " KEY(%02u) ", get_part_id(room));
draw_text_at_idx(text_renderer, top, 0, TA_CENTER);
++top;
}
if (check_room_has_element(room, RSLOT)) { //OUTPUT()
empty = false;
snprintf(text_renderer, TEXT_RENDERER_SIZE, " LOCK(%02u) ", get_slot_id(room));
draw_text_at_idx(text_renderer, top, 0, TA_CENTER);
++top;
}
if (check_room_has_element(room, RTRAP)) {
empty = false;
snprintf(text_renderer, TEXT_RENDERER_SIZE, " SHARED ");
draw_text_at_idx(text_renderer, top, 0, TA_CENTER);
++top;
}
if (empty == true) { //PRIVATE
snprintf(text_renderer, TEXT_RENDERER_SIZE, " EMPTY ");
draw_text_at_idx(text_renderer, top, 0, TA_CENTER);
++top;
}
}
void draw_game_multi_main(const room_t room,const part_t part, const u16 slot_left, const bool taunt){
char text_renderer[TEXT_RENDERER_SIZE] = {0};
snprintf(text_renderer, TEXT_RENDERER_SIZE, "LEVEL: #");
draw_text_at_idx(text_renderer, 1, 1, TA_LEFT);
snprintf(text_renderer, TEXT_RENDERER_SIZE, "TIME: ####");
draw_text_at_idx(text_renderer, 1, 1, TA_RIGHT);
snprintf(text_renderer, TEXT_RENDERER_SIZE, "%s", taunt ? "T" : " ");
draw_text_at_idx(text_renderer, 1, 0, TA_CENTER);
snprintf(text_renderer, TEXT_RENDERER_SIZE, "ROOM CONTENT");
draw_text_at_idx(text_renderer, 6, 0, TA_CENTER);
print_room_content(text_renderer, room, slot_left, 8);
if (part > 0) {
snprintf(text_renderer, TEXT_RENDERER_SIZE, "CARRYING KEY: %02u (1/1)", part);
} else {
snprintf(text_renderer, TEXT_RENDERER_SIZE, "CARRYING KEY: -- (0/1) ");
}
draw_text_at_idx(text_renderer, 17, 1, TA_LEFT);
snprintf(text_renderer, TEXT_RENDERER_SIZE, "SLOTS LEFT: %02u", slot_left);
draw_text_at_idx(text_renderer, 19, 1, TA_LEFT);
snprintf(text_renderer, TEXT_RENDERER_SIZE, "EXIT: %s", slot_left == 0 ? "OPEN " : "CLOSED");
draw_text_at_idx(text_renderer, 21, 1, TA_LEFT);
}
void draw_game_main(const game_t* const game, const u32 time)
{
char text_renderer[TEXT_RENDERER_SIZE] = {0};
u16 level = 0;
u16 tmp = game->maze->level;
while (tmp > 0) {
tmp = tmp >> 1;
++level;
}
snprintf(text_renderer, TEXT_RENDERER_SIZE, "LEVEL: %u", level);
draw_text_at_idx(text_renderer, 1, 1, TA_LEFT);
snprintf(text_renderer, TEXT_RENDERER_SIZE, "TIME: %04u", time);
draw_text_at_idx(text_renderer, 1, 1, TA_RIGHT);
snprintf(text_renderer, TEXT_RENDERER_SIZE, "%s", game->player->taunt ? "T" : " ");
draw_text_at_idx(text_renderer, 1, 0, TA_CENTER);
snprintf(text_renderer, TEXT_RENDERER_SIZE, "ROOM CONTENT");
draw_text_at_idx(text_renderer, 6, 0, TA_CENTER);
print_room_content(text_renderer, *get_player_current_room(game->maze, game->player), game->maze->slot_left, 8);
if (game->player->part > 0) {
snprintf(text_renderer, TEXT_RENDERER_SIZE, "CARRYING KEY: %02u (1/1)", game->player->part);
} else {
snprintf(text_renderer, TEXT_RENDERER_SIZE, "CARRYING KEY: -- (0/1) ");
}
draw_text_at_idx(text_renderer, 17, 1, TA_LEFT);
snprintf(text_renderer, TEXT_RENDERER_SIZE, "SLOTS LEFT: %02u", game->maze->slot_left);
draw_text_at_idx(text_renderer, 19, 1, TA_LEFT);
snprintf(text_renderer, TEXT_RENDERER_SIZE, "EXIT: %s", game->maze->slot_left == 0 ? "OPEN " : "CLOSED");
draw_text_at_idx(text_renderer, 21, 1, TA_LEFT);
}

View File

@@ -0,0 +1,45 @@
#pragma once
/**
* @file graphics_main.h
* @author C. Hölzl
* @brief MainScreen Graphics header file
*/
#ifdef __cplusplus
extern "C" {
#endif
#include <nds.h>
#include "engine.h"
#include "utils.h"
void configure_graphics_main();
void switch_mode_main(gmode_t mode);
void create_palette_main();
void clear_main_text();
void draw_title_main();
void draw_menu_main();
void draw_guide_main();
void draw_credits_main();
void draw_rank_main();
void draw_warning_main(char* str);
void draw_message_main(char* str);
void clear_message_main();
void draw_game_multi_main(const room_t room,const part_t part, const u16 slot_left, const bool taunt);
void draw_game_main(const game_t* const game, const u32 time);
void draw_view(const player_t* const player, const room_t room);
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,414 @@
/**
* @brief Graphics engine
*/
#include "graphics_sub.h"
#include "engine.h"
#include "text.h"
#include "title.h"
#include "kc_full.h"
#define TEXT_TILE_OFFSET_SUB_0 6
#define TEXT_TILE_OFFSET_SUB_1 7
#define TEXT_TILE_MAP_SUB_0 BG_MAP_RAM_SUB(TEXT_TILE_OFFSET_SUB_0)
#define TEXT_TILE_MAP_SUB_1 BG_MAP_RAM_SUB(TEXT_TILE_OFFSET_SUB_1)
#define CLEAR_TEXT_TILE_MAP_0() memset(TEXT_TILE_MAP_SUB_0,0,32*48);
#define CLEAR_TEXT_TILE_MAP_1() memset(TEXT_TILE_MAP_SUB_1,0,32*48);
#define DRAW_TILE_AT_IDX(top,left) TEXT_TILE_MAP_SUB_0[(top) * 32 + (left)]
#define SPRITE_WIDTH 32
#define SPRITE_HEIGHT 32
#define KC_ROT 0
#define KC_IDX 0
#define GFX_PTR_OFFSET(offset) (((u32)offset & 0xFFFFF) >> oamSub.gfxOffsetStep)
#define SET_KC(gfxx) \
do { \
oamSub.oamMemory[KC_IDX].gfxIndex = GFX_PTR_OFFSET(gfxx); \
} while(false)
#define MOVE_KC(xx, yy) \
do { \
oamSub.oamMemory[KC_IDX].x = (xx); \
oamSub.oamMemory[KC_IDX].y = (yy); \
} while(false)
#define AFFINE_TRANSFORM(hx,vx,hy,vy)\
do { \
oamSub.oamRotationMemory[KC_ROT].hdx = hx;\
oamSub.oamRotationMemory[KC_ROT].vdx = vx;\
oamSub.oamRotationMemory[KC_ROT].hdy = hy;\
oamSub.oamRotationMemory[KC_ROT].vdy = vy;\
} while(false)
#define SCALE_KC(x,y) AFFINE_TRANSFORM(256*x,0,0,256*y)
u16* gfx_kc;
u16* gfx_kc_val;
u16* gfx_kc_inv;
u16* gfx_kc_slot;
#define SWITCH_KC_GRAPHICS(part,slot)\
do{\
if(slot >0 && part >0){\
if(slot == part){\
SET_KC(gfx_kc_val);\
}else{\
SET_KC(gfx_kc_inv);\
}\
}else if(slot > 0){\
SET_KC(gfx_kc_slot);\
}else if (part > 0){\
SET_KC(gfx_kc);\
}else{\
SET_KC(gfx_kc_slot);\
}\
}while(false)
u8 loading_screen_id = 0;
#define LOADING_SCREEN_COUNT 2
void configure_graphics_sub()
{
videoSetModeSub(MODE_5_2D);
vramSetBankC(VRAM_C_SUB_BG_0x06200000);
bgInitSub(0, BgType_Text8bpp, BgSize_T_256x256, TEXT_TILE_OFFSET_SUB_0, 0);
bgInitSub(1, BgType_Text8bpp, BgSize_T_256x256, TEXT_TILE_OFFSET_SUB_1, 0);
bgInitSub(2, BgType_Bmp8, BgSize_B8_256x256, 1, 0);
REG_BG2PA_SUB = 256;
REG_BG2PC_SUB = 0;
REG_BG2PB_SUB = 0;
REG_BG2PD_SUB = 256;
bgSetPriority(0,2);
bgSetPriority(1,1);
bgSetPriority(2,3);
swiCopy(titleBitmap + loading_screen_id * 64 * 192, BG_BMP_RAM_SUB(1), SCREEN_WIDTH * SCREEN_HEIGHT);
swiCopy(textTiles, BG_TILE_RAM_SUB(0), textTilesLen);
CLEAR_TEXT_TILE_MAP_0();
CLEAR_TEXT_TILE_MAP_1();
}
void create_palette_sub()
{
vramSetBankH(VRAM_H_SUB_BG_EXT_PALETTE);
swiCopy(titlePal, BG_PALETTE_SUB, titlePalLen);
SET_PERSONAL_PALETTE(BG_PALETTE_SUB);
}
void create_object_sub()
{
vramSetBankD(VRAM_D_SUB_SPRITE);
vramSetBankI(VRAM_I_SUB_SPRITE_EXT_PALETTE);
oamInit(&oamSub, SpriteMapping_1D_32, false);
gfx_kc = oamAllocateGfx(&oamSub, SpriteSize_32x64, SpriteColorFormat_256Color);
gfx_kc_val = oamAllocateGfx(&oamSub, SpriteSize_32x64, SpriteColorFormat_256Color);
gfx_kc_inv = oamAllocateGfx(&oamSub, SpriteSize_32x64, SpriteColorFormat_256Color);
gfx_kc_slot = oamAllocateGfx(&oamSub, SpriteSize_32x64, SpriteColorFormat_256Color);
//Copy data for the graphic (palette and bitmap)
swiCopy(kc_fullPal, SPRITE_PALETTE_SUB, kc_fullPalLen);
swiCopy(kc_fullTiles, gfx_kc, kc_fullTilesLen / (2 * 4));
swiCopy(kc_fullTiles + (64 * 8), gfx_kc_val, kc_fullTilesLen / (2 * 4));
swiCopy(kc_fullTiles + (64 * 16), gfx_kc_inv, kc_fullTilesLen / (2 * 4));
swiCopy(kc_fullTiles + (64 * 24), gfx_kc_slot, kc_fullTilesLen / (2 * 4));
oamSet(&oamSub, KC_IDX, SCREEN_WIDTH, 0, 0, 0, SpriteSize_32x64, SpriteColorFormat_256Color, gfx_kc,
KC_ROT, false, false, false, false, false);
}
void switch_mode_sub(gmode_t mode)
{
switch (mode) {
case GGAME:
CLEAR_TEXT_TILE_MAP_0();
CLEAR_TEXT_TILE_MAP_1();
SET_PERSONAL_PALETTE(BG_PALETTE_SUB);
break;
case GMENU:
CLEAR_TEXT_TILE_MAP_0();
CLEAR_TEXT_TILE_MAP_1();
swiCopy(titlePal, BG_PALETTE_SUB, titlePalLen);
swiCopy(titleBitmap + loading_screen_id * 64 * 192, BG_BMP_RAM_SUB(1), SCREEN_WIDTH * SCREEN_HEIGHT);
MOVE_KC(SCREEN_WIDTH, SCREEN_HEIGHT);
break;
case GGAME_ALT:
CLEAR_TEXT_TILE_MAP_0();
CLEAR_TEXT_TILE_MAP_1();
memset(BG_BMP_RAM_SUB(1), 0, SCREEN_WIDTH * SCREEN_HEIGHT);
swiCopy(textPal, BG_PALETTE_SUB, textPalLen);
MOVE_KC(SCREEN_WIDTH, SCREEN_HEIGHT);
break;
}
}
void next_loading_isr(u8 f)
{
++loading_screen_id;
if (loading_screen_id >= LOADING_SCREEN_COUNT || f != 0) {
loading_screen_id = LOADING_SCREEN_COUNT;
}
}
void draw_title_sub()
{
swiCopy(titleBitmap + loading_screen_id * 64 * 192, BG_BMP_RAM_SUB(1), SCREEN_WIDTH * SCREEN_HEIGHT);
MOVE_KC(SCREEN_WIDTH, SCREEN_HEIGHT);
}
u8 hit_kc = 0;
u8 screen_buff[SCREEN_WIDTH * SCREEN_HEIGHT] = {0};
void draw_vertical_line(const u32 col, const position_t* const pos, const room_t room, const s16 slot_left)
{
s16 angle = MOD((pos->r - (FOV / 2) + (col * FOV) / (SCREEN_WIDTH * 1.0)), 360);
float32 raydir_x = fixedToFloat(sinLerp(degreesToAngle(angle)), 12);
float32 raydir_y = fixedToFloat(cosLerp(degreesToAngle(angle)), 12);
s16 map_x = (s16)(pos->x);
s16 map_y = (s16)(pos->y);
float32 delta_dist_x = ABS(1.0 / raydir_x);
float32 delta_dist_y = ABS(1.0 / raydir_y);
float32 perp_dist = 0.1;
s8 step_x;
s8 step_y;
float32 border_dist_x;
float32 border_dist_y;
if (raydir_x < 0) {
step_x = -1;
border_dist_x = (pos->x - map_x) * delta_dist_x;
} else {
step_x = 1;
border_dist_x = (map_x + 1.0 - pos->x) * delta_dist_x;
}
if (raydir_y < 0) {
step_y = -1;
border_dist_y = (pos->y - map_y) * delta_dist_y;
} else {
step_y = 1;
border_dist_y = (map_y + 1.0 - pos->y) * delta_dist_y;
}
u8 side = 0;
u8 hit = 0;
part_t slot = get_slot_id(room);
part_t part = get_part_id(room);
while (hit == 0) {
if (border_dist_x < border_dist_y) {
border_dist_x += delta_dist_x;
map_x += step_x;
side = 0;
} else {
border_dist_y += delta_dist_y;
map_y += step_y;
side = 1;
}
if ((slot > 0 || part > 0) && (map_x-1 == ROOM_SIZE / 2) && map_y-1 == ROOM_SIZE / 2) {
hit_kc = 1;
if (side == 0) {
perp_dist = (map_x - pos->x + (1.0 - step_x) / 2.0) / raydir_x;
} else {
perp_dist = (map_y - pos->y + (1.0 - step_y) / 2.0) / raydir_y;
}
s16 lheight = (s16)(SCREEN_HEIGHT / perp_dist);
s16 lpos = MAX(0, -lheight / 2 + SCREEN_HEIGHT / 2);
SCALE_KC(MAX(1, perp_dist), MAX(1, perp_dist));
MOVE_KC(col - 32, SCREEN_HEIGHT - lpos - 64 / MAX(1, perp_dist));
SWITCH_KC_GRAPHICS(part, slot);
}
if ((is_wall(map_x, map_y, room) != 0) || (is_door(map_x, map_y, room) != 0)) hit = 1;
}
if (side == 0) {
perp_dist = (map_x - pos->x + (1.0 - step_x) / 2.0) / raydir_x;
} else {
perp_dist = (map_y - pos->y + (1.0 - step_y) / 2.0) / raydir_y;
}
s16 vheight = (SCREEN_HEIGHT / perp_dist);
if(perp_dist <= 0)
vheight = SCREEN_HEIGHT;
s16 vstart = (SCREEN_HEIGHT / 2) - (vheight / 2);
s16 vend = (SCREEN_HEIGHT / 2) + (vheight / 2);
u16 color = (is_door(map_x, map_y, room) > 0) ?
P_BLUE :
((is_wall(map_x, map_y, room) > 0) ?
(check_room_has_element(room, RTRAP) ?
P_VIOLET :
P_WHITE) :
P_TRANSPARENT);
if (side == 1) {
color = color + 1;
}
u8* buff = (u8*) screen_buff;
u32 row;
for (row = 0; row < SCREEN_HEIGHT; row++) {
if (row < vstart) {
buff[row * SCREEN_WIDTH + col] = P_DARK_DARK_WHITE;
} else if (row <= vend) {
buff[row * SCREEN_WIDTH + col] = color;
} else {
buff[row * SCREEN_WIDTH + col] = check_room_has_element(room, REXIT) ? (slot_left == 0 ? P_DARK_GREEN : P_DARK_RED) : P_DARK_DARK_WHITE;
}
}
}
void draw_view_sub(const position_t* const pos, const room_t room, const s16 left)
{
u32 col = 0;
hit_kc = 0;
for (col = 0; col < SCREEN_WIDTH; col++) {
draw_vertical_line(col, pos, room, left);
}
swiCopy(screen_buff, BG_BMP_RAM_SUB(1), SCREEN_WIDTH * SCREEN_HEIGHT);
if (hit_kc == 0) {
MOVE_KC(SCREEN_WIDTH, SCREEN_HEIGHT);
}
}
void draw_game_sub(const position_t* const pos, const room_t room, const s16 left)
{
draw_view_sub(pos, room, left);
}
static u16 elem_to_tile(room_elements elem){
switch(elem){
case NWALL:
case SWALL:
case WWALL:
case EWALL:
return 92;
break;
case RSLOT:
return 93;
break;
case RPART:
return 94;
break;
case RTRAP:
return 95;
break;
case REXIT:
return 96;
break;
}
return 0;
}
#define NET_ROOM_SIZE 16
#define NET_DOOR_SIZE (NET_ROOM_SIZE/4)
#define RMLO (16-NET_ROOM_SIZE/2)
#define RMTO 3
#define RMDO (16-NET_DOOR_SIZE/2)
void draw_game_multi_sub(const room_t room, const u32 slot_left){
memset(BG_BMP_RAM_SUB(1), 0, SCREEN_WIDTH * SCREEN_HEIGHT);
u16 i;
for(i = 0; i < NET_ROOM_SIZE; ++i){
DRAW_TILE_AT_IDX(RMTO,RMLO+i) = elem_to_tile(WWALL);
DRAW_TILE_AT_IDX(RMTO+1,RMLO+i) = elem_to_tile(WWALL);
DRAW_TILE_AT_IDX(RMTO+i,RMLO) = elem_to_tile(WWALL);
DRAW_TILE_AT_IDX(RMTO+i,RMLO+1) = elem_to_tile(WWALL);
DRAW_TILE_AT_IDX(RMTO+i,RMLO+NET_ROOM_SIZE-2) = elem_to_tile(WWALL);
DRAW_TILE_AT_IDX(RMTO+i,RMLO+NET_ROOM_SIZE-1) = elem_to_tile(WWALL);
DRAW_TILE_AT_IDX(RMTO+NET_ROOM_SIZE-2,RMLO+i) = elem_to_tile(WWALL);
DRAW_TILE_AT_IDX(RMTO+NET_ROOM_SIZE-1,RMLO+i) = elem_to_tile(WWALL);
}
for (i = 0; i < NET_DOOR_SIZE; ++i) {
if(!check_room_has_element(room, NWALL)){
DRAW_TILE_AT_IDX(RMTO,RMDO+i) = 0;
DRAW_TILE_AT_IDX(RMTO+1,RMDO+i) = 0;
}
if (!check_room_has_element(room, SWALL)) {
DRAW_TILE_AT_IDX(RMTO+NET_ROOM_SIZE-2,RMDO+i) = 0;
DRAW_TILE_AT_IDX(RMTO+NET_ROOM_SIZE-1,RMDO+i) = 0;
}
if (!check_room_has_element(room, WWALL)) {
DRAW_TILE_AT_IDX(RMTO+(NET_ROOM_SIZE/2)-(NET_DOOR_SIZE/2)+i,RMLO) = 0;
DRAW_TILE_AT_IDX(RMTO+(NET_ROOM_SIZE/2)-(NET_DOOR_SIZE/2)+i,RMLO+1) = 0;
}
if (!check_room_has_element(room, EWALL)) {
DRAW_TILE_AT_IDX(RMTO+(NET_ROOM_SIZE/2)-(NET_DOOR_SIZE/2)+i,RMLO+NET_ROOM_SIZE-2) = 0;
DRAW_TILE_AT_IDX(RMTO+(NET_ROOM_SIZE/2)-(NET_DOOR_SIZE/2)+i,RMLO+NET_ROOM_SIZE-1) = 0;
}
}
for (i = 0; i < ELEM_SIZE; ++i) {
if(check_room_has_element(room, RSLOT)){
u16 j;
for(j=0; j< ELEM_SIZE; ++j){
DRAW_TILE_AT_IDX(RMTO+(NET_ROOM_SIZE/2) - ELEM_SIZE/2+i, 16-2 + j)= elem_to_tile(RSLOT);
}
}
if(check_room_has_element(room, RPART)){
u16 j;
for(j=0; j< ELEM_SIZE; ++j){
DRAW_TILE_AT_IDX(RMTO+(NET_ROOM_SIZE/2) - ELEM_SIZE/2+1+i/2, 16-1 + j/2)= elem_to_tile(RPART);
}
}
if(check_room_has_element(room, REXIT)){
u16 spridx = elem_to_tile(REXIT) + ((slot_left == 0)?0:1);
DRAW_TILE_AT_IDX(RMTO+(ELEM_SIZE/2)+i - 2*(i/2), RMLO+(ELEM_SIZE/2) + i/2)= spridx;
DRAW_TILE_AT_IDX(RMTO+(ELEM_SIZE/2)+i - 2*(i/2), RMLO+NET_ROOM_SIZE-(ELEM_SIZE) + i/2)= spridx;
DRAW_TILE_AT_IDX(RMTO+NET_ROOM_SIZE-(ELEM_SIZE)+i - 2*(i/2), RMLO+NET_ROOM_SIZE-(ELEM_SIZE) + i/2)= spridx;
DRAW_TILE_AT_IDX(RMTO+NET_ROOM_SIZE-(ELEM_SIZE)+i - 2*(i/2), RMLO+(ELEM_SIZE/2) + i/2)= spridx;
}
if(check_room_has_element(room, RTRAP)){
DRAW_TILE_AT_IDX(RMTO+i - 2*(i/2), RMLO + i/2)= elem_to_tile(RTRAP) ;
DRAW_TILE_AT_IDX(RMTO+i - 2*(i/2), RMLO+NET_ROOM_SIZE-(ELEM_SIZE/2) + i/2)= elem_to_tile(RTRAP);
DRAW_TILE_AT_IDX(RMTO+NET_ROOM_SIZE-(ELEM_SIZE/2)+i - 2*(i/2), RMLO+NET_ROOM_SIZE-(ELEM_SIZE/2) + i/2)= elem_to_tile(RTRAP);
DRAW_TILE_AT_IDX(RMTO+NET_ROOM_SIZE-(ELEM_SIZE/2)+i - 2*(i/2), RMLO + i/2)= elem_to_tile(RTRAP);
}
}
}
void draw_player_multi_sub(const net_player_t* const player, const bool ghost){
TEXT_TILE_MAP_SUB_1[(RMTO+player->y) * 32 + (RMLO+player->x)] = elem_to_tile(REXIT)+1;
TEXT_TILE_MAP_SUB_0[(RMTO+player->y) * 32 + (RMLO+player->x)] = char_to_tile('A');//player->name[0]);
}

View File

@@ -0,0 +1,34 @@
#pragma once
/**
* @file graphics_sub.h
* @author C. Hölzl
* @brief Subscreen Graphics header file
*/
#ifdef __cplusplus
extern "C" {
#endif
#include <nds.h>
#include "engine.h"
#include "utils.h"
void configure_graphics_sub();
void switch_mode_sub(gmode_t mode);
void create_palette_sub();
void create_object_sub();
void draw_title_sub();
void next_loading_isr(u8 f);
void draw_game_sub(const position_t* const pos, const room_t room, const s16 left);
void draw_game_multi_sub(const room_t room, const u32 slot_left);
void draw_player_multi_sub(const net_player_t* const player, const bool ghost);
#ifdef __cplusplus
}
#endif

267
ee310-mes/source/input.c Normal file
View File

@@ -0,0 +1,267 @@
/*
* @file: input.c
* @author C. Hölzl
* @brief: Input Handler file
* 2019
*/
#include "input.h"
#include "network.h"
#include "graphics_engine.h"
#include "utils.h"
#define IS_PRESSED(key_code) (keys & key_code)
void handle_keys_solo(game_t* game, gs_t* status)
{
scanKeys();
u32 keys = keysDown();
if (IS_PRESSED(KEY_START)) {
*status = QUIT;
}
if (IS_PRESSED(KEY_SELECT)) {
//HANDLE SELECT
}
if (IS_PRESSED(KEY_A)) {
apply_action_pos(game->maze, game->player, INTERACT_PICKUP, status);
}
if (IS_PRESSED(KEY_B)) {
apply_action_pos(game->maze, game->player, INTERACT_DROP, status);
}
if (IS_PRESSED(KEY_X)) {
apply_action_pos(game->maze, game->player, INTERACT_EXIT, status);
}
if (IS_PRESSED(KEY_Y)) {
apply_action_pos(game->maze, game->player, TAUNT, status);
}
//keys = keysHeld();
if (IS_PRESSED(KEY_RIGHT)) {
apply_action_pos(game->maze, game->player, RIGHT, status);
}
if (IS_PRESSED(KEY_LEFT)) {
apply_action_pos(game->maze, game->player, LEFT, status);
}
if (IS_PRESSED(KEY_UP)) {
apply_action_pos(game->maze, game->player, UP, status);
}
if (IS_PRESSED(KEY_DOWN)) {
apply_action_pos(game->maze, game->player, DOWN, status);
}
if (IS_PRESSED(KEY_R)) {
game->player->pos.r = MOD(game->player->pos.r + 45, 360);
}
if (IS_PRESSED(KEY_L)) {
game->player->pos.r = MOD(game->player->pos.r - 45, 360);
}
}
void handle_keys_multi(gs_t* status)
{
scanKeys();
u32 keys = keysDown();
char action = 0;
if (IS_PRESSED(KEY_START)) {
action = 'Q';
*status = QUIT;
}
if (IS_PRESSED(KEY_SELECT)) {
action = 'F';
}
if (IS_PRESSED(KEY_A)) {
action = 'I';
}
if (IS_PRESSED(KEY_B)) {
action = 'I';
}
if (IS_PRESSED(KEY_X)) {
action = 'I';
}
if (IS_PRESSED(KEY_Y)) {
action = 'T';
}
if (IS_PRESSED(KEY_RIGHT)) {
action = 'D';
}
if (IS_PRESSED(KEY_LEFT)) {
action = 'A';
}
if (IS_PRESSED(KEY_UP)) {
action = 'W';
}
if (IS_PRESSED(KEY_DOWN)) {
action = 'S';
}
if (IS_PRESSED(KEY_L) && IS_PRESSED(KEY_R)) {
action = 'K';
}
if (action != 0 && (*status == RUN || *status == QUIT)) {
net_snd(&action, sizeof(char));
}
}
void handle_keys_menu(gs_t* gs, gt_t* gt)
{
scanKeys();
u32 keys = keysDown();
if (IS_PRESSED(KEY_TOUCH)) {
touchPosition touch;
touchRead(&touch);
if (touch.px > 52 && touch.px < SCREEN_WIDTH - 52 && touch.py > 50 && touch.py < 82) {
*gt = SOLO;
*gs = QUIT;
} else if (touch.px > 52 && touch.px < SCREEN_WIDTH - 52 && touch.py > 100 && touch.py < 132) {
*gt = MULTI;
*gs = QUIT;
} else if (touch.px > 5 && touch.px < 46 && touch.py > 168 && touch.py < 186) {
*gt = GUIDE;
*gs = QUIT;
} else if (touch.px > 196 && touch.px < 250 && touch.py > 168 && touch.py < 186) {
*gt = CREDITS;
*gs = QUIT;
} else if (touch.px > 96 && touch.px < 158 && touch.py > 158 && touch.py < 174) {
*gt = RANKING;
*gs = QUIT;
}
}
if (IS_PRESSED(KEY_START)) {
POWERDWN();
}
}
void handle_keys_submenu(gs_t* gs, gt_t* gt)
{
scanKeys();
u32 keys = keysDown();
if (IS_PRESSED(KEY_START) || IS_PRESSED(KEY_TOUCH)) {
*gs = QUIT;
}
}
void handle_keys_start(gs_t* gs)
{
scanKeys();
u32 keys = keysDown();
if (IS_PRESSED(KEY_START) || IS_PRESSED(KEY_TOUCH)) {
*gs = QUIT;
}
}
int timer_ticks;
void load_timer_ISR()
{
++timer_ticks;
if (timer_ticks % 16 == 0) { //2s
next_loading_isr(0);
}
if (timer_ticks >= 42) {
irqDisable(IRQ_TIMER0);
timer_ticks = 0;
}
}
u32 game_time = 0;
void game_time_ISR()
{
game_time = MIN(game_time + 1, SECTIME_MAX_VALUE);
}
u32 get_game_time()
{
return game_time;
}
void reset_game_time()
{
game_time = 0;
}
void init_load_timer()
{
timer_ticks = 0;
irqEnable(IRQ_TIMER0);
TIMER_DATA(0) = TIMER_FREQ_1024(8);
TIMER0_CR = TIMER_ENABLE | TIMER_DIV_1024;// | TIMER_IRQ_REQ;
irqSet(IRQ_TIMER0, &load_timer_ISR);
TIMER0_CR |= TIMER_IRQ_REQ;
}
void init_game_timer()
{
game_time = 0;
irqEnable(IRQ_TIMER1);
TIMER_DATA(1) = TIMER_FREQ_1024(1);
TIMER1_CR = TIMER_ENABLE | TIMER_DIV_1024;// | TIMER_IRQ_REQ;
irqSet(IRQ_TIMER1, &game_time_ISR);
TIMER1_CR |= TIMER_IRQ_REQ;
}
void disable_game_timer()
{
game_time = 0;
irqDisable(IRQ_TIMER1);
}
void init_audio()
{
mmInitDefaultMem((mm_addr)soundbank_bin);
mmLoad(MOD_FROZEN_26);
//mmLoadEffect(SFX_SWISH);
//mmLoadEffect(SFX_CLUNK);
mmStart(MOD_FROZEN_26, MM_PLAY_LOOP);
mmSetModuleVolume(512);
}
void play_sfx_audio(int i)
{
mm_sound_effect sound;
sound.id = i;
sound.rate = 1024;
sound.volume = 255;
// if(i == SFX_SWISH)
// sound.panning = 0;
// if(i == SFX_CLUNK)
// sound.panning = 255;
mmEffectEx(&sound);
}

38
ee310-mes/source/input.h Normal file
View File

@@ -0,0 +1,38 @@
#pragma once
/**
* @file input.h
* @author C. Hölzl
* @brief input header file
*/
#ifdef __cplusplus
extern "C" {
#endif
#include <nds.h>
#include <maxmod9.h>
#include "soundbank.h"
#include "soundbank_bin.h"
#include "engine.h"
void init_load_timer();
void init_game_timer();
void disable_game_timer();
void init_audio();
void handle_keys_solo(game_t* game, gs_t* status);
void handle_keys_multi(gs_t* status);
void handle_keys_menu(gs_t* gs, gt_t* gt);
void handle_keys_submenu(gs_t* gs, gt_t* gt);
void handle_keys_start(gs_t* status);
u32 get_game_time();
void reset_game_time();
#ifdef __cplusplus
}
#endif

328
ee310-mes/source/main.c Normal file
View File

@@ -0,0 +1,328 @@
/*
* @file: main.c
* @author C. Hölzl
* @brief: Main file
* 2019
*/
#include <nds.h>
#include <fat.h>
#include <stdio.h>
#include "utils.h"
#include "input.h"
#include "network.h"
#include "graphics_main.h"
#include "graphics_sub.h"
#include "graphics_engine.h"
gs_t status = LOAD;
gt_t gt = START;
#define DEFAULT_SOLO_MAZE_SIZE 0
void main_start()
{
while (status != QUIT) {
handle_keys_start(&status);
draw_title();
swiWaitForVBlank();
oamUpdate(&oamSub);
}
}
void main_menu()
{
while (status != QUIT) {
handle_keys_menu(&status, &gt);
swiWaitForVBlank();
}
}
void main_submenu()
{
while (status != QUIT) {
handle_keys_submenu(&status, &gt);
swiWaitForVBlank();
}
}
void main_solo()
{
u32 dimentions = DEFAULT_SOLO_MAZE_SIZE;
char name[NAME_LEN + 1] = PNAME;
draw_loading();
game_t* game = game_init(game_alloc(), dimentions, name, &status);
update_player_room(game->maze, game->player);
init_game_timer();
clear_main_text();
clear_message();
while (status != QUIT) {
if (game->maze->level > MAX_MAZE_SIZE) {
status = QUIT;
}
switch (status) {
case RUN:
handle_keys_solo(game, &status);
draw_game(game, get_game_time());
break;
case LOAD:
break;
case FINISHED:
if (game->maze->level == 8) {
pscore_t score = {"++", get_game_time()};
strncpy(score.name, game->player->name, NAME_LEN);
insert_score(&score);
write_score();
}
draw_loading();
game_reset(game, game->maze->level * DIFINC, game->player->name, &status);
reset_game_time();
clear_main_text();
clear_message();
break;
default:
break;
}
swiWaitForVBlank();
oamUpdate(&oamSub);
}
disable_game_timer();
game_end(game);
}
bool handle_rcv_msg_sc(const char * const in_msg)
{
switch (in_msg[0]) {
case 'L':
status = LOAD;
break;
case 'W':
status = WAIT;
break;
case 'D':
status = DEADLOCK;
break;
case 'R':
default:
break;
}
return true;
}
bool handle_rcv_msg_op(const char * imptr, room_t room)
{
net_player_t oplayer;
u32 n = 0;
while (strlen(imptr) >= 3) {
if (sscanf(imptr, " %2s %hhd %hhd %hhu %hhu %n", oplayer.name, &oplayer.pos.x, &oplayer.pos.y, &oplayer.part, &oplayer.taunt, &n) != 5) {
return false;
}
imptr += n;
draw_player_multi_sub(&oplayer,check_room_has_element(room, RTRAP));
}
return true;
}
bool handle_rcv_msg(const char * const in_msg)
{
if (strlen(in_msg) == 1) {
return handle_rcv_msg_sc(in_msg);
} else {
if (status != RUN && status != DEADLOCK && status != QUIT) {
status = RUN;
}
u32 slot_left = 0;
room_t room = BOX_ROOM;
u8 global_slot_left = 0;
u32 size = 0;
net_player_t player;
u32 n = 0;
const char* imptr = in_msg;
if (sscanf(imptr, "%u %hhu %d %2s %hhd %hhd %hhu %hhu %n", &room, &global_slot_left, &slot_left, player.name, &player.pos.x, &player.pos.y, &player.part, &player.taunt, &n) != 8) {
return false;
}
if (size) {}
imptr += n;
draw_game_multi(room, player.part, slot_left, player.taunt);
if (handle_rcv_msg_op(imptr, room) == false)
return false;
draw_player_multi_sub(&player,true);
//drawinfo(room, player.part, slot_left);
if (global_slot_left > 0 && slot_left == 0) {
draw_message("Waiting for everybody to finish");
} else {
clear_message_main();
}
}
return true;
}
#define RCV_BUFF_SIZE 1024
void main_multi()
{
char name[NAME_LEN + 1] = PNAME;
char rcv_buff[RCV_BUFF_SIZE] = {0};
draw_connecting();
if (init_wlpif() != 0) { //Connect to Wifi
status = QUIT;
return;
}
if (init_socket(1) != 0) { //Connect to Server
status = QUIT;
end_wlpif();
return;
}
if (net_snd(name, strlen(name)) == -1) { //Send name to server
end_wlpif();
end_socket();
return;
}
draw_loading();
while (status != QUIT) {
switch (status) {
case DEADLOCK:
draw_warning("A player left, maze might be unsolvable");
case RUN:
handle_keys_multi(&status);
// draw_game_multi(game, get_game_time());
break;
case WAIT:
draw_message("Waiting for Previous Game to Finish");
break;
case LOAD:
clear_message_main();
draw_loading();
break;
case TIMEOUT:
status = QUIT;
break;
case FINISHED:
clear_message_main();
//draw_loading();
break;
default:
break;
}
if(rcv_room_from_server(rcv_buff, RCV_BUFF_SIZE, &status)){
if(handle_rcv_msg(rcv_buff)==false){
status = QUIT;
}
}
swiWaitForVBlank();
oamUpdate(&oamSub);
}
end_wlpif();
end_socket();
}
int main(void)
{
fatInitDefault();
rand_init(clock());
read_score();
init_graphics();
init_load_timer();
init_audio();
while (gt != END) {
status = LOAD;
switch (gt) {
case START:
main_start();
next_loading_isr(1);
gt = MENU;
break;
case MENU:
switch_mode(GMENU);
draw_menu();
main_menu();
break;
case SOLO:
switch_mode(GGAME);
main_solo();
gt = MENU;
break;
case MULTI:
switch_mode(GGAME_ALT);
main_multi();
gt = MENU;
break;
case CREDITS:
switch_mode_main(GGAME);
draw_credits();
main_submenu();
gt = MENU;
break;
case GUIDE:
switch_mode_main(GGAME);
draw_guide();
main_submenu();
gt = MENU;
break;
case RANKING:
switch_mode_main(GGAME);
draw_rank();
main_submenu();
gt = MENU;
break;
default:
return 1;
}
swiWaitForVBlank();
}
return 0;
}

191
ee310-mes/source/network.c Normal file
View File

@@ -0,0 +1,191 @@
#include <string.h> // for memset
#include "network.h"
#include "engine.h"
#include "utils.h"
#define SSID "MES-NDS"
#define PROTOCOL_IP_TCP 6
#define PROTOCOL_IP_UDP 17
#define MSG_KEY "FRZN"
#define MSG_KEY_LEN 4
saddr_t sa_out, sa_in;
s32 sockfd = 01;
bool socket_init = false;
bool wlpif_init = false;
#define MAX_WLP_RETRIES 1024
s16 init_wlpif()
{
if (wlpif_init == true)
return 0;
Wifi_AccessPoint ap;
s32 found = 0, count = 0, i = 0;
Wifi_InitDefault(false);
Wifi_ScanMode();
u8 retries = 0;
while (found == 0) {
count = Wifi_GetNumAP();
for (i = 0; (i < count) && (found == 0); i++) {
Wifi_GetAPData(i, &ap);
if (strcmp(SSID, ap.ssid) == 0)
found = 1;
}
++retries;
if (retries > MAX_WLP_RETRIES)
return -1;
}
Wifi_SetIP(0, 0, 0, 0, 0);
Wifi_ConnectAP(&ap, WEPMODE_NONE, 0, 0);
s32 status = ASSOCSTATUS_DISCONNECTED;
while ((status != ASSOCSTATUS_ASSOCIATED) &&
(status != ASSOCSTATUS_CANNOTCONNECT)) {
status = Wifi_AssocStatus();
swiWaitForVBlank();
}
wlpif_init = (status == ASSOCSTATUS_ASSOCIATED);
return 0;
}
// ======================================================================
s16 init_socket(const s16 t)
{
if (socket_init == true) return 0;
if (wlpif_init == false) return -1;
sockfd = socket(AF_INET, SOCK_STREAM, PROTOCOL_IP_TCP);//IPPROTO_TCP);
//sockfd = socket(AF_INET, SOCK_DGRAM, PROTOCOL_IP_UDP);//IPPROTO_UDP);
if (sockfd == -1) return -1;
if (t >= 0) {
struct timeval timeout;
memset(&timeout, 0, sizeof(timeout));
timeout.tv_sec = t;
timeout.tv_usec = 100;
if (setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO,
&timeout, sizeof(timeout)) == -1) {
closesocket(sockfd);
return -1;
}
}
sa_in.sin_family = AF_INET;
sa_in.sin_port = htons(DEFAULT_PORT);
sa_in.sin_addr.s_addr = 0x00000000;
if (bind(sockfd, (struct sockaddr*)&sa_in, sizeof(sa_in)) < 0) {
closesocket(sockfd);
return -1;
}
//struct hostent* server_host = gethostbyname(DEFAULT_IP);
sa_out.sin_family = AF_INET;
sa_out.sin_port = htons(DEFAULT_PORT);
sa_out.sin_addr.s_addr = DEFAULT_IP_BIN; //*(server_host->h_addr_list[0]);//
//char nonblock = 1;
//ioctl(sockfd, FIONBIO, &nonblock);
if (connect(sockfd, (struct sockaddr*)&sa_out, sizeof(sa_out)) < 0) {
closesocket(sockfd);
return -1;
}
socket_init = true;
return 0;
}
void end_socket()
{
if (socket_init == false)
return;
shutdown(sockfd, SHUT_RDWR);
closesocket(sockfd);
socket_init = false;
}
void end_wlpif()
{
if (wlpif_init == false)
return;
Wifi_DisconnectAP();
wlpif_init = false;
}
s32 net_snd(char* data_buff, s32 bytes)
{
if (socket_init == false)
return -1;
sendto(sockfd, data_buff, bytes, 0, (struct sockaddr *)&sa_out, sizeof(sa_out));
return 1;
}
s32 net_rcv(char* data_buff, s32 bytes)
{
if (socket_init == false)
return -1;
s32 received_bytes;
s32 info_size = sizeof(sa_in);
received_bytes = recvfrom(sockfd, data_buff, bytes,
~MSG_PEEK,
(struct sockaddr *)&sa_in, (int*) &info_size);
return received_bytes;
}
bool rcv_room_from_server(char* data_buff, s32 bytes, gs_t* const game_status)
{
if (socket_init == false)
return -1;
memset(data_buff, 0, 1024);
s32 data_buff_len = net_rcv(data_buff, bytes);
if (data_buff_len < 0) {
return false;
} else if (data_buff_len == 0) {
*game_status = QUIT;
return false;
}
if ((s32)data_buff_len == strlen(data_buff)) {
return true;
} else {
return false;
}
}

View File

@@ -0,0 +1,63 @@
#pragma once
#include <nds.h>
#include <dswifi9.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include "engine.h"
#include "utils.h"
/**
* @brief Server Listen and Server Ip's
*/
#define DEFAULT_IP "35.157.44.223" //AWS_IP
#define DEFAULT_IP_BIN 0x239d2cdf //Precomputed because arpa/inet.h is not available
/**
* @brief default port for UDP/TCP communication
*/
#define DEFAULT_PORT 27500
/*typedef struct {
u16 addraddr;
u16 addr;
} saddr_t;*/
typedef struct sockaddr_in saddr_t;
typedef enum {INVALID = -1, NAME, GSTART, ACTION} client_message_t;
/** ======================================================================
* @brief Initializes and connects to WIFI
* @return error
*/
s16 init_wlpif();
/** ======================================================================
* @brief get a socket for communication and sets its reception timeout
* @param receive timeout in seconds, 0 means infinity (no timeout)
* @return error
*/
s16 init_socket(const s16 receive_timeout_in_seconds);
/** ======================================================================
* @brief Cleans up a socket
*/
void end_socket();
/** ======================================================================
* @brief Disconnects from wifi
*/
void end_wlpif();
// VARIOUS FUNCTIONS
s32 net_snd(char* data_buff, s32 bytes);
s32 net_rcv(char* data_buff, s32 bytes);
bool rcv_room_from_server(char* data_buff, s32 bytes, gs_t* const game_status);

304
ee310-mes/source/utils.h Normal file
View File

@@ -0,0 +1,304 @@
/**
* @file util.h
*/
#pragma once
/**
* @file util.h
* @author C. Hölzl
* @brief util header file
*/
#ifdef __cplusplus
extern "C" {
#endif
#include <nds.h>
#include <fat.h>
#include <stdio.h>
#include <string.h>
#define NAME_LEN 2
#define MAX(x,y) ((x)>(y)?(x):(y))
#define MIN(x,y) ((x)<(y)?(x):(y))
#define ABS(x) ((x)<0?(-(x)):(x))
#define MOD(x,y) (((y)==0)?0:((s32)((x)+(y)))%(y))
#define SIGN(a) ((a)/abs(a))
#define ARGB6(a,r,g,b) ( ((a) << 5) | ((r)|((g)<<5)|((b)<<10)))
#define HALF_BRIGHT_COLOR(color) ARGB16((color >> 15),\
(color & 0x1F)/2,\
((color >> 5) & 0x1F)/2,\
((color >> 10) & 0x1F)/2)
#define TRANSPARENT ARGB16(0,0,0,0)
#define DARK_DARK_WHITE ARGB16(1,7,7,7)
#define DARK_WHITE ARGB16(1,15,15,15)
#define WHITE ARGB16(1,29,29,30)
#define DARK_BLUE ARGB16(1,7,8,10)
#define BLUE ARGB16(1,11,16,21)
#define DARK_RED ARGB16(1,12,6,7)
#define RED ARGB16(1,23,12,13)
#define DARK_ORANGE ARGB16(1,13,8,7)
#define ORANGE ARGB16(1,25,16,14)
#define DARK_YELLOW ARGB16(1,15,13,9)
#define YELLOW ARGB16(1,29,25,17)
#define DARK_GREEN ARGB16(1,10,12,9)
#define GREEN ARGB16(1,20,23,17)
#define DARK_VIOLET ARGB16(1,11,9,11)
#define VIOLET ARGB16(1,11,9,11)
#define P_TRANSPARENT 31
#define P_WHITE 16
#define P_DARK_WHITE 17
#define P_DARK_DARK_WHITE 18
#define P_BLUE 19
#define P_DARK_BLUE 20
#define P_RED 21
#define P_DARK_RED 22
#define P_ORANGE 23
#define P_DARK_ORANGE 24
#define P_YELLOW 25
#define P_DARK_YELLOW 26
#define P_GREEN 27
#define P_DARK_GREEN 28
#define P_VIOLET 29
#define P_DARK_VIOLET 30
#define SET_PERSONAL_PALETTE(PTR)\
do {\
PTR[P_TRANSPARENT] = TRANSPARENT;\
PTR[P_WHITE] = WHITE;\
PTR[P_DARK_WHITE] = DARK_WHITE;\
PTR[P_DARK_DARK_WHITE] = DARK_DARK_WHITE;\
PTR[P_BLUE] = BLUE;\
PTR[P_DARK_BLUE] = DARK_BLUE;\
PTR[P_RED] = RED;\
PTR[P_DARK_RED] = DARK_RED;\
PTR[P_ORANGE] = ORANGE;\
PTR[P_DARK_ORANGE] = DARK_ORANGE;\
PTR[P_YELLOW] = YELLOW;\
PTR[P_DARK_YELLOW] = DARK_YELLOW;\
PTR[P_GREEN] = GREEN;\
PTR[P_DARK_GREEN] = DARK_GREEN;\
PTR[P_VIOLET] = VIOLET;\
PTR[P_DARK_VIOLET] = DARK_VIOLET;\
} while (false)
typedef enum {GGAME, GGAME_ALT, GMENU} gmode_t;
/*
* Initialize random number generator
*/
static inline void rand_init(u32 seed)
{
srand(seed);
}
/*
* Generate a random number within range
*/
static inline u32 rand_value(u32 range)
{
return ((u32)((float32) range * rand() / (RAND_MAX + 1.0)));
}
typedef enum { TA_LEFT, TA_RIGHT, TA_CENTER} textalign_t;
#define PNAME {PersonalData->name[0],PersonalData->name[1],0}
#define SCORE_TAB_SIZE 16
#define SECTIME_MAX_VALUE 9999
typedef struct {
char name[NAME_LEN + 1];
u32 time;
} pscore_t;
pscore_t highscore[SCORE_TAB_SIZE];
#define POWERDWN() powerOn(PM_SYSTEM_PWR)
static inline void write_score()
{
FILE* file = fopen("/nfh8_score.txt", "w+");
if (file != NULL) {
u32 i;
for (i = 0; i < SCORE_TAB_SIZE; ++i) {
fprintf(file, "%2s %u\n", highscore[i].name, highscore[i].time);
}
fclose(file);
}
}
static inline void insert_score(const pscore_t* score)
{
u32 i = SCORE_TAB_SIZE - 1;
//pscore_t tmp = {"++",SECTIME_MAX_VALUE};
while (i < SCORE_TAB_SIZE && score->time < highscore[i].time) {
if (i - 1 >= 0) {
strncpy(highscore[i].name, highscore[i - 1].name, NAME_LEN);
highscore[i].time = highscore[i - 1].time;
}
strncpy(highscore[i - 1].name, score->name, NAME_LEN);
highscore[i - 1].time = score->time;
++i;
}
}
static inline pscore_t* get_score()
{
return highscore;
}
static inline void read_score()
{
FILE* file = fopen("/nfh8_score.txt", "r");
if (file != NULL) {
u32 i;
for (i = 0; i < SCORE_TAB_SIZE; ++i) {
u8 r = fscanf(file, "%2s %u\n", highscore[i].name, &(highscore[i].time));
if (r != 2 || strnlen(highscore[i].name, NAME_LEN + 1) == 0 || highscore[i].time > SECTIME_MAX_VALUE) {
//strncpy(highscore[i].name, "--", NAME_LEN);
highscore[i].time = SECTIME_MAX_VALUE;
}
}
fclose(file);
} else {
u32 i;
for (i = 0; i < SCORE_TAB_SIZE; ++i) {
strncpy(highscore[i].name, "", NAME_LEN);
highscore[i].time = SECTIME_MAX_VALUE;
}
}
}
static inline u16 char_to_tile(char c)
{
if (c >= 'A' && c <= 'Z') {
return (c - 'A') + 1;
}
if (c >= 'a' && c <= 'z') {
return (c - 'a') + 39;
}
if (c >= '1' && c <= '9') {
return (c - '1') + 27;
}
if (c == '0') {
return 36;
}
switch (c) {
case '[':
return 37;
case ']':
return 38;
case '!':
return 65;
case '.':
return 66;
case '?':
return 67;
case '@':
return 68;
case '#':
return 69;
case '$':
return 70;
case '%':
return 71;
case '^':
return 72;
case '&':
return 73;
case '(':
return 74;
case ')':
return 75;
case ':':
return 76;
case ';':
return 77;
case ',':
return 78;
case '\'':
return 79;
case '+':
return 81;
case '-':
return 82;
case '=':
return 83;
case '{':
return 84;
case '}':
return 85;
case '\\':
return 86;
case '/':
return 87;
case '<':
return 88;
case '>':
return 89;
case '`':
return 90;
case '"':
return 91;
case ' ':
return 0;
default:
return 0;
}
}
#ifdef __cplusplus
}
#endif