Tools for making games are now available.
This commit is contained in:
mibi88 2023-07-18 16:31:12 +02:00
commit efbf7fdbee
26 changed files with 884 additions and 309 deletions

1
.gitignore vendored
View File

@ -1,3 +1,4 @@
build/
lib/
*g1a
/tools/mapconv/mapconv

View File

@ -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

View File

@ -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

View File

@ -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 */

View File

@ -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();
}

View File

@ -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;
}

View File

@ -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);
}
}

View File

@ -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;
}
}
}
}

View File

@ -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
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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;

View File

@ -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");
}

9
microfx_src/src/rtc.c Normal file
View File

@ -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);
}

View File

@ -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();
}

View File

@ -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 ... */

View File

@ -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);
}

View File

@ -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
}

View File

@ -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.

View File

@ -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;
}

24
tools/mapconv/Makefile Normal file
View File

@ -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)

12
tools/mapconv/inc/help.h Normal file
View File

@ -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

31
tools/mapconv/inc/parse.h Normal file
View File

@ -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

154
tools/mapconv/src/main.c Normal file
View File

@ -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;
}

120
tools/mapconv/src/parse.c Normal file
View File

@ -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;
}