commit
efbf7fdbee
|
@ -1,3 +1,4 @@
|
|||
build/
|
||||
lib/
|
||||
*g1a
|
||||
/tools/mapconv/mapconv
|
||||
|
|
|
@ -12,7 +12,10 @@ SRC = src/start.c \
|
|||
src/time.c \
|
||||
src/gui.c \
|
||||
src/memory.c \
|
||||
src/ext/img.c
|
||||
src/rtc.c \
|
||||
src/ext/img.c \
|
||||
src/ext/gametools/map.c \
|
||||
src/ext/gametools/collisions.c
|
||||
OBJ = $(SRC:src/%=build/%.o)
|
||||
|
||||
CFLAGS = -Os -Wall -Wextra -Wpedantic -Werror -std=c89
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
#ifndef GAMETOOLS_H
|
||||
#define GAMETOOLS_H
|
||||
|
||||
/******* MAP *******/
|
||||
|
||||
/* Struct */
|
||||
|
||||
typedef struct {
|
||||
unsigned char *map; /* Map data (size w*h)
|
||||
the tile 0 contains nothing, and the other tiles are decremented and grabbed
|
||||
in tileset, so 1 is the first tile in tileset. */
|
||||
unsigned char **tileset; /* Tileset (Sprite Coder sprite table) */
|
||||
int w, h; /* Map width and height */
|
||||
int tw, th; /* Tile width and height */
|
||||
int px, py; /* Contains the position of the player on the screen, after
|
||||
drawing the map */
|
||||
int pw, ph; /* Player height and width. */
|
||||
int sx, sy; /* Where the map started to be drawn. */
|
||||
int padx, pady; /* Where the map was drawn on the screen. */
|
||||
int sw, sh; /* The size of the part that was drawn on screen. */
|
||||
} MMap;
|
||||
|
||||
/* Prototypes */
|
||||
|
||||
/* void vmap(int sx, int sy, MMap *map);
|
||||
|
||||
Draws a map contained in a MMap struct.
|
||||
vmap draw the map with the player at sx, sy.
|
||||
*/
|
||||
|
||||
void vmap(int sx, int sy, MMap *map);
|
||||
|
||||
/* void vplayer(MMap *map, unsigned char **player_sprites, int anim_frame);
|
||||
|
||||
Draws the player on map map, from the sprite coder image in the image table at
|
||||
anim frame.
|
||||
*/
|
||||
|
||||
void vplayer(MMap *map, unsigned char **player_sprites, int anim_frame);
|
||||
|
||||
/* void vitem(MMap *map, int x, int y, int w, int h, unsigned char **item,
|
||||
int anim_frame);
|
||||
|
||||
Draws an item at the position (x, y) on the map on the screen.
|
||||
item is the sprite coder sprite table that contains the diffrent frames of the
|
||||
animation of this item.
|
||||
anim_frame is the frame of the animation of item that should be drawn.
|
||||
*/
|
||||
|
||||
void vitem(MMap *map, int x, int y, int w, int h, unsigned char **item,
|
||||
int anim_frame);
|
||||
|
||||
/******* COLLISIONS *******/
|
||||
|
||||
/* int vget_tile_at_point(MMap *map, int x, int y);
|
||||
|
||||
Get the tile located at x, y on MMap map map.
|
||||
Returns the tile number or -1 if the tile is outside of the map.
|
||||
*/
|
||||
|
||||
int vget_tile_at_point(MMap *map, int x, int y);
|
||||
|
||||
#endif
|
|
@ -90,6 +90,13 @@ Works like stext, but here the font is PrintMini and you cannot set the color.
|
|||
|
||||
void stextmini(int x, int y, char *text);
|
||||
|
||||
/* char* sgetvram(void);
|
||||
|
||||
Get the address of the VRAM.
|
||||
*/
|
||||
|
||||
char* sgetvram(void);
|
||||
|
||||
/******* KEYBOARD *******/
|
||||
|
||||
/* int kisdown(void);
|
||||
|
@ -219,6 +226,20 @@ Stop the timer id.
|
|||
|
||||
void tstoptimer(int id);
|
||||
|
||||
/******* RTC *******/
|
||||
|
||||
typedef struct {
|
||||
int year, month, day; /* The current date (unused) */
|
||||
int hour, minute, second, millisecond; /* The current time */
|
||||
} MRtc;
|
||||
|
||||
/* void rgettime(MRtc *rtc);
|
||||
|
||||
Puts the current hour, minute, second and millisecond in the rtc Mrtc struct.
|
||||
*/
|
||||
|
||||
void rgettime(MRtc *rtc);
|
||||
|
||||
/******* CPU *******/
|
||||
|
||||
/* void csleep(void);
|
||||
|
@ -252,7 +273,7 @@ input.
|
|||
|
||||
void gstrask(char *buffer, char *message, int maxlen);
|
||||
|
||||
/* void simage(int sx, int sy, int w, int h, unsigned char *img, int mode);
|
||||
/* void gfkeyset(int pos, unsigned char *img);
|
||||
|
||||
Draws an fkey from a Sprite Coder string that is in img, at fkey position pos.
|
||||
*/
|
||||
|
@ -266,6 +287,13 @@ Draws a message box of height height with that contains message.
|
|||
|
||||
void gmessagebox(int height, char *message);
|
||||
|
||||
/* void gpopup(int hlines);
|
||||
|
||||
Draws a popup that has a height of hlines lines.
|
||||
*/
|
||||
|
||||
void gpopup(int hlines);
|
||||
|
||||
/******* Memory *******/
|
||||
|
||||
/* File structure */
|
||||
|
|
|
@ -14,77 +14,57 @@ void _Print(unsigned char *text);
|
|||
void _Bdisp_DrawLineVRAM(int x1, int y1, int x2, int y2);
|
||||
void _Bdisp_ClearLineVRAM(int x1, int y1, int x2, int y2);
|
||||
void _PrintMiniSd(int x, int y, unsigned char *text, int color);
|
||||
void _DisplayMessageBox(int height, unsigned char *message);
|
||||
char* _GetVRAMAddress(void);
|
||||
|
||||
/* Microfx */
|
||||
|
||||
void sclear() {
|
||||
_Bdisp_AllClr_VRAM();
|
||||
_Bdisp_AllClr_VRAM();
|
||||
}
|
||||
|
||||
void supdate() {
|
||||
_Bdisp_PutDisp_DD();
|
||||
_Bdisp_PutDisp_DD();
|
||||
}
|
||||
|
||||
void spixel(int x, int y, int color) {
|
||||
if(x>=0 && x<SWIDTH && y>=0 && y<SHEIGHT){
|
||||
_Bdisp_SetPoint_VRAM(x, y, color);
|
||||
}
|
||||
if(x>=0 && x<SWIDTH && y>=0 && y<SHEIGHT){
|
||||
_Bdisp_SetPoint_VRAM(x, y, color);
|
||||
}
|
||||
}
|
||||
|
||||
void srect(int x1, int y1, int x2, int y2) {
|
||||
_Bdisp_DrawRectangle(x1, y1, x2, y2);
|
||||
_Bdisp_DrawRectangle(x1, y1, x2, y2);
|
||||
}
|
||||
|
||||
void sline(int x1, int y1, int x2, int y2, int color) {
|
||||
if(color){
|
||||
_Bdisp_DrawLineVRAM(x1, y1, x2, y2);
|
||||
}else{
|
||||
_Bdisp_ClearLineVRAM(x1, y1, x2, y2);
|
||||
}
|
||||
if(color){
|
||||
_Bdisp_DrawLineVRAM(x1, y1, x2, y2);
|
||||
}else{
|
||||
_Bdisp_ClearLineVRAM(x1, y1, x2, y2);
|
||||
}
|
||||
}
|
||||
|
||||
void stext(int x, int y, char *text, int color) {
|
||||
_PrintXY(x, y, (unsigned char*)text, !color);
|
||||
_PrintXY(x, y, (unsigned char*)text, !color);
|
||||
}
|
||||
|
||||
void slocate(int x, int y, char *text) {
|
||||
_locate(x, y);
|
||||
_Print((unsigned char*)text);
|
||||
_locate(x, y);
|
||||
_Print((unsigned char*)text);
|
||||
}
|
||||
|
||||
void saddlocate(char *text) {
|
||||
_Print((unsigned char*)text);
|
||||
_Print((unsigned char*)text);
|
||||
}
|
||||
|
||||
void sgoto(int x, int y) {
|
||||
_locate(x, y);
|
||||
_locate(x, y);
|
||||
}
|
||||
|
||||
void stextmini(int x, int y, char *text) {
|
||||
_PrintMiniSd(x, y, (unsigned char*)text, 0);
|
||||
_PrintMiniSd(x, y, (unsigned char*)text, 0);
|
||||
}
|
||||
|
||||
void gmessagebox(int height, char *message) {
|
||||
_DisplayMessageBox(height, (unsigned char*)message);
|
||||
}
|
||||
|
||||
/******* Tools *******/
|
||||
|
||||
/* Syscalls */
|
||||
|
||||
int _LongToAscHex(int value, char *dest, int digits);
|
||||
|
||||
/* Microfx */
|
||||
|
||||
void itohex(char *buffer, int value, int len) {
|
||||
_LongToAscHex(value, buffer, len);
|
||||
}
|
||||
|
||||
/******* CPU *******/
|
||||
|
||||
/* Microfx */
|
||||
|
||||
void csleep(void) {
|
||||
__asm__("sleep");
|
||||
char* sgetvram(void) {
|
||||
return _GetVRAMAddress();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
#include "../../../include/microfx/ext/gametools.h"
|
||||
|
||||
int vget_tile_at_point(MMap *map, int x, int y) {
|
||||
/* tx and ty contain the tile position. */
|
||||
int tx = x/map->tw, ty = y/map->th;
|
||||
if(tx>=0 && tx < map->w && ty>=0 && ty < map->h){
|
||||
return (int)map->map[ty*map->w+tx];
|
||||
}
|
||||
return -1;
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
#include "../../../include/microfx/ext/gametools.h"
|
||||
#include "../../../include/microfx/ext/img.h"
|
||||
#include "../../../include/microfx/microfx.h"
|
||||
|
||||
void vmap(int sx, int sy, MMap *map) {
|
||||
/* Dessine la map à l'écran. */
|
||||
int padx = map->padx, pady = map->pady;
|
||||
int w = map->sw, h = map->sh;
|
||||
/* x and y will contain the position in the loop. */
|
||||
int x, y;
|
||||
/* The positions where we start drawing the tiles will be in tx and ty. */
|
||||
int tx, ty;
|
||||
/* mx and my will contain how many pixels will be hidden on x and on y. */
|
||||
int mx, my;
|
||||
/* dw and dh contain the amount of tiles that will be drawn on x and on y.
|
||||
*/
|
||||
int dw = w/map->tw+1, dh = h/map->th+1;
|
||||
/* mw and mh will contain the height and the width of the map. */
|
||||
int mw = map->w*map->tw, mh = map->h*map->th;
|
||||
/* tile contains the tile to draw. */
|
||||
unsigned char tile;
|
||||
/* Fix sx. */
|
||||
if(sx<w/2){
|
||||
/* If I can't center the player because I'm near the left border of the
|
||||
map. */
|
||||
map->px = sx;
|
||||
sx = 0;
|
||||
}else if(sx+w/2>mw){
|
||||
/* If I can't center the player because I'm near the right border of the
|
||||
map. */
|
||||
map->px = sx-(mw-w);
|
||||
sx = mw-w;
|
||||
}else{
|
||||
/* I can center the player. */
|
||||
sx = sx-w/2;
|
||||
map->px = w/2;
|
||||
}
|
||||
/* Fix sy. */
|
||||
if(sy<h/2){
|
||||
/* If I can't center the player because I'm near the top border of the
|
||||
map. */
|
||||
map->py = sy;
|
||||
sy = 0;
|
||||
}else if(sy+h/2>mh){
|
||||
/* If I can't center the player because I'm near the bottom border of
|
||||
the map. */
|
||||
map->py = sy-(mh-h);
|
||||
sy = mh-h;
|
||||
}else{
|
||||
/* I can center the player. */
|
||||
sy = sy-h/2;
|
||||
map->py = h/2;
|
||||
}
|
||||
tx = sx/map->tw;
|
||||
ty = sy/map->th;
|
||||
mx = sx-tx*map->tw;
|
||||
my = sy-ty*map->th;
|
||||
for(y=0;y<dh;y++){
|
||||
for(x=0;x<dw;x++){
|
||||
/* I get the tile number if his position is inside the map unsigned
|
||||
char*. Then I draw it. */
|
||||
if(tx+x>=0 && tx+x < map->w && ty+y>=0 && ty+y < map->h){
|
||||
tile = map->map[(ty+y)*map->w+tx+x];
|
||||
if(tile > 0){
|
||||
simage(x*map->tw-mx+padx, y*map->th-my+pady, map->tw,
|
||||
map->th, map->tileset[(int)tile-1], SNORMAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
map->sx = sx;
|
||||
map->sy = sy;
|
||||
map->sw = w;
|
||||
map->sh = h;
|
||||
map->padx = padx;
|
||||
map->pady = pady;
|
||||
}
|
||||
|
||||
void vplayer(MMap *map, unsigned char **player_sprites, int anim_frame) {
|
||||
simage(map->px-map->pw/2, map->py-map->ph/2, map->pw, map->ph,
|
||||
player_sprites[anim_frame], SNORMAL);
|
||||
}
|
||||
|
||||
void vitem(MMap *map, int x, int y, int w, int h, unsigned char **item,
|
||||
int anim_frame) {
|
||||
int dx = x-map->sx, dy = y-map->sy;
|
||||
if(dx+w>=0 && dx<map->sw && dy+h>=0 && dy<map->sh) {
|
||||
simage(dx, dy, w, h, item[anim_frame], SNORMAL);
|
||||
}
|
||||
}
|
|
@ -2,28 +2,28 @@
|
|||
#include "../../include/microfx/microfx.h"
|
||||
|
||||
void simage(int sx, int sy, int w, int h, unsigned char *img, int mode) {
|
||||
/* Draws an image from a sprite coder string */
|
||||
int x, y, rpos, gpos, bpos, color;
|
||||
for(y=0;y<h;y++){
|
||||
for(x=0;x<w;x++){
|
||||
rpos = y*(w+(w%2))+x;
|
||||
gpos = rpos/8;
|
||||
bpos = rpos%8;
|
||||
color = (img[gpos] << bpos) & 0x80;
|
||||
switch(mode){
|
||||
case STRANSP:
|
||||
if(color) spixel(sx+x, sy+y, SWHITE);
|
||||
break;
|
||||
case SNOWHITE:
|
||||
if(color) spixel(sx+x, sy+y, SBLACK);
|
||||
break;
|
||||
case SNOBLACK:
|
||||
if(!color) spixel(sx+x, sy+y, SWHITE);
|
||||
break;
|
||||
default: /* SNORMAL or SINVERTED */
|
||||
spixel(sx+x, sy+y, mode ? !color : color);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Draws an image from a sprite coder string */
|
||||
int x, y, rpos, gpos, bpos, color;
|
||||
for(y=0;y<h;y++){
|
||||
for(x=0;x<w;x++){
|
||||
rpos = y*(w+(w%2))+x;
|
||||
gpos = rpos/8;
|
||||
bpos = rpos%8;
|
||||
color = (img[gpos] << bpos) & 0x80;
|
||||
switch(mode){
|
||||
case STRANSP:
|
||||
if(color) spixel(sx+x, sy+y, SWHITE);
|
||||
break;
|
||||
case SNOWHITE:
|
||||
if(color) spixel(sx+x, sy+y, SBLACK);
|
||||
break;
|
||||
case SNOBLACK:
|
||||
if(!color) spixel(sx+x, sy+y, SWHITE);
|
||||
break;
|
||||
default: /* SNORMAL or SINVERTED */
|
||||
spixel(sx+x, sy+y, mode ? !color : color);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,32 +2,32 @@ ENTRY(_start)
|
|||
|
||||
MEMORY
|
||||
{
|
||||
rom (rx) : ORIGIN = 0x00300200, LENGTH = 512K
|
||||
ram (rw) : ORIGIN = 0x08100200, LENGTH = 20K
|
||||
rom (rx) : ORIGIN = 0x00300200, LENGTH = 512K
|
||||
ram (rw) : ORIGIN = 0x08100200, LENGTH = 20K
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.text : {
|
||||
*(.pretext)
|
||||
*(.text)
|
||||
} > rom
|
||||
.rodata : {
|
||||
*(.rodata)
|
||||
*(.rodata.str1.4)
|
||||
_romdata_start = . ;
|
||||
} > rom
|
||||
.bss : {
|
||||
_start_bss = . ;
|
||||
_bssdatasize = . ;
|
||||
LONG(0);
|
||||
*(.bss)
|
||||
*(COMMON)
|
||||
_end_bss = . ;
|
||||
} > ram
|
||||
.data : AT(_romdata_start) {
|
||||
_start_data = . ;
|
||||
*(.data)
|
||||
_end_data = . ;
|
||||
} > ram
|
||||
.text : {
|
||||
*(.pretext)
|
||||
*(.text)
|
||||
} > rom
|
||||
.rodata : {
|
||||
*(.rodata)
|
||||
*(.rodata.str1.4)
|
||||
_romdata_start = . ;
|
||||
} > rom
|
||||
.bss : {
|
||||
_start_bss = . ;
|
||||
_bssdatasize = . ;
|
||||
LONG(0);
|
||||
*(.bss)
|
||||
*(COMMON)
|
||||
_end_bss = . ;
|
||||
} > ram
|
||||
.data : AT(_romdata_start) {
|
||||
_start_data = . ;
|
||||
*(.data)
|
||||
_end_data = . ;
|
||||
} > ram
|
||||
}
|
||||
|
|
|
@ -7,17 +7,27 @@
|
|||
int _InputNumber(unsigned char *heading, int maxlen, int mode);
|
||||
int _InputString(unsigned char *buffer, unsigned char *heading, int maxlen);
|
||||
void _DisplayFKeyIcon(int FKeyPos, unsigned char *pBitmap);
|
||||
void _DisplayMessageBox(int height, unsigned char *message);
|
||||
void _PopupWin(int nlines);
|
||||
|
||||
/* Microfx */
|
||||
|
||||
int gnumask(char *message, int maxlen, int type) {
|
||||
return _InputNumber((unsigned char *)message, maxlen, type);
|
||||
return _InputNumber((unsigned char *)message, maxlen, type);
|
||||
}
|
||||
|
||||
void gstrask(char *buffer, char *message, int maxlen) {
|
||||
_InputString((unsigned char *)buffer, (unsigned char *)message, maxlen);
|
||||
_InputString((unsigned char *)buffer, (unsigned char *)message, maxlen);
|
||||
}
|
||||
|
||||
void gfkeyset(int pos, unsigned char *img) {
|
||||
_DisplayFKeyIcon(pos, img);
|
||||
_DisplayFKeyIcon(pos, img);
|
||||
}
|
||||
|
||||
void gmessagebox(int height, char *message) {
|
||||
_DisplayMessageBox(height, (unsigned char*)message);
|
||||
}
|
||||
|
||||
void gpopup(int hlines) {
|
||||
_PopupWin(hlines);
|
||||
}
|
||||
|
|
|
@ -10,33 +10,33 @@ int _Keyboard_PRGM_GetKey(unsigned char* buffer);
|
|||
/* Microfx */
|
||||
|
||||
int kisdown(void) {
|
||||
return _Keyboard_KeyDown();
|
||||
return _Keyboard_KeyDown();
|
||||
}
|
||||
|
||||
int kcheck(int key) {
|
||||
/* TODO : Compatibility with older calcs. */
|
||||
/* Get the column and the row of the key. */
|
||||
int row = key%10;
|
||||
int column = key/10 - 1;
|
||||
/* The bit that I will read in the KIUDATA
|
||||
register. */
|
||||
int column_pos = column + 8 * (row & 1);
|
||||
/* row_data will contain the data of the
|
||||
KIUDATA register that we need.
|
||||
keyboard_register contains the address of
|
||||
KIUDATA0. */
|
||||
unsigned short *keyboard_register = (unsigned short*)0xA44B0000;
|
||||
unsigned short row_data;
|
||||
/* Get KIUDATAx where x is row / 2 because two rows
|
||||
are stored in each KIUDATA register. */
|
||||
row_data = keyboard_register[row/2];
|
||||
/* Get the bit located at column. */
|
||||
return (row_data >> column_pos) & 1;
|
||||
/* TODO : Compatibility with older calcs. */
|
||||
/* Get the column and the row of the key. */
|
||||
int row = key%10;
|
||||
int column = key/10 - 1;
|
||||
/* The bit that I will read in the KIUDATA
|
||||
register. */
|
||||
int column_pos = column + 8 * (row & 1);
|
||||
/* row_data will contain the data of the
|
||||
KIUDATA register that we need.
|
||||
keyboard_register contains the address of
|
||||
KIUDATA0. */
|
||||
unsigned short *keyboard_register = (unsigned short*)0xA44B0000;
|
||||
unsigned short row_data;
|
||||
/* Get KIUDATAx where x is row / 2 because two rows
|
||||
are stored in each KIUDATA register. */
|
||||
row_data = keyboard_register[row/2];
|
||||
/* Get the bit located at column. */
|
||||
return (row_data >> column_pos) & 1;
|
||||
}
|
||||
|
||||
int kgetkey(void){
|
||||
/* Made a prgm like getkey in the same way as simlo described it. */
|
||||
unsigned char buffer[12];
|
||||
_Keyboard_PRGM_GetKey(buffer);
|
||||
return (buffer[1] & 0x0F) * 10 + ((buffer[2] & 0xF0 ) >> 4);
|
||||
/* Made a prgm like getkey in the same way as simlo described it. */
|
||||
unsigned char buffer[12];
|
||||
_Keyboard_PRGM_GetKey(buffer);
|
||||
return (buffer[1] & 0x0F) * 10 + ((buffer[2] & 0xF0 ) >> 4);
|
||||
}
|
||||
|
|
|
@ -19,57 +19,57 @@ int _Bfile_Size(int fd);
|
|||
extern int fugue;
|
||||
|
||||
int mfugue(void) {
|
||||
return fugue;
|
||||
return fugue;
|
||||
}
|
||||
|
||||
unsigned short int fname[PATHSIZELIMIT];
|
||||
|
||||
void _fixname(const char *filename) {
|
||||
int len, i;
|
||||
len = 0;
|
||||
/* Getting the lenght of the filename */
|
||||
while(filename[len] != '\0' && len < PATHSIZELIMIT){
|
||||
len++;
|
||||
}
|
||||
/* Clearing fname, the file name for Bfile. */
|
||||
for(i=0;i<PATHSIZELIMIT;i++){
|
||||
fname[i] = '\0';
|
||||
}
|
||||
/* Copying the start of a Bfile file name to fname */
|
||||
for(i=0;i<7;i++){
|
||||
fname[i] = fname_start[i];
|
||||
}
|
||||
/* Copying the file name to fname, slashs are also replaced by backslashs */
|
||||
for(i=0;i<len;i++){
|
||||
if(filename[i+1] != '/'){
|
||||
fname[i+7] = filename[i+1];
|
||||
}else{
|
||||
fname[i+7] = '\\';
|
||||
}
|
||||
}
|
||||
int len, i;
|
||||
len = 0;
|
||||
/* Getting the lenght of the filename */
|
||||
while(filename[len] != '\0' && len < PATHSIZELIMIT){
|
||||
len++;
|
||||
}
|
||||
/* Clearing fname, the file name for Bfile. */
|
||||
for(i=0;i<PATHSIZELIMIT;i++){
|
||||
fname[i] = '\0';
|
||||
}
|
||||
/* Copying the start of a Bfile file name to fname */
|
||||
for(i=0;i<7;i++){
|
||||
fname[i] = fname_start[i];
|
||||
}
|
||||
/* Copying the file name to fname, slashs are also replaced by backslashs */
|
||||
for(i=0;i<len;i++){
|
||||
if(filename[i+1] != '/'){
|
||||
fname[i+7] = filename[i+1];
|
||||
}else{
|
||||
fname[i+7] = '\\';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int mremove(const char *filename) {
|
||||
_fixname(filename);
|
||||
return _Bfile_DeleteEntry(fname);
|
||||
_fixname(filename);
|
||||
return _Bfile_DeleteEntry(fname);
|
||||
}
|
||||
|
||||
int mcreate(const char *filename, int type, int size) {
|
||||
int out;
|
||||
_fixname(filename);
|
||||
out = _Bfile_Create(fname, type, &size);
|
||||
return out;
|
||||
int out;
|
||||
_fixname(filename);
|
||||
out = _Bfile_Create(fname, type, &size);
|
||||
return out;
|
||||
}
|
||||
|
||||
MFile mopen(const char *filename, int mode) {
|
||||
MFile file;
|
||||
_fixname(filename);
|
||||
file.out = _Bfile_Open(fname, mode);
|
||||
_fixname(filename);
|
||||
file.out = _Bfile_Open(fname, mode);
|
||||
if(file.out > 0){
|
||||
file.fd = file.out;
|
||||
file.error = 0;
|
||||
file.fpos = 0;
|
||||
file.fwpos = 0;
|
||||
file.fwpos = 0;
|
||||
}else{
|
||||
file.error = 1;
|
||||
}
|
||||
|
@ -77,23 +77,23 @@ MFile mopen(const char *filename, int mode) {
|
|||
}
|
||||
|
||||
void mwrite(MFile *file, const void *data, int size) {
|
||||
/* Some checks to make the operation more secure. */
|
||||
if(!fugue && size%2){
|
||||
/* Some checks to make the operation more secure. */
|
||||
if(!fugue && size%2){
|
||||
file->error = MODDSIZEWRITE;
|
||||
file->out = 1;
|
||||
return;
|
||||
}
|
||||
msize(file);
|
||||
if(file->fwpos + size > file->out && !file->error){
|
||||
file->out = MTOOBIGSIZE;
|
||||
file->error = 1;
|
||||
return;
|
||||
}
|
||||
/* Calling the Bfile syscall and updating the MFile struct. */
|
||||
file->out = _Bfile_Write(file->fd, data, size);
|
||||
file->fpos += size;
|
||||
file->fwpos += size;
|
||||
if(file->out < 0){
|
||||
return;
|
||||
}
|
||||
msize(file);
|
||||
if(file->fwpos + size > file->out && !file->error){
|
||||
file->out = MTOOBIGSIZE;
|
||||
file->error = 1;
|
||||
return;
|
||||
}
|
||||
/* Calling the Bfile syscall and updating the MFile struct. */
|
||||
file->out = _Bfile_Write(file->fd, data, size);
|
||||
file->fpos += size;
|
||||
file->fwpos += size;
|
||||
if(file->out < 0){
|
||||
file->error = 1;
|
||||
}else{
|
||||
file->error = 0;
|
||||
|
@ -101,17 +101,17 @@ void mwrite(MFile *file, const void *data, int size) {
|
|||
}
|
||||
|
||||
void mread(MFile *file, void *data, int size, int whence) {
|
||||
/* Making an absolute position out of whence. */
|
||||
/* Making an absolute position out of whence. */
|
||||
if(whence == MRCONTINUE) whence = file->fpos;
|
||||
/* A check to make the operation more secure. */
|
||||
msize(file);
|
||||
if(whence + size > file->out && !file->error){
|
||||
file->out = MTOOBIGSIZE;
|
||||
file->error = 1;
|
||||
return;
|
||||
}
|
||||
/* Calling the Bfile syscall and updating the MFile struct. */
|
||||
file->out = _Bfile_Read(file->fd, data, size, whence);
|
||||
/* A check to make the operation more secure. */
|
||||
msize(file);
|
||||
if(whence + size > file->out && !file->error){
|
||||
file->out = MTOOBIGSIZE;
|
||||
file->error = 1;
|
||||
return;
|
||||
}
|
||||
/* Calling the Bfile syscall and updating the MFile struct. */
|
||||
file->out = _Bfile_Read(file->fd, data, size, whence);
|
||||
file->fpos += size;
|
||||
if(file->out < 0){
|
||||
file->error = 1;
|
||||
|
@ -121,8 +121,8 @@ void mread(MFile *file, void *data, int size, int whence) {
|
|||
}
|
||||
|
||||
void mclose(MFile *file) {
|
||||
/* Calling the Bfile syscall and updating the MFile struct. */
|
||||
file->out = _Bfile_Close(file->fd);
|
||||
/* Calling the Bfile syscall and updating the MFile struct. */
|
||||
file->out = _Bfile_Close(file->fd);
|
||||
if(file->out < 0){
|
||||
file->error = 1;
|
||||
}else{
|
||||
|
@ -131,17 +131,17 @@ void mclose(MFile *file) {
|
|||
}
|
||||
|
||||
void mseek(MFile *file, int pos) {
|
||||
/* Setting the new position whitout making checks because more informations
|
||||
are required to make checks, so they are made directly when doing operations
|
||||
on the file.
|
||||
error and out are set to 0 because no error can occur when doing this. */
|
||||
/* Setting the new position whitout making checks because more informations
|
||||
are required to make checks, so they are made directly when doing operations
|
||||
on the file.
|
||||
error and out are set to 0 because no error can occur when doing this. */
|
||||
file->fpos = pos;
|
||||
file->error = 0;
|
||||
file->out = 0;
|
||||
}
|
||||
|
||||
void msize(MFile *file) {
|
||||
/* Calling the Bfile syscall and updating the MFile struct. */
|
||||
/* Calling the Bfile syscall and updating the MFile struct. */
|
||||
file->out = _Bfile_Size(file->fd);
|
||||
if(file->out < 0){
|
||||
file->error = 1;
|
||||
|
|
|
@ -9,7 +9,7 @@ int _LongToAscHex(int value, char *dest, int digits);
|
|||
/* Microfx */
|
||||
|
||||
void itohex(char *buffer, int value, int len) {
|
||||
_LongToAscHex(value, buffer, len);
|
||||
_LongToAscHex(value, buffer, len);
|
||||
}
|
||||
|
||||
/******* CPU *******/
|
||||
|
@ -17,5 +17,5 @@ void itohex(char *buffer, int value, int len) {
|
|||
/* Microfx */
|
||||
|
||||
void csleep(void) {
|
||||
__asm__("sleep");
|
||||
__asm__("sleep");
|
||||
}
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
#include "../include/microfx/microfx.h"
|
||||
|
||||
void _RTC_GetTime(unsigned int *hour, unsigned int *minute,
|
||||
unsigned int *second, unsigned int *millisecond);
|
||||
|
||||
void rgettime(MRtc *rtc) {
|
||||
_RTC_GetTime((unsigned int *)&rtc->hour, (unsigned int *)&rtc->minute,
|
||||
(unsigned int *)&rtc->second, (unsigned int *)&rtc->millisecond);
|
||||
}
|
|
@ -17,28 +17,28 @@ int fugue;
|
|||
__attribute__((section(".pretext")))
|
||||
|
||||
int start(void) {
|
||||
int i;
|
||||
char *bss_startptr, *data_startptr, *romdataptr;
|
||||
char *os_version = (void *)0x80010020;
|
||||
/* Clearing the bss. */
|
||||
bss_startptr = &start_bss;
|
||||
for(i=0;i<&end_bss - &start_bss;i++){
|
||||
bss_startptr[i] = 0;
|
||||
}
|
||||
/* Load the ROM data into the RAM. */
|
||||
data_startptr = &start_data;
|
||||
romdataptr = &romdata_start;
|
||||
for(i=0;i<&end_data - &start_data;i++){
|
||||
data_startptr[i] = romdataptr[i];
|
||||
}
|
||||
/* Checking if the calculator has a fugue filesystem, because it is
|
||||
important to know that when using Bfile. */
|
||||
if(os_version[1] == '3'){
|
||||
fugue = 1;
|
||||
}else{
|
||||
fugue = 0;
|
||||
}
|
||||
/* Calling main. The return value of main is directly returned because no
|
||||
modifications need to be made. */
|
||||
return main();
|
||||
int i;
|
||||
char *bss_startptr, *data_startptr, *romdataptr;
|
||||
char *os_version = (void *)0x80010020;
|
||||
/* Clearing the bss. */
|
||||
bss_startptr = &start_bss;
|
||||
for(i=0;i<&end_bss - &start_bss;i++){
|
||||
bss_startptr[i] = 0;
|
||||
}
|
||||
/* Load the ROM data into the RAM. */
|
||||
data_startptr = &start_data;
|
||||
romdataptr = &romdata_start;
|
||||
for(i=0;i<&end_data - &start_data;i++){
|
||||
data_startptr[i] = romdataptr[i];
|
||||
}
|
||||
/* Checking if the calculator has a fugue filesystem, because it is
|
||||
important to know that when using Bfile. */
|
||||
if(os_version[1] == '3'){
|
||||
fugue = 1;
|
||||
}else{
|
||||
fugue = 0;
|
||||
}
|
||||
/* Calling main. The return value of main is directly returned because no
|
||||
modifications need to be made. */
|
||||
return main();
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
.text
|
||||
|
||||
/* Screen */
|
||||
.global __Bdisp_PutDisp_DD
|
||||
.global __Bdisp_DrawRectangle
|
||||
.global __Bdisp_AllClr_VRAM
|
||||
|
@ -12,6 +13,7 @@
|
|||
.global __Bdisp_ClearLineVRAM
|
||||
.global __PrintMiniSd
|
||||
.global __DisplayMessageBox
|
||||
.global __GetVRAMAddress
|
||||
/* Keyboard */
|
||||
.global __Keyboard_KeyDown
|
||||
.global __Keyboard_PRGM_GetKey
|
||||
|
@ -24,6 +26,8 @@
|
|||
.global __Timer_Deinstall
|
||||
.global __Timer_Start
|
||||
.global __Timer_Stop
|
||||
/* RTC */
|
||||
.global __RTC_GetTime
|
||||
/* Files */
|
||||
.global __Bfile_DeleteEntry
|
||||
.global __Bfile_Create
|
||||
|
@ -57,125 +61,133 @@
|
|||
.global __InputNumber
|
||||
.global __InputString
|
||||
.global __DisplayFKeyIcon
|
||||
.global __PopupWin
|
||||
|
||||
#define syscall(syscall_number) \
|
||||
mov.l 1f, r0 ;\
|
||||
mov.l do_syscall, r2 ;\
|
||||
jmp @r2 ;\
|
||||
nop ;\
|
||||
mov.l 1f, r0 ;\
|
||||
mov.l do_syscall, r2 ;\
|
||||
jmp @r2 ;\
|
||||
nop ;\
|
||||
.align 4 ;\
|
||||
1: .long syscall_number
|
||||
1: .long syscall_number
|
||||
|
||||
/* Display */
|
||||
__Bdisp_PutDisp_DD:
|
||||
syscall(0x028)
|
||||
syscall(0x028)
|
||||
__Bdisp_DrawRectangle:
|
||||
syscall(0x0763)
|
||||
syscall(0x0763)
|
||||
__Bdisp_AllClr_VRAM:
|
||||
syscall(0x143)
|
||||
syscall(0x143)
|
||||
__Bdisp_SetPoint_VRAM:
|
||||
syscall(0x146)
|
||||
syscall(0x146)
|
||||
__Bdisp_GetPoint_VRAM:
|
||||
syscall(0x149)
|
||||
syscall(0x149)
|
||||
__PrintXY:
|
||||
syscall(0x150)
|
||||
syscall(0x150)
|
||||
__locate:
|
||||
syscall(0x807)
|
||||
syscall(0x807)
|
||||
__Print:
|
||||
syscall(0x808)
|
||||
syscall(0x808)
|
||||
__Bdisp_DrawLineVRAM:
|
||||
syscall(0x030)
|
||||
syscall(0x030)
|
||||
__Bdisp_ClearLineVRAM:
|
||||
syscall(0x031)
|
||||
syscall(0x031)
|
||||
__PrintMiniSd:
|
||||
syscall(0xC4F)
|
||||
syscall(0xC4F)
|
||||
__DisplayMessageBox:
|
||||
syscall(0x0901)
|
||||
syscall(0x0901)
|
||||
__GetVRAMAddress:
|
||||
syscall(0x135)
|
||||
/* Keyboard */
|
||||
__Keyboard_KeyDown:
|
||||
syscall(0x24D)
|
||||
syscall(0x24D)
|
||||
__Keyboard_PRGM_GetKey:
|
||||
syscall(0x6C4)
|
||||
syscall(0x6C4)
|
||||
/* Time */
|
||||
__Sleep:
|
||||
syscall(0x0420)
|
||||
syscall(0x0420)
|
||||
__RTC_GetTicks:
|
||||
syscall(0x03B)
|
||||
syscall(0x03B)
|
||||
__RTC_Elapsed_ms:
|
||||
syscall(0x03C)
|
||||
syscall(0x03C)
|
||||
__RTC_Reset:
|
||||
syscall(0x039)
|
||||
syscall(0x039)
|
||||
__Timer_Install:
|
||||
syscall(0x0118)
|
||||
syscall(0x0118)
|
||||
__Timer_Deinstall:
|
||||
syscall(0x0119)
|
||||
syscall(0x0119)
|
||||
__Timer_Start:
|
||||
syscall(0x011A)
|
||||
syscall(0x011A)
|
||||
__Timer_Stop:
|
||||
syscall(0x011B)
|
||||
syscall(0x011B)
|
||||
/* RTC */
|
||||
__RTC_GetTime:
|
||||
syscall(0x03A)
|
||||
/* Files */
|
||||
__Bfile_DeleteEntry:
|
||||
mov #0, r5
|
||||
syscall(0x0439)
|
||||
mov #0, r5
|
||||
syscall(0x0439)
|
||||
__Bfile_Create:
|
||||
syscall(0x434)
|
||||
syscall(0x434)
|
||||
__Bfile_Write:
|
||||
syscall(0x435)
|
||||
syscall(0x435)
|
||||
__Bfile_Open:
|
||||
mov #0, r6
|
||||
syscall(0x42C)
|
||||
mov #0, r6
|
||||
syscall(0x42C)
|
||||
__Bfile_Read:
|
||||
syscall(0x432)
|
||||
syscall(0x432)
|
||||
__Bfile_Close:
|
||||
syscall(0x042D)
|
||||
syscall(0x042D)
|
||||
__Bfile_Size:
|
||||
syscall(0x042F)
|
||||
syscall(0x042F)
|
||||
/* Tools */
|
||||
_itoa:
|
||||
syscall(0x541)
|
||||
syscall(0x541)
|
||||
_malloc:
|
||||
syscall(0xACD)
|
||||
syscall(0xACD)
|
||||
_calloc:
|
||||
syscall(0xE6B)
|
||||
syscall(0xE6B)
|
||||
_realloc:
|
||||
syscall(0xE6D)
|
||||
syscall(0xE6D)
|
||||
_free:
|
||||
syscall(0xACC)
|
||||
syscall(0xACC)
|
||||
__LongToAscHex:
|
||||
syscall(0x467)
|
||||
syscall(0x467)
|
||||
_memcmp:
|
||||
syscall(0xACE)
|
||||
syscall(0xACE)
|
||||
_memcpy:
|
||||
syscall(0xACF)
|
||||
syscall(0xACF)
|
||||
_memset:
|
||||
syscall(0xAD0)
|
||||
syscall(0xAD0)
|
||||
_strcat:
|
||||
syscall(0xAD4)
|
||||
syscall(0xAD4)
|
||||
_strcmp:
|
||||
syscall(0xAD5)
|
||||
syscall(0xAD5)
|
||||
_strlen:
|
||||
syscall(0xAD6)
|
||||
syscall(0xAD6)
|
||||
_strncat:
|
||||
syscall(0xAD7)
|
||||
syscall(0xAD7)
|
||||
_strncmp:
|
||||
syscall(0xAD8)
|
||||
syscall(0xAD8)
|
||||
_strncpy:
|
||||
syscall(0xAD9)
|
||||
syscall(0xAD9)
|
||||
_strrchr:
|
||||
syscall(0xADA)
|
||||
syscall(0xADA)
|
||||
_strchr:
|
||||
syscall(0xE6E)
|
||||
syscall(0xE6E)
|
||||
_strstr:
|
||||
syscall(0xE6F)
|
||||
syscall(0xE6F)
|
||||
_memmove:
|
||||
syscall(0xE6C)
|
||||
syscall(0xE6C)
|
||||
/* GUI */
|
||||
__InputNumber:
|
||||
syscall(0x0CC4)
|
||||
syscall(0x0CC4)
|
||||
__InputString:
|
||||
syscall(0x0CC5)
|
||||
syscall(0x0CC5)
|
||||
__DisplayFKeyIcon:
|
||||
syscall(0x04D1)
|
||||
syscall(0x04D1)
|
||||
__PopupWin:
|
||||
syscall(0x08FE)
|
||||
/* Menu */
|
||||
/* Nothing here ... */
|
||||
|
||||
|
|
|
@ -17,33 +17,33 @@ int _Timer_Stop(int InternalTimerID);
|
|||
/* Microfx */
|
||||
|
||||
void tsleep_ms(int ms) {
|
||||
_Sleep(ms);
|
||||
_Sleep(ms);
|
||||
}
|
||||
|
||||
int tgetticks(void) {
|
||||
return _RTC_GetTicks();
|
||||
return _RTC_GetTicks();
|
||||
}
|
||||
|
||||
int tiselapsed(int start, int ms) {
|
||||
return _RTC_Elapsed_ms(start, ms);
|
||||
return _RTC_Elapsed_ms(start, ms);
|
||||
}
|
||||
|
||||
void treset(void) {
|
||||
_RTC_Reset(1);
|
||||
_RTC_Reset(1);
|
||||
}
|
||||
|
||||
int tinittimer(int ms, void (*callback)(void)) {
|
||||
return _Timer_Install(0, callback, ms);
|
||||
return _Timer_Install(0, callback, ms);
|
||||
}
|
||||
|
||||
void tfreetimer(int id) {
|
||||
_Timer_Deinstall(id);
|
||||
_Timer_Deinstall(id);
|
||||
}
|
||||
|
||||
void tstarttimer(int id) {
|
||||
_Timer_Start(id);
|
||||
_Timer_Start(id);
|
||||
}
|
||||
|
||||
void tstoptimer(int id) {
|
||||
_Timer_Stop(id);
|
||||
_Timer_Stop(id);
|
||||
}
|
||||
|
|
|
@ -2,32 +2,32 @@ ENTRY(_start)
|
|||
|
||||
MEMORY
|
||||
{
|
||||
rom (rx) : ORIGIN = 0x00300200, LENGTH = 512K
|
||||
ram (rw) : ORIGIN = 0x08100200, LENGTH = 20K
|
||||
rom (rx) : ORIGIN = 0x00300200, LENGTH = 512K
|
||||
ram (rw) : ORIGIN = 0x08100200, LENGTH = 20K
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.text : {
|
||||
*(.pretext)
|
||||
*(.text)
|
||||
} > rom
|
||||
.rodata : {
|
||||
*(.rodata)
|
||||
*(.rodata.str1.4)
|
||||
_romdata_start = . ;
|
||||
} > rom
|
||||
.bss : {
|
||||
_start_bss = . ;
|
||||
_bssdatasize = . ;
|
||||
LONG(0);
|
||||
*(.bss)
|
||||
*(COMMON)
|
||||
_end_bss = . ;
|
||||
} > ram
|
||||
.data : AT(_romdata_start) {
|
||||
_start_data = . ;
|
||||
*(.data)
|
||||
_end_data = . ;
|
||||
} > ram
|
||||
.text : {
|
||||
*(.pretext)
|
||||
*(.text)
|
||||
} > rom
|
||||
.rodata : {
|
||||
*(.rodata)
|
||||
*(.rodata.str1.4)
|
||||
_romdata_start = . ;
|
||||
} > rom
|
||||
.bss : {
|
||||
_start_bss = . ;
|
||||
_bssdatasize = . ;
|
||||
LONG(0);
|
||||
*(.bss)
|
||||
*(COMMON)
|
||||
_end_bss = . ;
|
||||
} > ram
|
||||
.data : AT(_romdata_start) {
|
||||
_start_data = . ;
|
||||
*(.data)
|
||||
_end_data = . ;
|
||||
} > ram
|
||||
}
|
||||
|
|
|
@ -90,6 +90,13 @@ Works like stext, but here the font is PrintMini and you cannot set the color.
|
|||
|
||||
void stextmini(int x, int y, char *text);
|
||||
|
||||
/* char* sgetvram(void);
|
||||
|
||||
Get the address of the VRAM.
|
||||
*/
|
||||
|
||||
char* sgetvram(void);
|
||||
|
||||
/******* KEYBOARD *******/
|
||||
|
||||
/* int kisdown(void);
|
||||
|
@ -219,6 +226,20 @@ Stop the timer id.
|
|||
|
||||
void tstoptimer(int id);
|
||||
|
||||
/******* RTC *******/
|
||||
|
||||
typedef struct {
|
||||
int year, month, day; /* The current date (unused) */
|
||||
int hour, minute, second, millisecond; /* The current time */
|
||||
} MRtc;
|
||||
|
||||
/* void rgettime(MRtc *rtc);
|
||||
|
||||
Puts the current hour, minute, second and millisecond in the rtc Mrtc struct.
|
||||
*/
|
||||
|
||||
void rgettime(MRtc *rtc);
|
||||
|
||||
/******* CPU *******/
|
||||
|
||||
/* void csleep(void);
|
||||
|
@ -252,7 +273,7 @@ input.
|
|||
|
||||
void gstrask(char *buffer, char *message, int maxlen);
|
||||
|
||||
/* void simage(int sx, int sy, int w, int h, unsigned char *img, int mode);
|
||||
/* void gfkeyset(int pos, unsigned char *img);
|
||||
|
||||
Draws an fkey from a Sprite Coder string that is in img, at fkey position pos.
|
||||
*/
|
||||
|
@ -266,6 +287,13 @@ Draws a message box of height height with that contains message.
|
|||
|
||||
void gmessagebox(int height, char *message);
|
||||
|
||||
/* void gpopup(int hlines);
|
||||
|
||||
Draws a popup that has a height of hlines lines.
|
||||
*/
|
||||
|
||||
void gpopup(int hlines);
|
||||
|
||||
/******* Memory *******/
|
||||
|
||||
/* File structure */
|
||||
|
|
Binary file not shown.
|
@ -1,16 +1,16 @@
|
|||
#include <microfx/microfx.h>
|
||||
|
||||
int main(void) {
|
||||
while(kisdown());
|
||||
/* Clear the screen */
|
||||
sclear();
|
||||
stext(1, 1, "A Microfx Add-in !", SBLACK);
|
||||
/* Update the screen */
|
||||
supdate();
|
||||
/* Waits that the user presses EXIT. */
|
||||
int key = 0;
|
||||
while(key != KCEXIT){
|
||||
key = kgetkey();
|
||||
}
|
||||
return 1;
|
||||
while(kisdown());
|
||||
/* Clear the screen */
|
||||
sclear();
|
||||
stext(1, 1, "A Microfx Add-in !", SBLACK);
|
||||
/* Update the screen */
|
||||
supdate();
|
||||
/* Waits that the user presses EXIT. */
|
||||
int key = 0;
|
||||
while(key != KCEXIT){
|
||||
key = kgetkey();
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
NAME = mapconv
|
||||
|
||||
SRC = src/main.c \
|
||||
src/parse.c
|
||||
OBJ = $(SRC:src/%=build/%.o)
|
||||
|
||||
BUILD = build
|
||||
|
||||
CFLAGS = -Wall -Wextra -Wpedantic
|
||||
|
||||
all: $(OBJ)
|
||||
$(CC) $(OBJ) -o $(NAME)
|
||||
|
||||
$(BUILD)/%.o: src/% | $(BUILD)/
|
||||
$(CC) -c $< -o $@ -Os -Iinc -std=c89 $(CFLAGS)
|
||||
|
||||
.PRECIOUS: %/
|
||||
|
||||
%/:
|
||||
@ mkdir -p $@
|
||||
|
||||
clean: $(BUILD)
|
||||
rm $(BUILD) --recursive
|
||||
rm $(NAME)
|
|
@ -0,0 +1,12 @@
|
|||
#ifndef HELP_H
|
||||
#define HELP_H
|
||||
|
||||
/* TODO: Explain how to write a config.txt file. */
|
||||
|
||||
const char help[] = "mapconv - Microfx map creator\n\n"
|
||||
"This little tool makes it easier to create maps for the Microfx gametools ext."
|
||||
"\n"
|
||||
"Use :\n"
|
||||
" mapconv conf.txt\n";
|
||||
|
||||
#endif
|
|
@ -0,0 +1,31 @@
|
|||
#ifndef PARSE_H
|
||||
#define PARSE_H
|
||||
|
||||
#define TOKEN_SZ 64
|
||||
|
||||
typedef enum {
|
||||
T_GROUP,
|
||||
T_NAME,
|
||||
T_CHAR,
|
||||
T_STRING,
|
||||
T_INT
|
||||
} Token;
|
||||
|
||||
typedef struct {
|
||||
Token token;
|
||||
char content[TOKEN_SZ];
|
||||
} Tokendata;
|
||||
|
||||
typedef enum {
|
||||
FALSE,
|
||||
TRUE
|
||||
} bool;
|
||||
|
||||
int parse(char *content, Tokendata **data);
|
||||
int search_token(Token token, char *content, Tokendata *tokens, int token_d_sz);
|
||||
int get_value_from_name(Token value_type, char *value, Tokendata *tokens,
|
||||
int token_d_sz);
|
||||
int get_value_from_name_noerror(Token value_type, char *value,
|
||||
Tokendata *tokens, int token_d_sz);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,154 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <help.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include <parse.h>
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
FILE *fp;
|
||||
FILE *fp_map;
|
||||
size_t size;
|
||||
char tiles[256];
|
||||
int i, a, len, out;
|
||||
int w, h, pw, ph, tw, th, padx, pady, dw, dh;
|
||||
bool found;
|
||||
Tokendata *tokens = NULL;
|
||||
char buffer[TOKEN_SZ], c;
|
||||
char *data = NULL;
|
||||
int amount;
|
||||
if(argc < 2){
|
||||
puts(help);
|
||||
return 1;
|
||||
}
|
||||
/* Loading config */
|
||||
fp = fopen(argv[1], "rb");
|
||||
if(fp == NULL){
|
||||
printf("[mapconv] Can't open \"%s\"\n", argv[1]);
|
||||
return 2;
|
||||
}
|
||||
fseek(fp, 0L, SEEK_END);
|
||||
size = ftell(fp);
|
||||
rewind(fp);
|
||||
data = malloc(sizeof(unsigned char) * size);
|
||||
if(data == NULL){
|
||||
puts("[mapconv] More memory needed!");
|
||||
return 3;
|
||||
}
|
||||
if(!fread(data, 1, sizeof(unsigned char) * size, fp)){
|
||||
fclose(fp);
|
||||
return 4;
|
||||
}
|
||||
fclose(fp);
|
||||
puts("[status] Parsing config ...");
|
||||
out = parse(data, &tokens);
|
||||
if(out < 0){
|
||||
puts("[mapconv] Error when parsing config!");
|
||||
return -1;
|
||||
}
|
||||
puts("[status] Parsing config successful!");
|
||||
/* TODO the following lines are really dirty */
|
||||
/* Get the width and the height */
|
||||
i=get_value_from_name(T_INT, "width", tokens, out);
|
||||
w = atoi(tokens[i].content);
|
||||
i=get_value_from_name(T_INT, "height", tokens, out);
|
||||
h=atoi(tokens[i].content);
|
||||
len=0;
|
||||
puts("[status] Getting tile numbers.");
|
||||
for(i=0;i<256;i++){
|
||||
sprintf(buffer, "t%d", i);
|
||||
a = get_value_from_name_noerror(T_CHAR, buffer, tokens, out);
|
||||
if(a<0) break;
|
||||
tiles[i] = tokens[a].content[0];
|
||||
len++;
|
||||
}
|
||||
free(data);
|
||||
/* Make the map */
|
||||
puts("[status] Reading map.");
|
||||
i=get_value_from_name(T_STRING, "input", tokens, out);
|
||||
fp = fopen(tokens[i].content, "rb");
|
||||
if(fp == NULL){
|
||||
printf("[mapconv] Can't open \"%s\"\n", tokens[i].content);
|
||||
return 2;
|
||||
}
|
||||
fseek(fp, 0L, SEEK_END);
|
||||
size = ftell(fp);
|
||||
rewind(fp);
|
||||
data = malloc(sizeof(unsigned char) * size);
|
||||
if(data == NULL){
|
||||
puts("[mapconv] More memory needed!");
|
||||
return 3;
|
||||
}
|
||||
if(!fread(data, 1, sizeof(unsigned char) * size, fp)){
|
||||
fclose(fp);
|
||||
return 4;
|
||||
}
|
||||
fclose(fp);
|
||||
i=get_value_from_name(T_STRING, "output", tokens, out);
|
||||
fp_map = fopen(tokens[i].content, "w");
|
||||
if(fp == NULL){
|
||||
printf("[mapconv] Can't open \"%s\"\n", tokens[i].content);
|
||||
return 2;
|
||||
}
|
||||
a=get_value_from_name(T_STRING, "mapname", tokens, out);
|
||||
for(i=0;i<(int)strlen(tokens[a].content);i++){
|
||||
c = tokens[a].content[i];
|
||||
if((c >= 0x30 && c <= 0x39) || (c >= 0x41 && c <= 0x5A) ||
|
||||
(c >= 0x61 && c <= 0x7A)){
|
||||
buffer[i] = toupper(c);
|
||||
}else{
|
||||
buffer[i] = '_';
|
||||
}
|
||||
}
|
||||
puts("[status] Generating header.");
|
||||
i=get_value_from_name(T_STRING, "tileset_header", tokens, out);
|
||||
fprintf(fp_map, "#ifndef %s_H\n#define %s_H\n\n#include <%s>\n"
|
||||
"#include <microfx/ext/gametools.h>\n\nconst unsigned char _%s[] = {",
|
||||
buffer, buffer, tokens[i].content, tokens[a].content);
|
||||
amount = 0;
|
||||
for(i=0;i<(int)size;i++){
|
||||
if(data[i] != '\n'){
|
||||
found = FALSE;
|
||||
for(a=0;a<len;a++){
|
||||
if(tiles[a] == data[i]){
|
||||
fprintf(fp_map, "%d, ", a);
|
||||
found = TRUE;
|
||||
amount++;
|
||||
}
|
||||
}
|
||||
if(!found){
|
||||
printf("[mapconv] Tile number of '%c' not found\n", data[i]);
|
||||
return 5;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(amount!=w*h){
|
||||
printf("[warning] %d tiles written instead of %d*%d=%d\n", amount, w, h,
|
||||
w*h);
|
||||
}
|
||||
fseek(fp_map, -2L, SEEK_CUR);
|
||||
fputs("};", fp_map);
|
||||
a=get_value_from_name(T_STRING, "mapname", tokens, out);
|
||||
i=get_value_from_name(T_STRING, "tileset_name", tokens, out);
|
||||
tw=get_value_from_name(T_INT, "tilewidth", tokens, out);
|
||||
th=get_value_from_name(T_INT, "tileheight", tokens, out);
|
||||
pw=get_value_from_name(T_INT, "playerwidth", tokens, out);
|
||||
ph=get_value_from_name(T_INT, "playerheight", tokens, out);
|
||||
padx=get_value_from_name(T_INT, "drawingzone_x", tokens, out);
|
||||
pady=get_value_from_name(T_INT, "drawingzone_y", tokens, out);
|
||||
dw=get_value_from_name(T_INT, "drawingzone_w", tokens, out);
|
||||
dh=get_value_from_name(T_INT, "drawingzone_h", tokens, out);
|
||||
fprintf(fp_map, "\n\nMMap %s = {(unsigned char *)_%s, (unsigned char **)"
|
||||
"%s, %d, %d, %s, %s, 0, 0, %s, %s, 0, 0, %s, %s, %s, %s};\n\n#endif\n",
|
||||
tokens[a].content, tokens[a].content, tokens[i].content, w, h,
|
||||
tokens[tw].content, tokens[th].content, tokens[pw].content,
|
||||
tokens[ph].content, tokens[padx].content, tokens[pady].content,
|
||||
tokens[dw].content, tokens[dh].content);
|
||||
/* TODO end */
|
||||
fclose(fp_map);
|
||||
free(data);
|
||||
puts("[status] Generating done! You can now use the generated header "
|
||||
"file.");
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,120 @@
|
|||
#include <parse.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
int parse(char *content, Tokendata **data) {
|
||||
int i, current_token_pos = 0;
|
||||
bool token_started = FALSE;
|
||||
char c;
|
||||
char current_token[TOKEN_SZ];
|
||||
Token current_token_type;
|
||||
int token_num = 0;
|
||||
for(i=0;i<(int)strlen(content);i++){
|
||||
c = content[i];
|
||||
if(!token_started && c != ' '){
|
||||
token_started = TRUE;
|
||||
switch(c){
|
||||
case '\'':
|
||||
current_token_type = T_CHAR;
|
||||
break;
|
||||
case '"':
|
||||
current_token_type = T_STRING;
|
||||
break;
|
||||
case '-':
|
||||
current_token_type = T_GROUP;
|
||||
break;
|
||||
default:
|
||||
current_token_type = T_NAME;
|
||||
}
|
||||
if(c >= 0x30 && c <= 0x39){
|
||||
current_token_type = T_INT;
|
||||
}
|
||||
}
|
||||
if(token_started){
|
||||
if(c != ' ' || (current_token_type == T_STRING ||
|
||||
current_token_type == T_CHAR)){
|
||||
/* TODO : the following condition should be changed, to allow
|
||||
'"', '\'' and '-' in chars, strings, names, groups ... */
|
||||
if(current_token_pos < TOKEN_SZ && (c != '"' && c != '\'' &&
|
||||
c != '=' && c != '-' && c != '\n')){
|
||||
current_token[current_token_pos] = c;
|
||||
current_token_pos++;
|
||||
}else if(current_token_pos >= TOKEN_SZ){
|
||||
puts("[config] Too big token !");
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
if(((c == '=' && current_token_type == T_NAME) ||
|
||||
c == '\n') && strlen(current_token) > 0){
|
||||
(*data) = realloc((*data), (token_num+1)*sizeof(Tokendata));
|
||||
if(!(*data)){
|
||||
puts("[config] More memory needed !");
|
||||
return -1;
|
||||
}
|
||||
(*data)[token_num].token = current_token_type;
|
||||
strcpy((*data)[token_num].content, current_token);
|
||||
memset(current_token, '\0', TOKEN_SZ);
|
||||
current_token_pos = 0;
|
||||
token_started = FALSE;
|
||||
token_num++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(current_token_pos > 0){
|
||||
(*data) = realloc((*data), (token_num+1)*sizeof(Tokendata));
|
||||
if(!(*data)){
|
||||
puts("[config] More memory needed !");
|
||||
return -1;
|
||||
}
|
||||
(*data)[token_num].token = current_token_type;
|
||||
strcpy((*data)[token_num].content, current_token);
|
||||
}
|
||||
return token_num;
|
||||
}
|
||||
|
||||
int search_token(Token token, char *content, Tokendata *tokens,
|
||||
int token_d_sz) {
|
||||
int i;
|
||||
for(i=0;i<token_d_sz;i++){
|
||||
if(tokens[i].token == token && !strcmp(tokens[i].content, content)){
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int get_value_from_name(Token value_type, char *value, Tokendata *tokens,
|
||||
int token_d_sz) {
|
||||
int i;
|
||||
i=search_token(T_NAME, value, tokens, token_d_sz);
|
||||
if(i<0){
|
||||
printf("[config] Can't get \"%s\" value !\n", value);
|
||||
exit(-2);
|
||||
}
|
||||
if(i+1 >= token_d_sz){
|
||||
printf("[config] Can't get \"%s\" value, value not existing ! !\n",
|
||||
value);
|
||||
exit(-2);
|
||||
}
|
||||
if(tokens[i+1].token != value_type){
|
||||
printf("[config] Bad type for \"%s\" value !\n", value);
|
||||
exit(-2);
|
||||
}
|
||||
return i+1;
|
||||
}
|
||||
|
||||
int get_value_from_name_noerror(Token value_type, char *value,
|
||||
Tokendata *tokens, int token_d_sz) {
|
||||
int i;
|
||||
i=search_token(T_NAME, value, tokens, token_d_sz);
|
||||
if(i<0 || i+1 >= token_d_sz){
|
||||
return -1;
|
||||
}
|
||||
if(tokens[i+1].token != value_type){
|
||||
return -1;
|
||||
}
|
||||
return i+1;
|
||||
}
|
Loading…
Reference in New Issue