Disabled external gits
This commit is contained in:
1386
ee310-mes/source/engine.c
Normal file
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
174
ee310-mes/source/engine.h
Normal 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
|
107
ee310-mes/source/graphics_engine.c
Normal file
107
ee310-mes/source/graphics_engine.c
Normal 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)
|
||||
{
|
||||
|
||||
}
|
43
ee310-mes/source/graphics_engine.h
Normal file
43
ee310-mes/source/graphics_engine.h
Normal 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
|
298
ee310-mes/source/graphics_main.c
Normal file
298
ee310-mes/source/graphics_main.c
Normal 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);
|
||||
}
|
||||
|
||||
|
45
ee310-mes/source/graphics_main.h
Normal file
45
ee310-mes/source/graphics_main.h
Normal 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
|
||||
|
414
ee310-mes/source/graphics_sub.c
Normal file
414
ee310-mes/source/graphics_sub.c
Normal 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]);
|
||||
}
|
34
ee310-mes/source/graphics_sub.h
Normal file
34
ee310-mes/source/graphics_sub.h
Normal 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
267
ee310-mes/source/input.c
Normal 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
38
ee310-mes/source/input.h
Normal 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
328
ee310-mes/source/main.c
Normal 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, >);
|
||||
swiWaitForVBlank();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void main_submenu()
|
||||
{
|
||||
while (status != QUIT) {
|
||||
handle_keys_submenu(&status, >);
|
||||
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
191
ee310-mes/source/network.c
Normal 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;
|
||||
}
|
||||
}
|
||||
|
63
ee310-mes/source/network.h
Normal file
63
ee310-mes/source/network.h
Normal 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
304
ee310-mes/source/utils.h
Normal 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
|
Reference in New Issue
Block a user