This commit is contained in:
sulokutdcmago 2008-12-28 19:34:39 +00:00
commit 361c89d8c6
40 changed files with 2466 additions and 0 deletions

140
Makefile Normal file
View File

@ -0,0 +1,140 @@
#---------------------------------------------------------------------------------
# Clear the implicit built in rules
#---------------------------------------------------------------------------------
.SUFFIXES:
#---------------------------------------------------------------------------------
ifeq ($(strip $(DEVKITPPC)),)
$(error "Please set DEVKITPPC in your environment. export DEVKITPPC=<path to>devkitPPC)
endif
include $(DEVKITPPC)/wii_rules
#---------------------------------------------------------------------------------
# TARGET is the name of the output
# BUILD is the directory where object files & intermediate files will be placed
# SOURCES is a list of directories containing source code
# INCLUDES is a list of directories containing extra header files
#---------------------------------------------------------------------------------
#TARGET := $(notdir $(CURDIR))
TARGET := gcmm_WII
BUILD := build
SOURCES := source
DATA := data
INCLUDES :=
#---------------------------------------------------------------------------------
# options for code generation
#---------------------------------------------------------------------------------
CFLAGS = -g -O2 -Wall $(MACHDEP) $(INCLUDE)
CXXFLAGS = $(CFLAGS)
LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map
#---------------------------------------------------------------------------------
# any extra libraries we wish to link with the project
#---------------------------------------------------------------------------------
LIBS := -lwiiuse -lbte -lfat -logc -lm -lfreetype
#---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing
# include and lib
#---------------------------------------------------------------------------------
LIBDIRS :=
#---------------------------------------------------------------------------------
# no real need to edit anything past this point unless you need to add additional
# rules for different file extensions
#---------------------------------------------------------------------------------
ifneq ($(BUILD),$(notdir $(CURDIR)))
#---------------------------------------------------------------------------------
export OUTPUT := $(CURDIR)/$(TARGET)
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
export DEPSDIR := $(CURDIR)/$(BUILD)
#---------------------------------------------------------------------------------
# automatically build a list of object files for our project
#---------------------------------------------------------------------------------
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
sFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.S)))
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
#---------------------------------------------------------------------------------
# use CXX for linking C++ projects, CC for standard C
#---------------------------------------------------------------------------------
ifeq ($(strip $(CPPFILES)),)
export LD := $(CC)
else
export LD := $(CXX)
endif
export OFILES := $(addsuffix .o,$(BINFILES)) \
$(CPPFILES:.cpp=.o) $(CFILES:.c=.o) \
$(sFILES:.s=.o) $(SFILES:.S=.o)
#---------------------------------------------------------------------------------
# build a list of include paths
#---------------------------------------------------------------------------------
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
-I$(CURDIR)/$(BUILD) \
-I$(LIBOGC_INC)
#---------------------------------------------------------------------------------
# build a list of library paths
#---------------------------------------------------------------------------------
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) \
-L$(LIBOGC_LIB)
export OUTPUT := $(CURDIR)/$(TARGET)
.PHONY: $(BUILD) clean
#---------------------------------------------------------------------------------
$(BUILD):
@[ -d $@ ] || mkdir -p $@
@make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
#---------------------------------------------------------------------------------
clean:
@echo clean ...
@rm -fr $(BUILD) $(OUTPUT).elf $(OUTPUT).dol
#---------------------------------------------------------------------------------
run:
psoload $(TARGET).dol
#---------------------------------------------------------------------------------
reload:
psoload -r $(TARGET).dol
#---------------------------------------------------------------------------------
else
DEPENDS := $(OFILES:.o=.d)
#---------------------------------------------------------------------------------
# main targets
#---------------------------------------------------------------------------------
$(OUTPUT).dol: $(OUTPUT).elf
$(OUTPUT).elf: $(OFILES)
#---------------------------------------------------------------------------------
# This rule links in binary data with the .jpg extension
#---------------------------------------------------------------------------------
%.jpg.o : %.jpg
#---------------------------------------------------------------------------------
@echo $(notdir $<)
$(bin2o)
-include $(DEPENDS)
#---------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------

140
Makefile.gc Normal file
View File

@ -0,0 +1,140 @@
#---------------------------------------------------------------------------------
# Clear the implicit built in rules
#---------------------------------------------------------------------------------
.SUFFIXES:
#---------------------------------------------------------------------------------
ifeq ($(strip $(DEVKITPPC)),)
$(error "Please set DEVKITPPC in your environment. export DEVKITPPC=<path to>devkitPPC)
endif
include $(DEVKITPPC)/gamecube_rules
#---------------------------------------------------------------------------------
# TARGET is the name of the output
# BUILD is the directory where object files & intermediate files will be placed
# SOURCES is a list of directories containing source code
# INCLUDES is a list of directories containing extra header files
#---------------------------------------------------------------------------------
#TARGET := $(notdir $(CURDIR))
TARGET := gcmm_GC
BUILD := build
SOURCES := source
DATA := data
INCLUDES :=
#---------------------------------------------------------------------------------
# options for code generation
#---------------------------------------------------------------------------------
CFLAGS = -g -O2 -Wall $(MACHDEP) $(INCLUDE)
CXXFLAGS = $(CFLAGS)
LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map
#---------------------------------------------------------------------------------
# any extra libraries we wish to link with the project
#---------------------------------------------------------------------------------
LIBS := -lfat -logc -lm -lfreetype
#---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing
# include and lib
#---------------------------------------------------------------------------------
LIBDIRS :=
#---------------------------------------------------------------------------------
# no real need to edit anything past this point unless you need to add additional
# rules for different file extensions
#---------------------------------------------------------------------------------
ifneq ($(BUILD),$(notdir $(CURDIR)))
#---------------------------------------------------------------------------------
export OUTPUT := $(CURDIR)/$(TARGET)
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
export DEPSDIR := $(CURDIR)/$(BUILD)
#---------------------------------------------------------------------------------
# automatically build a list of object files for our project
#---------------------------------------------------------------------------------
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
sFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.S)))
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
#---------------------------------------------------------------------------------
# use CXX for linking C++ projects, CC for standard C
#---------------------------------------------------------------------------------
ifeq ($(strip $(CPPFILES)),)
export LD := $(CC)
else
export LD := $(CXX)
endif
export OFILES := $(addsuffix .o,$(BINFILES)) \
$(CPPFILES:.cpp=.o) $(CFILES:.c=.o) \
$(sFILES:.s=.o) $(SFILES:.S=.o)
#---------------------------------------------------------------------------------
# build a list of include paths
#---------------------------------------------------------------------------------
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
-I$(CURDIR)/$(BUILD) \
-I$(LIBOGC_INC)
#---------------------------------------------------------------------------------
# build a list of library paths
#---------------------------------------------------------------------------------
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) \
-L$(LIBOGC_LIB)
export OUTPUT := $(CURDIR)/$(TARGET)
.PHONY: $(BUILD) clean
#---------------------------------------------------------------------------------
$(BUILD):
@[ -d $@ ] || mkdir -p $@
@make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
#---------------------------------------------------------------------------------
clean:
@echo clean ...
@rm -fr $(BUILD) $(OUTPUT).elf $(OUTPUT).dol
#---------------------------------------------------------------------------------
run:
psoload $(TARGET).dol
#---------------------------------------------------------------------------------
reload:
psoload -r $(TARGET).dol
#---------------------------------------------------------------------------------
else
DEPENDS := $(OFILES:.o=.d)
#---------------------------------------------------------------------------------
# main targets
#---------------------------------------------------------------------------------
$(OUTPUT).dol: $(OUTPUT).elf
$(OUTPUT).elf: $(OFILES)
#---------------------------------------------------------------------------------
# This rule links in binary data with the .jpg extension
#---------------------------------------------------------------------------------
%.jpg.o : %.jpg
#---------------------------------------------------------------------------------
@echo $(notdir $<)
$(bin2o)
-include $(DEPENDS)
#---------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 977 B

BIN
background/wiibk.psd Normal file

Binary file not shown.

170
source/bitmap.c Normal file
View File

@ -0,0 +1,170 @@
/****************************************************************************
* bitmap.c
*
* libogc example to display a Windows bitmap.
*
* NOTE: Windows BMP must comply to the following:
* 24-bit uncompressed (99.99% of Windows Editor output)
* Be less than or equal to 640 x 480(MPAL/NTSC) 640x528(PAL)
*
* This example decodes a BMP file onto the linear framebuffer.
****************************************************************************/
#include <gccore.h>
#include <ogcsys.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "bitmap.h"
//*extern GXRModeObj *vmode; /*** Graphics Mode Object ***/
//extern u32 *xfb[2] = { NULL, NULL }; /*** Framebuffers ***/
//extern int whichfb = 0; /*** Frame buffer toggle ***/
/****************************************************************************
* Supporting Functions
*
* Intel to PowerPC
* FLIP32 Convert little to big endian ints.
* FLIP16 Convert little to big endian shorts.
* CvtRGB Convert RGB pixels to Y1CbY2Cr.
****************************************************************************/
u32 FLIP32(u32 value) {
u32 b;
b = (value & 0xff) << 24;
b |= (value & 0xff00) << 8;
b |= (value & 0xff0000) >> 8;
b |= (value & 0xff000000) >> 24;
return b;
}
u16 FLIP16(u16 value) {
return ((value & 0xff) << 8) | ((value & 0xff00) >> 8);
}
/****************************************************************************
* CvtRGB
*
* This function simply returns two RGB pixels as one Y1CbY2Cr.
*****************************************************************************/
u32 CvtRGB(u8 r1, u8 g1, u8 b1, u8 r2, u8 g2, u8 b2) {
int y1, cb1, cr1, y2, cb2, cr2, cb, cr;
y1 = (299 * r1 + 587 * g1 + 114 * b1) / 1000;
cb1 = (-16874 * r1 - 33126 * g1 + 50000 * b1 + 12800000) / 100000;
cr1 = (50000 * r1 - 41869 * g1 - 8131 * b1 + 12800000) / 100000;
y2 = (299 * r2 + 587 * g2 + 114 * b2) / 1000;
cb2 = (-16874 * r2 - 33126 * g2 + 50000 * b2 + 12800000) / 100000;
cr2 = (50000 * r2 - 41869 * g2 - 8131 * b2 + 12800000) / 100000;
cb = (cb1 + cb2) >> 1;
cr = (cr1 + cr2) >> 1;
return (y1 << 24) | (cb << 16)| (y2 << 8)| cr;
}
/****************************************************************************
* Windows 24-Bit Bitmap Header
*
* These are only the values which are important for GC.
****************************************************************************/
typedef struct {
u16 bfMagic; /*** Always BM ***/
u32 bfSize; /*** Size of file ***/
u32 bfReserved; /*** Always 0 ***/
u32 bfOffset; /*** Offset to pixel data ***/
u32 biImageHdrSize; /*** Size of Image info header ***/
u32 biWidth; /*** Width of bitmap ***/
u32 biHeight; /*** Height of bitmap ***/
u16 biPlanes; /*** Number of planes ***/
u16 biBitsPerPixel; /*** Bits per pixel ***/
u32 biCompression; /*** Is this compressed? ***/
} __attribute__ ((__packed__)) WINBITMAP;
/****************************************************************************
* ShowBMP
*
* This function does some basic checks on the bitmap, to make sure it's the
* format expected.
*
* It will display the bitmap data centred on the NEXT framebuffer.
****************************************************************************/
u32 ShowBMP(u8 * bmpfile) {
WINBITMAP *bitmap;
u32 fbwidth, width, height;
u8 *bgr;
u32 fboffset;
u32 rows, cols;
bitmap = (WINBITMAP *) bmpfile;
/*** First check, is this a windows bitmap ? ***/
if (memcmp (&bitmap->bfMagic, "BM", 2))
return 0;
/*** Only support single plane ***/
if (FLIP16 (bitmap->biPlanes) != 1)
return 0;
/*** Only support non-compressed ***/
if (FLIP32 (bitmap->biCompression) != 0)
return 0;
/*** 24 bits per pixel ***/
if (FLIP16 (bitmap->biBitsPerPixel) != 24)
return 0;
width = FLIP32 (bitmap->biWidth);
height = FLIP32 (bitmap->biHeight);
/*** Will the bitmap fit in the framebuffer? ***/
if ((width > 640) || (height > vmode->xfbHeight))
return 0;
/*** Looks like decoding this is ok ***/
bgr = (u8 *) bmpfile + FLIP32 (bitmap->bfOffset);
fbwidth = width;
if (fbwidth & 1)
fbwidth++;
/***
* Windows BMP files are stored left-to-right, bottom-to-top
***/
/*** Centre width ***/
fboffset = ((640 - fbwidth) >> 1) >> 1;
/*** Centre height ***/
fboffset += (((vmode->xfbHeight - height) >> 1) * 320);
fboffset += (height * 320);
/*** Move to NEXT framebuffer ***/
whichfb ^= 1;
for (rows = 0; rows < height; rows++) {
for (cols = 0; cols < (fbwidth >> 1); cols++) {
xfb[whichfb][fboffset + cols] =CvtRGB (bgr[2], bgr[1], bgr[0],
bgr[5], bgr[4], bgr[3]);
bgr += 6;
}
fboffset -= 320; /*** Go up one row ***/
} /*** Outer row loop ***/
/*** Setup the video to display this picture ***/
/*VIDEO_SetNextFramebuffer (xfb[whichfb]);
VIDEO_Flush ();
VIDEO_WaitVSync ();*/
return 1;
}
void ClearScreen() {
ShowBMP(bitmapfile);
}

7
source/bitmap.h Normal file
View File

@ -0,0 +1,7 @@
/*** 2D Video Globals ***/
extern GXRModeObj *vmode; /*** Graphics Mode Object ***/
extern u32 *xfb[2]; /*** Framebuffers ***/
extern int whichfb; /*** Frame buffer toggle ***/
extern u8 bitmapfile[];
u32 ShowBMP (u8 *bmpfile);
void ClearScreen();

12
source/fontface.s Normal file
View File

@ -0,0 +1,12 @@
# Fonts
.rodata
.globl fontface
.balign 32
fontface:
.incbin "../source/ttf/font.ttf"
.globl fontsize
fontsize: .long 28736

770
source/freetype.c Normal file
View File

@ -0,0 +1,770 @@
/****************************************************************************
* libFreeType
*
* Needed to show the user what's the hell's going on !!
* These functions are generic, and do not contain any Memory Card specific
* routines.
****************************************************************************/
#include <gccore.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ft2build.h>
#include FT_FREETYPE_H
#include "freetype.h"
#include "gci.h"
#include "mcard.h"
#include "sdsupp.h"
#include "bitmap.h"
#define MCDATAOFFSET 64
#ifdef HW_RVL
#include <wiiuse/wpad.h>
#endif
/*** Globals ***/
FT_Library ftlibrary;
FT_Face face;
FT_GlyphSlot slot;
FT_UInt glyph_index;
extern int cancel;
extern int mode;
static int fonthi, fontlo;
/*** The actual TrueType Font ***/
extern char fontface[]; /*** From fontface.s ***/
extern int fontsize; /*** From fontface.s ***/
/*** From video subsystem ***/
extern int screenheight;
extern u32 *xfb[2];
extern int whichfb;
extern GXRModeObj *vmode;
/*** File listings ***/
extern card_dir CardList[];
extern u8 filelist[1024][1024];
extern u32 maxfile;
extern GCI gci;
#define MAXFILEBUFFER (1024 * 2048)
extern u8 FileBuffer[MAXFILEBUFFER] ATTRIBUTE_ALIGN (32);
#define PAGESIZE 18
#ifdef HW_RVL
// POWER BUTTON
bool power=false;
void PowerOff()
{
//LWP_MutexDestroy(m_audioMutex);
SYS_ResetSystem(SYS_POWEROFF, 0, 0);
exit(0);
}
static void set_power_var()
{
power = true;
}
static void set_wiimote_power_var(s32 chan)
{
power = true;
}
void initialise_power()
{
SYS_SetPowerCallback(set_power_var);
WPAD_SetPowerButtonCallback(set_wiimote_power_var);
}
// END POWER BUTTON
#endif
/****************************************************************************
* FT_Init
*
* Initialise freetype library
****************************************************************************/
int FT_Init (){
int err;
err = FT_Init_FreeType (&ftlibrary);
if (err)
return 1;
err =
FT_New_Memory_Face (ftlibrary, (FT_Byte *) fontface, fontsize, 0, &face);
if (err)
return 1;
setfontsize (16);
setfontcolour (0xff, 0xff, 0xff);
slot = face->glyph;
return 0;
}
/****************************************************************************
* setfontsize
****************************************************************************/
void setfontsize (int pixelsize){
int err;
err = FT_Set_Pixel_Sizes (face, 0, pixelsize);
if (err)
printf ("Error setting pixel sizes!");
}
static void DrawCharacter (FT_Bitmap * bmp, FT_Int x, FT_Int y){
FT_Int i, j, p, q;
FT_Int x_max = x + bmp->width;
FT_Int y_max = y + bmp->rows;
int spos;
unsigned int pixel;
int c;
for (i = x, p = 0; i < x_max; i++, p++)
{
for (j = y, q = 0; j < y_max; j++, q++)
{
if (i < 0 || j < 0 || i >= 640 || j >= screenheight)
continue;
/*** Convert pixel position to GC int sizes ***/
spos = (j * 320) + (i >> 1);
pixel = xfb[whichfb][spos];
c = bmp->buffer[q * bmp->width + p];
/*** Cool Anti-Aliasing doesn't work too well at hires on GC ***/
if (c > 128)
{
if (i & 1)
pixel = (pixel & 0xffff0000) | fontlo;
else
pixel = ((pixel & 0xffff) | fonthi);
xfb[whichfb][spos] = pixel;
}
}
}
}
/**
* DrawText
*
* Place the font bitmap on the screen
*/
void DrawText (int x, int y, char *text){
int px, n;
int i;
int err;
int value, count;
n = strlen (text);
if (n == 0)
return;
/*** x == -1, auto centre ***/
if (x == -1)
{
value = 0;
px = 0;
}
else
{
value = 1;
px = x;
}
for (count = value; count < 2; count++)
{
/*** Draw the string ***/
for (i = 0; i < n; i++)
{
err = FT_Load_Char (face, text[i], FT_LOAD_RENDER);
if (err)
{
printf ("Error %c %d\n", text[i], err);
continue; /*** Skip unprintable characters ***/
}
if (count)
DrawCharacter (&slot->bitmap, px + slot->bitmap_left,
y - slot->bitmap_top);
px += slot->advance.x >> 6;
}
px = (640 - px) >> 1;
}
}
/**
* getcolour
*
* Simply converts RGB to Y1CbY2Cr format
*
* I got this from a pastebin, so thanks to whoever originally wrote it!
*/
static unsigned int getcolour (u8 r1, u8 g1, u8 b1){
int y1, cb1, cr1, y2, cb2, cr2, cb, cr;
u8 r2, g2, b2;
r2 = r1;
g2 = g1;
b2 = b1;
y1 = (299 * r1 + 587 * g1 + 114 * b1) / 1000;
cb1 = (-16874 * r1 - 33126 * g1 + 50000 * b1 + 12800000) / 100000;
cr1 = (50000 * r1 - 41869 * g1 - 8131 * b1 + 12800000) / 100000;
y2 = (299 * r2 + 587 * g2 + 114 * b2) / 1000;
cb2 = (-16874 * r2 - 33126 * g2 + 50000 * b2 + 12800000) / 100000;
cr2 = (50000 * r2 - 41869 * g2 - 8131 * b2 + 12800000) / 100000;
cb = (cb1 + cb2) >> 1;
cr = (cr1 + cr2) >> 1;
return ((y1 << 24) | (cb << 16) | (y2 << 8) | cr);
}
/**
* setfontcolour
*
* Uses RGB triple values.
*/
void setfontcolour (u8 r, u8 g, u8 b){
u32 fontcolour;
fontcolour = getcolour (r, g, b);
fonthi = fontcolour & 0xffff0000;
fontlo = fontcolour & 0xffff;
}
/****************************************************************************
* ClearScreen
****************************************************************************/
/*void ClearScreen (){
whichfb ^= 1;
VIDEO_ClearFrameBuffer (vmode, xfb[whichfb], COLOR_BLACK);
}
*/
/****************************************************************************
* ShowScreen
****************************************************************************/
void ShowScreen (){
VIDEO_SetNextFramebuffer (xfb[whichfb]);
VIDEO_Flush ();
VIDEO_WaitVSync ();
}
/**
* Show an action in progress
*/
void ShowAction (char *msg){
//int ypos = screenheight >> 1;
//ypos += 16;
//ClearScreen ();
//DrawText (-1, ypos, msg);
writeStatusBar(msg,"");
ShowScreen ();
}
/****************************************************************************
* SelectMode
****************************************************************************/
int SelectMode (){
/*
int ypos;
ypos = (screenheight >> 1);
ClearScreen ();
DrawText (-1, ypos, "Press A for SMB BACKUP mode");
DrawText (-1, ypos + 20, "Press B for SMB RESTORE mode");
DrawText (-1, ypos + 40, "Press Y for SD CARD BACKUP mode");
DrawText (-1, ypos + 60, "Press X for SD CARD RESTORE mode");
DrawText (-1, ypos + 80, "Press Z for SD/PSO Reload");
ShowScreen ();*/
ClearScreen ();
//setfontcolour(84,174,211);
// setfontcolour(28,28,28);
// DrawText(495,305,"choose your mode");
writeStatusBar("Choose your mode","");
ShowScreen();
/*** Clear any pending buttons - button 'debounce' ***/
while (PAD_ButtonsHeld (0)
#ifdef HW_RVL
| WPAD_ButtonsHeld(0)
#endif
)
VIDEO_WaitVSync ();
for (;;){
if (PAD_ButtonsHeld (0) & PAD_BUTTON_A){
while ((PAD_ButtonsDown (0) & PAD_BUTTON_A)){ VIDEO_WaitVSync (); }
return 100;
}
if (PAD_ButtonsHeld (0) & PAD_TRIGGER_Z){
while ((PAD_ButtonsDown (0) & PAD_BUTTON_B)){ VIDEO_WaitVSync (); }
return 200;
}
if (PAD_ButtonsHeld (0) & PAD_BUTTON_Y){
while ((PAD_ButtonsDown (0) & PAD_BUTTON_Y)){ VIDEO_WaitVSync (); }
return 300;
}
if (PAD_ButtonsHeld (0) & PAD_BUTTON_X){
while ((PAD_ButtonsDown (0) & PAD_BUTTON_X)){ VIDEO_WaitVSync (); }
return 400;
}
if (PAD_ButtonsHeld (0) & PAD_BUTTON_START){
while ((PAD_ButtonsDown (0) & PAD_BUTTON_START)){ VIDEO_WaitVSync (); }
return 500;
}
#ifdef HW_RVL
if (WPAD_ButtonsHeld (0) & WPAD_BUTTON_A){
while ((WPAD_ButtonsDown (0) & WPAD_BUTTON_A)){ VIDEO_WaitVSync (); }
return 100;
}
if (WPAD_ButtonsHeld (0) & WPAD_BUTTON_2){
while ((WPAD_ButtonsDown (0) & WPAD_BUTTON_MINUS)){ VIDEO_WaitVSync (); }
return 200;
}
if (WPAD_ButtonsHeld (0) & WPAD_BUTTON_MINUS){
while ((WPAD_ButtonsDown (0) & WPAD_BUTTON_MINUS)){ VIDEO_WaitVSync (); }
return 300;
}
if (WPAD_ButtonsHeld (0) & WPAD_BUTTON_PLUS){
while ((WPAD_ButtonsDown (0) & WPAD_BUTTON_PLUS)){ VIDEO_WaitVSync (); }
return 400;
}
if (WPAD_ButtonsHeld (0) & WPAD_BUTTON_HOME){
while ((WPAD_ButtonsDown (0) & WPAD_BUTTON_HOME)){ VIDEO_WaitVSync (); }
return 500;
}
if (power){
PowerOff();
}
#endif
VIDEO_WaitVSync ();
}
}
/**
* Wait for user to press A
*/
void WaitButtonA (){
#ifdef HW_DOL
while (PAD_ButtonsDown (0) & PAD_BUTTON_A );
while (!(PAD_ButtonsDown (0) & PAD_BUTTON_A));
#else
while (1){
if (PAD_ButtonsDown (0) & PAD_BUTTON_A )
break;
if (WPAD_ButtonsDown (0) & WPAD_BUTTON_A )
break;
if (power){
PowerOff();
}
}
while (1){
if (!(PAD_ButtonsDown (0) & PAD_BUTTON_A))
break;
if (!(WPAD_ButtonsDown (0) & WPAD_BUTTON_A))
break;
if (power){
PowerOff();
}
}
#endif
}
/**
* Show a prompt
*/
void WaitPrompt (char *msg){
//int ypos = (screenheight) >> 1;
//ClearScreen ();
//DrawText (-1, ypos, msg);
//ypos += 20;
//DrawText (-1, ypos, "Press A to continue");
writeStatusBar(msg,"Press A to continue");
ShowScreen ();
WaitButtonA ();
//clear the text
int bgcolor = getcolour(0xff,0xff,0xff);
DrawBoxFilled(10, 430, 510, 485, bgcolor);
}
void DrawLineFast (int startx, int endx, int y, u8 r, u8 g, u8 b){
int width;
u32 offset;
u32 colour;
int i;
offset = (y * 320) + (startx >> 1);
colour = getcolour (r, g, b);
width = (endx - startx) >> 1;
for (i = 0; i < width; i++)
xfb[whichfb][offset++] = colour;
}
void showSaveInfo(int sel) {
int y = 190, x = 380, j;
char gamecode[5], company[3], txt[1024];
//clear right pane, but we don't want to erase previous text
int bgcolor = getcolour(84,174,211);
DrawBoxFilled(375, 175, 605, 410, bgcolor);
// memcpy(company, CardList[sel].company, 2);
// memcpy(gamecode, CardList[sel].gamecode, 4);
//company[2] = gamecode[4] = 0;
// read file, display some more info
// TODO: only read the necessary header + comment for sd
if (mode == RESTORE_MODE){
j = SDLoadMCImageHeader(filelist[sel]);
memcpy(&gci, FileBuffer, 64);
ExtractGCIHeader();
GCIMakeHeader();
}else if( mode == RESTORE_MODE || mode == DELETE_MODE){
j = CardReadFileHeader(CARD_SLOTB, sel);
}
// struct gci now contains header info
memcpy(company, gci.company, 2);
memcpy(gamecode, gci.gamecode, 4);
company[2] = gamecode[4] = 0;
sprintf(txt, "#%d %s/%s", sel, gamecode, company);
DrawText(x, y, txt);
y += 20;
// Compute date/time
u32 t = gci.time; // seconds since jan 1, 2000
int month, day, year, hour, min, sec;
month = day = year = hour = min = sec = 0;
sprintf(txt, "D: %08lX", t);
DrawText(x, y, txt);
y += 20;
int monthdays[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
char monthstr[12][4] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul",
"Aug", "Sep", "Oct", "Nov", "Dec" };
sec = t % 60;
t /= 60;
min = t % 60;
t /= 60;
hour = t % 24;
t /= 24;
day = t % 365;
year = t / 365;
// figure in leap years
day -= year / 4;
if ( (year % 4 == 0) && (day > 31+29) ) {
// TODO: check if day<0, go back one month
day--;
}
// day now is number of days into the year
for(j=0; j<12; j++) {
if (day > monthdays[j]) {
month++;
day -= monthdays[j];
} else {
j = 12;
}
}
sprintf(txt, "Date: %s %02d, %04d", monthstr[month], day+1, year+2000);
DrawText(x, y, txt);
y += 20;
sprintf(txt, "Time: %02d:%02d:%02d", hour, min, sec);
DrawText(x, y, txt);
y += 20;
sprintf(txt, "Blocks: %d", gci.filesize8);
DrawText(x, y, txt);
y += 20;
sprintf(txt, "Perm: %s%s%s",
(gci.unknown1 & 16) ? "M " : "x",
(gci.unknown1 & 8) ? "C " : "x",
(gci.unknown1 & 4) ? "P" : "x");
DrawText(x, y, txt);
y += 20;
// Comment at MCDATAOFFSET+(comment addr)
char *comment = (char*) (FileBuffer+MCDATAOFFSET+gci.comment_addr);
j = 0;
int x2, z = 0;
int offset = 0;
for (x2=t=0; (t<strlen(comment)) && (t<64); t++) {
z++;
//x2 += font_size[(int)comment[t]];
x2 += 16;
if (x2 > 225) { // max width of left pane
strncpy(txt, comment+offset, z-1);
txt[z-1] = 0;
//char c = txt[t];
//txt[t] = 0;
DrawText(x, y, txt);
y += 20;
offset = t-1;
//txt[t] = c;
//strcpy(txt, comment+t);
z = 0;
//x2 = font_size[(int)comment[t]];
x2 = 16;
}
}
if (z) {
strcpy(txt, comment+offset);
//txt[z] = 0;
DrawText(x, y, txt);
y += 20;
}
}
static void ShowFiles (int offset, int selection){
int i, j;
char text[80];
int ypos;
int w;
clearLeftPane();
//setfontsize (16);
setfontsize (14);
//ypos = 70;
ypos = (screenheight - (PAGESIZE * 20)) >> 1;
//ypos += 20;
ypos += 25;
j = 0;
for (i = offset; i < (offset + PAGESIZE) && (i < maxfile); i++){
strcpy (text, filelist[i]);
if (j == (selection - offset)){
/*** Highlighted text entry ***/
for (w = 0; w < 20; w++){
// DrawLineFast (30, 610, (j * 20) + (ypos - 16) + w, 0x00, 0x00, 0xC0);
//DrawLineFast (35, 330, (j * 20) + (ypos - 16) + w, 0xff, 0xff, 0xff);
DrawLineFast (35, 330, (j * 20) + (ypos - 14) + w, 0xff, 0xff, 0xff);
}
//setfontcolour (0xff, 0xff, 0xff);
//setfontcolour (84, 174, 211);
setfontcolour (28, 28, 28);
// DrawText (-1, (j * 20) + ypos, text);
DrawText (35, (j * 20) + ypos, text);
showSaveInfo(selection);
setfontcolour (0xff, 0xff, 0xff);
//setfontcolour (0xc0, 0xc0, 0xc0);
}
else{
/*** Normal entry ***/
//****************
for (w = 0; w < 20; w++){
// DrawLineFast (30, 610, (j * 20) + (ypos - 16) + w, 0x00, 0x00, 0xC0);
//DrawLineFast (35, 330, (j * 20) + (ypos - 16) + w, 84, 174,211);
DrawLineFast (35, 330, (j * 20) + (ypos - 14) + w, 84, 174,211);
//***********************************************************
}
DrawText (35, (j * 20) + ypos, text);
}
j++;
}
ShowScreen ();
}
/*void ShowFiles(int offset, int selected, int maxfiles) {
int y = 110, tmp;
//WaitPrompt("ShowFiles");
clearLeftPane();
for (tmp = offset; (tmp<offset+PAGESIZE) && (tmp < maxfiles); tmp++) {
char str[1024], txt[1024];
int x, t;
strcpy(str, CardList[tmp].filename);
for (x=t=0; t<strlen(str); t++) {
x += font_size[(int)str[t]];
if (x > 290) { // max width of left pane
str[t] = 0;
t = strlen(str);
}
}
strcpy(txt, str);
//txt[t-1] = 0;
if (tmp == selected) {
// Highlight this file
fntDrawBoxFilled(35, y, 330, y+23, hlcolor);
showSaveInfo(selected);
}
write_font(35, y, txt); // write filename on left
y += 20;
}
}
*/
/****************************************************************************
* ShowSelector
*
* Let's the user select a file to backup or restore.
* Returns index of file chosen.
****************************************************************************/
int ShowSelector (){
u32 p, wp;
int redraw = 1;
int quit = 0;
int offset, selection;
offset = selection = 0;
while (quit == 0){
if (redraw){
ShowFiles (offset, selection);
redraw = 0;
}
p = PAD_ButtonsDown (0);
#ifdef HW_RVL
wp = WPAD_ButtonsDown (0);
#endif
if ((p & PAD_BUTTON_B )
#ifdef HW_RVL
| (wp & WPAD_BUTTON_B)
#endif
){
cancel = 1;
return;
}
#ifdef HW_RVL
if (power){
PowerOff();
}
#endif
if ((p & PAD_BUTTON_A)
#ifdef HW_RVL
| (wp & WPAD_BUTTON_A)
#endif
){
return selection;
}
if ((p & PAD_BUTTON_DOWN)
#ifdef HW_RVL
| (wp & WPAD_BUTTON_DOWN)
#endif
) {
selection++;
if (selection == maxfile){
selection = offset = 0;
}
if ((selection - offset) >= PAGESIZE){
offset += PAGESIZE;
}
redraw = 1;
}
if ((p & PAD_BUTTON_UP)
#ifdef HW_RVL
| (wp & WPAD_BUTTON_UP)
#endif
){
selection--;
if (selection < 0){
selection = maxfile - 1;
offset = selection - PAGESIZE + 1;
}
if (selection < offset){
offset -= PAGESIZE;
}
if (offset < 0){
offset = 0;
}
redraw = 1;
}
}
return selection;
}
void writeStatusBar(char *line1, char *line2) {
int bgcolor = getcolour(0xff,0xff,0xff);
//DrawBoxFilled(10, 404, 510, 455, bgcolor);
DrawBoxFilled(10, 430, 510, 485, bgcolor);
//setfontcolour(84,174,211);
setfontcolour(28,28,28);
DrawText(40, 450, line1);
DrawText(40, 475, line2);
}
void clearLeftPane() {
int bgcolor = getcolour(84,174,211);
DrawBoxFilled(34, 110, 333, 380, bgcolor);
}
void clearRightPane() {
int bgcolor = getcolour(84,174,211);
DrawBoxFilled(375, 140, 605, 410, bgcolor);
}
void DrawHLine (int x1, int x2, int y, int color)
{
int i;
y = 320 * y;
x1 >>= 1;
x2 >>= 1;
for (i = x1; i <= x2; i++) {
int *tmpfb = xfb[whichfb];
tmpfb[y+i] = color;
}
}
void DrawVLine (int x, int y1, int y2, int color)
{
int i;
x >>= 1;
for (i = y1; i <= y2; i++) {
int *tmpfb = xfb[whichfb];
tmpfb[x + (640 * i) / 2] = color;
}
}
void DrawBox (int x1, int y1, int x2, int y2, int color)
{
DrawHLine (x1, x2, y1, color);
DrawHLine (x1, x2, y2, color);
DrawVLine (x1, y1, y2, color);
DrawVLine (x2, y1, y2, color);
}
void DrawBoxFilled (int x1, int y1, int x2, int y2, int color)
{
int h;
for (h = y1; h <= y2; h++)
DrawHLine (x1, x2, h, color);
}

39
source/freetype.h Normal file
View File

@ -0,0 +1,39 @@
/****************************************************************************
* FreeType font
****************************************************************************/
#ifndef _FTFONTS_
#define _FTFONTS_
//#define PRESSED_BUTTON_A 100 /* Free mode */
#define DELETE_MODE 200
#define BACKUP_MODE 300
#define RESTORE_MODE 400
//#define RELOAD_MODE 500 /* Free mode */
#ifdef HW_RVL
void initialise_power() ;
#endif
int FT_Init ();
void setfontsize (int pixelsize);
void setfontcolour (u8 r, u8 g, u8 b);
void DrawText (int x, int y, char *text);
//extern void ClearScreen ();
void ShowScreen ();
void ShowAction (char *msg);
void WaitPrompt (char *msg);
int ShowSelector ();
int SelectMode ();
void writeStatusBar(char *line1, char *line2);
void clearLeftPane();
void clearRightPane();
/****************************************************************************
* Draw functions - lines, boxes
****************************************************************************/
void DrawHLine (int x1, int x2, int y, int color);
void DrawVLine (int x, int y1, int y2, int color);
void DrawBox (int x1, int y1, int x2, int y2, int color);
void DrawBoxFilled (int x1, int y1, int x2, int y2, int color);
#endif

BIN
source/gcbk.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 844 KiB

31
source/gci.h Normal file
View File

@ -0,0 +1,31 @@
/****************************************************************************
* GCI Memory Card stuff
*
* This is an attempt at compatibility.
****************************************************************************/
#ifndef __GCIHDR_
#define __GCIHDR_
#include <gccore.h>
typedef struct {
u8 gamecode[4];
u8 company[2];
u8 reserved01; /*** Always 0xff ***/
u8 banner_fmt;
u8 filename[CARD_FILENAMELEN];
u32 time;
u32 icon_addr;
u16 icon_fmt;
u16 icon_speed;
u8 unknown1; /*** Permission key? ***/
u8 unknown2; /*** Again, unknown ***/
u16 index; /*** Ignore - and throw away ***/
u16 filesize8; /*** File size / 8192 ***/
u16 reserved02; /*** Always 0xffff ***/
u32 comment_addr;
} __attribute__((__packed__)) GCI;
#define MCDATAOFFSET 64
#endif

6
source/gcmm-bk.gamecube Normal file
View File

@ -0,0 +1,6 @@
.rodata
.globl bitmapfile
.balign 32
bitmapfile:
.incbin "../source/gcbk.bmp"

6
source/gcmm-bk.s Normal file
View File

@ -0,0 +1,6 @@
.rodata
.globl bitmapfile
.balign 32
bitmapfile:
.incbin "../source/wiibk.bmp"

353
source/main.c Normal file
View File

@ -0,0 +1,353 @@
/****************************************************************************
* ds bomb gamecube memory card manager
*based on libOGC Memory Card Backup by askot
* delete support + saves information made by dsbomb
* Gui original design by dsbomb
* Gui adds and user interaction by justb
* Uses freetype.
* libFreeType is available from the downloads sections.
*****************************************************************************/
#include <gccore.h>
#include <ogcsys.h>
#include <network.h>
#include <smb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fat.h>
#include <sys/dir.h>
#include <sys/time.h>
#ifdef HW_RVL
#include <wiiuse/wpad.h>
#endif
#include "mcard.h"
#include "sdsupp.h"
#include "freetype.h"
#include "bitmap.h"
#define PSOSDLOADID 0x7c6000a6
int mode;
int cancel;
/*** 2D Video Globals ***/
GXRModeObj *vmode; /*** Graphics Mode Object ***/
u32 *xfb[2] = { NULL, NULL }; /*** Framebuffers ***/
int whichfb = 0; /*** Frame buffer toggle ***/
int screenheight;
extern u8 filelist[1024][1024];
static void updatePAD(){
PAD_ScanPads();
#ifdef HW_RVL
WPAD_ScanPads();
#endif
}
static int initFAT(){
//init fat filesystem
fatInit(8, false);
//sleep(2); // espero dos segundos, no se muy bien si para darle tiempo a que el dispositivo negocie o esté preparado para funcionar
//fatSetDefaultInterface(PI_INTERNAL_SD); // usa SD como fat:
int have_device=0; // bits que me indican la presencia de dispositivos
DIR_ITER *dir;
char path_initfat[]="fatX:/";
#ifdef HW_RVL
path_initfat[3]=48+PI_INTERNAL_SD; // path_file ="fatX:/";
#else
path_initfat[3]=48+PI_SDGECKO_A; // path_file ="fatX:/";
#endif
int n;
for(n=0;n<5;n++) // numero de reintentos por si la unidad no está preparada o está "enojada" :lol:
{
dir = diropen(path_initfat);
if (dir) {
dirclose(dir);
//have_device|=1;
have_device=1;
#ifdef HW_RVL
fatEnableReadAhead(PI_INTERNAL_SD, 12, 32);// monta la cache
#endif
break;
}
//usleep(200*1000);
}
return have_device;
}
/****************************************************************************
* Initialise Video
*
* Before doing anything in libogc, it's recommended to configure a video
* output.
****************************************************************************/
static void
Initialise (void)
{
VIDEO_Init (); /*** ALWAYS CALL FIRST IN ANY LIBOGC PROJECT!
Not only does it initialise the video
subsystem, but also sets up the ogc os
***/
PAD_Init (); /*** Initialise pads for input ***/
#ifdef HW_RVL
WPAD_Init ();
#endif
/*** Try to match the current video display mode
using the higher resolution interlaced.
So NTSC/MPAL gives a display area of 640x480
PAL display area is 640x528
***/
switch (VIDEO_GetCurrentTvMode ())
{
case VI_NTSC:
vmode = &TVNtsc480IntDf;
break;
case VI_PAL:
vmode = &TVPal528IntDf;
break;
case VI_MPAL:
vmode = &TVMpal480IntDf;
break;
default:
vmode = &TVNtsc480IntDf;
break;
}
/*** Let libogc configure the mode ***/
VIDEO_Configure (vmode);
/*** Now configure the framebuffer.
Really a framebuffer is just a chunk of memory
to hold the display line by line.
***/
xfb[0] = (u32 *) MEM_K0_TO_K1 (SYS_AllocateFramebuffer (vmode));
/*** I prefer also to have a second buffer for double-buffering.
This is not needed for the console demo.
***/
xfb[1] = (u32 *) MEM_K0_TO_K1 (SYS_AllocateFramebuffer (vmode));
/*** Define a console ***/
console_init (xfb[0], 20, 64, vmode->fbWidth, vmode->xfbHeight,
vmode->fbWidth * 2);
/*** Update screen height for font engine ***/
screenheight = vmode->xfbHeight;
/*** Clear framebuffer to black ***/
VIDEO_ClearFrameBuffer (vmode, xfb[0], COLOR_BLACK);
VIDEO_ClearFrameBuffer (vmode, xfb[1], COLOR_BLACK);
/*** Set the framebuffer to be displayed at next VBlank ***/
VIDEO_SetNextFramebuffer (xfb[0]);
/*** Get the PAD status updated by libogc ***/
VIDEO_SetPostRetraceCallback (updatePAD);
VIDEO_SetBlack (0);
/*** Update the video for next vblank ***/
VIDEO_Flush ();
VIDEO_WaitVSync (); /*** Wait for VBL ***/
if (vmode->viTVMode & VI_NON_INTERLACE)
VIDEO_WaitVSync ();
}
/****************************************************************************
* BackupMode -SD Mode
*
* Perform backup of a memory card file from a SD Card.
****************************************************************************/
void SD_BackupMode (){
int memitems;
int selected = 0;
int bytestodo;
clearRightPane();
//DrawText(390,130,"B a c k u p M o d e");
DrawText(388,160,"B a c k u p M o d e");
writeStatusBar("Pick a file using UP or DOWN ", "Press A to backup to SD Card ") ;
/*** Get the directory listing from the memory card ***/
memitems = CardGetDirectory (CARD_SLOTB);
/*** If it's a blank card, get out of here ***/
if (!memitems) {WaitPrompt ("No saved games to backup !");}
else
{
selected = ShowSelector ();
if (cancel) {WaitPrompt ("Backup action cancelled !");}
else
{
/*** Backup the file ***/
ShowAction ("Reading File From MC SLOT B");
bytestodo = CardReadFile (CARD_SLOTB, selected);
if (bytestodo){
ShowAction ("Saving to SD CARD");
if (SDSaveMCImage ()){
WaitPrompt ("Backup complete");
}
else{
WaitPrompt ("Backup failed");
}
}
else{
WaitPrompt ("Error reading MC file");
}
}
}
}
/****************************************************************************
* RestoreMode
*
* Restore a file to Memory Card from SD Card
****************************************************************************/
void SD_RestoreMode (){
int files;
int selected;
clearRightPane();
//DrawText(390,130,"R e s t o r e M o d e");
DrawText(388,160,"R e s t o r e M o d e");
writeStatusBar("Pick a file using UP or DOWN", "Press A to restore to Memory Card ") ;
files = SDGetFileList ();
if (!files) {WaitPrompt ("No saved games in SD Card to restore !");}
else
{
selected = ShowSelector ();
if (cancel) {WaitPrompt ("restore action cancelled !");}
else
{
ShowAction ("Reading from SD Card");
if (SDLoadMCImage (filelist[selected])){
ShowAction ("Updating Memory Card");
if (CardWriteFile (CARD_SLOTB)){
WaitPrompt ("Restore Complete");
}
else {
WaitPrompt ("Error during restore");
}
}
else{
WaitPrompt ("Error reading image");
}
}
}
}
/****************************************************************************
* TestMode
*
*
****************************************************************************/
/*void testMode (){
clearRightPane();
DrawText(390,130,"T e s t M o d e");
int bytestodo;
clearRightPane();
ShowAction ("Reading From MC SLOT B");
bytestodo = testreadimage (CARD_SLOTB);
if (bytestodo){
ShowAction ("Saving to SD CARD");
if (SDSaveraw ()){
WaitPrompt ("Backup complete");
}
else{
WaitPrompt ("Backup failed");
}
}
else{
WaitPrompt ("Error reading MC file");
}
// writeStatusBar("Pick a file using UP or DOWN", "Press A to restore to Memory Card ") ;
//WaitPrompt ("No saved games in SD Card to restore !");
//ShowAction ("Reading from SD Card");
}*/
/****************************************************************************
* Main
****************************************************************************/
int main (){
#ifdef HW_DOL
int *psoid = (int *) 0x80001800;
void (*PSOReload) () = (void (*)()) 0x80001800;
#endif
Initialise (); /*** Start video ***/
FT_Init (); /*** Start FreeType ***/
if(!initFAT())
WaitPrompt("Insert SDCARD");
#ifdef HW_RVL
initialise_power();
#endif
for (;;){
/*** Select Mode ***/
ClearScreen();
cancel = 0;/******a global value to track action aborted by user pressing button B********/
mode = SelectMode ();
/*** Mode == 100 for backup, 200 for restore ***/
switch (mode){
case 100 :
//SMB_BackupMode();
//WaitPrompt ("Inactive");
break;
case 200 :
MC_DeleteMode(CARD_SLOTB);
break;
case 300 :
SD_BackupMode();
break;
case 400 :
SD_RestoreMode();
break;
case 500 :
#ifdef HW_RVL
if (!!*(u32*)0x80001800) exit(1);
else SYS_ResetSystem(SYS_RETURNTOMENU, 0, 0);
#else
if (psoid[0] == PSOSDLOADID)
PSOReload ();
#endif
break; //PSO_Reload
}
}
while (1);
return 0;
}

513
source/mcard.c Normal file
View File

@ -0,0 +1,513 @@
/****************************************************************************
* Memory Card
*
* Supporting functions.
*
* MAXFILEBUFFER is set to 2MB as it's the largest file I've seen.
*
* CARDBACKUP FILE
*
* 0 - Copy of CardDir
* 64 - Copy of CardStatus
* 192 - Memory Card File Data
****************************************************************************/
#include <gccore.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "mcard.h"
#include "gci.h"
#include "freetype.h"
/*** Memory Card Work Area ***/
static u8 SysArea[CARD_WORKAREA] ATTRIBUTE_ALIGN (32);
/*** Memory File Buffer ***/
#define MAXFILEBUFFER (1024 * 2048) /*** 2MB Buffer ***/
u8 FileBuffer[MAXFILEBUFFER] ATTRIBUTE_ALIGN (32);
u8 filelist[1024][1024];
int maxfile;
extern int cancel;
/*** Card lib ***/
card_dir CardList[CARD_MAXFILES]; /*** Directory listing ***/
static card_dir CardDir;
static card_file CardFile;
static card_stat CardStatus;
static int cardcount = 0;
GCI gci;
/*---------------------------------------------------------------------------------
This function is called if a card is physically removed
---------------------------------------------------------------------------------*/
void card_removed(s32 chn,s32 result) {
//---------------------------------------------------------------------------------
printf("card was removed from slot %c\n",(chn==0)?'A':'B');
CARD_Unmount(chn);
}
/****************************************************************************
* MountCard
*
* Mounts the memory card in the given slot.
* Returns the result of the last attempted CARD_Mount command.
***************************************************************************/
int MountCard(int cslot)
{
int ret = -1;
int tries = 0;
// Mount the card
while ( tries < 10 && ret != 0)
{
EXI_ProbeReset ();
ret = CARD_Mount (cslot, SysArea, card_removed);
VIDEO_WaitVSync ();
tries++;
}
return ret;
}
/****************************************************************************
* GCIMakeHeader
*
* Create a GCI compatible header from libOGC card_stat
****************************************************************************/
void GCIMakeHeader()
{
/*** Clear out the cgi header ***/
memset(&gci, 0xff, sizeof(GCI) );
/*** Populate ***/
memcpy(&gci.gamecode, &CardStatus.gamecode, 4);
memcpy(&gci.company, &CardStatus.company, 2);
gci.banner_fmt = CardStatus.banner_fmt;
memcpy(&gci.filename, &CardStatus.filename, CARD_FILENAMELEN);
gci.time = CardStatus.time;
gci.icon_addr = CardStatus.icon_addr;
gci.icon_fmt = CardStatus.icon_fmt;
gci.icon_speed = CardStatus.icon_speed;
/*** In the games I've checked, these are always 0 ***/
gci.unknown1 = gci.unknown2 = 0;
/*** Block index does not matter, it won't be restored at the same spot ***/
gci.index = 32;
gci.filesize8 = (CardStatus.len / 8192);
gci.comment_addr = CardStatus.comment_addr;
/*** Copy to head of buffer ***/
memcpy(FileBuffer, &gci, sizeof(GCI));
}
/****************************************************************************
* ExtractGCIHeader
*
* Extract a GCI Header to libOGC card_stat
****************************************************************************/
void ExtractGCIHeader()
{
/*** Clear out the status ***/
memset(&CardStatus, 0, sizeof(card_stat));
memcpy(&gci, FileBuffer, sizeof(GCI));
memcpy(&CardStatus.gamecode, &gci.gamecode, 4);
memcpy(&CardStatus.company, &gci.company, 2);
CardStatus.banner_fmt = gci.banner_fmt;
memcpy(&CardStatus.filename, &gci.filename, CARD_FILENAMELEN);
CardStatus.time = gci.time;
CardStatus.icon_addr = gci.icon_addr;
CardStatus.icon_fmt = gci.icon_fmt;
CardStatus.icon_speed = gci.icon_speed;
CardStatus.len = gci.filesize8 * 8192;
CardStatus.comment_addr = gci.comment_addr;
}
/****************************************************************************
* CardGetDirectory
*
* Returns number of files found on a card.
****************************************************************************/
int CardGetDirectory (int slot){
int err;
char company[4];
char gamecode[6];
company[2] = gamecode[4] = 0;
/*** Clear the work area ***/
memset (SysArea, 0, CARD_WORKAREA);
/*** Initialise the Card system, show all ***/
CARD_Init (NULL, NULL);
/*** Try to mount the card ***/
err = MountCard(slot);
if (err){
WaitCardError("CardMount",CARD_GetErrorCode(slot));
return 0; /*** Unable to mount the card ***/
}
/*** Retrieve the directory listing ***/
cardcount = 0;
err = CARD_FindFirst (slot, &CardDir, true);
while (err != CARD_ERROR_NOFILE)
{
memcpy (&CardList[cardcount], &CardDir, sizeof (card_dir));
memset (filelist[cardcount], 0, 1024);
memcpy (company, &CardDir.company, 2);
memcpy (gamecode, &CardDir.gamecode, 4);
sprintf (filelist[cardcount], "%s-%s-%s", company, gamecode, CardDir.filename);
cardcount++;
err = CARD_FindNext (&CardDir);
}
/*** Release as soon as possible ***/
CARD_Unmount (slot);
maxfile = cardcount;
return cardcount;
}
/****************************************************************************
* CardListFiles
****************************************************************************/
void CardListFiles (){
int i;
char company[4];
char gamecode[6];
company[2] = 0;
gamecode[4] = 0;
for (i = 0; i < cardcount; i++)
{
memcpy (company, &CardList[i].company, 2);
memcpy (gamecode, &CardList[i].gamecode, 4);
printf ("%s %s %s\n", company, gamecode, CardList[i].filename);
}
}
/****************************************************************************
* CardReadFileHeader
*
* Retrieve a file header from the previously populated list.
****************************************************************************/
int CardReadFileHeader (int slot, int id){
int err;
char company[4];
char gamecode[6];
if (id >= cardcount){
WaitPrompt("Bad id");
return 0; /*** Bad id ***/
}
/*** Clear the work buffers ***/
memset (SysArea, 0, CARD_WORKAREA);
company[2] = 0;
gamecode[4] = 0;
memcpy (company, &CardList[id].company, 2);
memcpy (gamecode, &CardList[id].gamecode, 4);
/*** Initialise for this company ***/
CARD_Init (gamecode, company);
/*** Mount the card ***/
err = MountCard (slot);
if (err){
WaitCardError("CardMount",CARD_GetErrorCode(slot));
return 0;
}
/*** Get card status info ***/
CARD_GetStatus (slot, CardFile.filenum, &CardStatus);
GCIMakeHeader();
/*** Unmount the card ***/
CARD_Unmount (slot);
return 1;
}
/****************************************************************************
* CardReadFile
*
* Retrieve a file from the previously populated list.
* Place in filebuffer space, for collection by SMB write.
****************************************************************************/
int CardReadFile (int slot, int id){
int bytesdone = 0;
int err;
u32 SectorSize;
char company[4];
char gamecode[6];
int filesize;
if (id >= cardcount){
WaitPrompt("Bad id");
return 0; /*** Bad id ***/
}
/*** Clear the work buffers ***/
memset (FileBuffer, 0, MAXFILEBUFFER);
memset (SysArea, 0, CARD_WORKAREA);
company[2] = 0;
gamecode[4] = 0;
memcpy (company, &CardList[id].company, 2);
memcpy (gamecode, &CardList[id].gamecode, 4);
/*** Initialise for this company ***/
CARD_Init (gamecode, company);
/*** Mount the card ***/
err = MountCard (slot);
if (err){
WaitCardError("CardMount",CARD_GetErrorCode(slot));
return 0;
}
/*** Retrieve sector size ***/
CARD_GetSectorSize (slot, &SectorSize);
/*** Open the file ***/
err = CARD_Open (slot, (char *) &CardList[id].filename, &CardFile);
if (err)
{
CARD_Unmount (slot);
WaitCardError("CardOpen",CARD_GetErrorCode(slot));
return 0;
}
/*** Get card status info ***/
CARD_GetStatus (slot, CardFile.filenum, &CardStatus);
GCIMakeHeader();
/*** Copy the file contents to the buffer ***/
filesize = CardFile.len;
while (bytesdone < filesize)
{
CARD_Read (&CardFile, FileBuffer + MCDATAOFFSET + bytesdone, SectorSize,
bytesdone);
bytesdone += SectorSize;
}
/*** Close the file ***/
CARD_Close (&CardFile);
/*** Unmount the card ***/
CARD_Unmount (slot);
return filesize + MCDATAOFFSET;
}
/****************************************************************************
* CardWriteFile
*
* Relies on *GOOD* data being placed in the FileBuffer prior to calling.
* See ReadSMBImage
****************************************************************************/
int CardWriteFile (int slot) {
char company[4];
char gamecode[6];
char filename[CARD_FILENAMELEN];
int err;
u32 SectorSize;
int offset;
int written;
int filelen;
company[2] = gamecode[4] = 0;
memset (SysArea, 0, CARD_WORKAREA);
memset(filename, 0, CARD_FILENAMELEN);
ExtractGCIHeader();
memcpy(company, &gci.company, 2);
memcpy(gamecode, &gci.gamecode, 4);
memcpy(filename, &gci.filename, CARD_FILENAMELEN);
filelen = gci.filesize8 * 8192;
/*** Init system ***/
CARD_Init (gamecode, company);
err = MountCard(slot);
if (err){
WaitCardError("CardMount",CARD_GetErrorCode(slot));
return 0;
}
CARD_GetSectorSize (slot, &SectorSize);
/*** If this file exists, abort ***/
err = CARD_FindFirst (slot, &CardDir, false);
while (err != CARD_ERROR_NOFILE){
if (strcmp ((char *) CardDir.filename, (char *)filename) == 0){
/*** Found the file - abort ***/
CARD_Unmount (slot);
WaitCardError("File already exists",CARD_GetErrorCode(slot));
return 0;
}
err = CARD_FindNext (&CardDir);
}
CARD_SetCompany(company);
CARD_SetGamecode(gamecode);
/*** Now restore the file from backup ***/
err = CARD_Create (slot, (char *) filename, filelen, &CardFile);
if (err){
CARD_Unmount (slot);
WaitCardError("CardCreate",CARD_GetErrorCode(slot));
return 0;
}
/*** Now write the file data, in sector sized chunks ***/
offset = 0;
while (offset < filelen){
if ((offset + SectorSize) <= filelen){
written = CARD_Write (&CardFile, FileBuffer + MCDATAOFFSET + offset, SectorSize, offset);
}
else{
written = CARD_Write (&CardFile, FileBuffer + MCDATAOFFSET + offset, ((offset + SectorSize) - filelen), offset);
}
offset += SectorSize;
}
/*** Finally, update the status ***/
CARD_SetStatus (slot, CardFile.filenum, &CardStatus);
CARD_Close (&CardFile);
CARD_Unmount (slot);
return 1;
}
void WaitCardError(char *src, int error) {
char msg[1024], err[256];
switch (error) {
case CARD_ERROR_BUSY:
sprintf(err, "Busy");
break;
case CARD_ERROR_WRONGDEVICE:
sprintf(err, "Wrong device in slot");
break;
case CARD_ERROR_NOCARD:
sprintf(err, "No Card");
break;
case CARD_ERROR_NOFILE:
sprintf(err, "No File");
break;
case CARD_ERROR_IOERROR:
sprintf(err, "Internal EXI I/O error");
break;
case CARD_ERROR_BROKEN:
sprintf(err, "File/Dir entry broken");
break;
case CARD_ERROR_EXIST:
sprintf(err, "File already exists");
break;
case CARD_ERROR_NOENT:
sprintf(err, "No empty blocks");
break;
case CARD_ERROR_INSSPACE:
sprintf(err, "Not enough space");
break;
case CARD_ERROR_NOPERM:
sprintf(err, "No permission");
break;
case CARD_ERROR_LIMIT:
sprintf(err, "Card size limit reached");
break;
case CARD_ERROR_NAMETOOLONG:
sprintf(err, "Filename too long");
break;
case CARD_ERROR_ENCODING:
sprintf(err, "Font encoding mismatch");
break;
case CARD_ERROR_CANCELED:
sprintf(err, "Card operation cancelled");
break;
case CARD_ERROR_FATAL_ERROR:
sprintf(err, "Fatal error");
break;
case CARD_ERROR_READY:
sprintf(err, "Ready");
break;
default:
sprintf(err, "Unknown");
break;
}
sprintf(msg, "MemCard Error: %s - %s", src, err);
WaitPrompt(msg);
}
void MC_DeleteMode(int slot) {
int memitems, err;
int selected = 0;
clearRightPane();
DrawText(388,160,"D e l e t e M o d e");
writeStatusBar("Choose a file with UP button or DOWN button ", "Press A button to delete ") ;
char msg[1024];
/*** Get the directory listing from the memory card ***/
memitems = CardGetDirectory (slot);
/*** If it's a blank card, get out of here ***/
if (!memitems)
{WaitPrompt ("No saved games to delete !");}
else
{
// TODO: implement showselector
selected = ShowSelector ();
if (cancel) {WaitPrompt ("delete action cancelled !");}
else{
// selected = 1;
/*** Delete the file ***/
sprintf(msg, "Deleting \"%s\"", CardList[selected].filename);
writeStatusBar(msg,"");
//WaitPrompt(msg);
CARD_Init(CardList[selected].gamecode, CardList[selected].company);
/*** Try to mount the card ***/
err = MountCard(slot);
if (err) {
WaitCardError("MCDel Mount", err);
return; /*** Unable to mount the card ***/
}
err = CARD_Delete(slot, (char *) &CardList[selected].filename);
if (err) {
WaitCardError("MCDel", err);
} else {
WaitPrompt("Delete complete");
}
CARD_Unmount(slot);
}
}
}

18
source/mcard.h Normal file
View File

@ -0,0 +1,18 @@
/****************************************************************************
* mcard support prototypes
****************************************************************************/
#ifndef _MCARDSUP_
#define _MCARDSUP_
void GCIMakeHeader();
void ExtractGCIHeader();
int MountCard(int cslot);
int CardGetDirectory (int slot);
void CardListFiles ();
int CardReadFileHeader (int slot, int id);
int CardReadFile (int slot, int id);
int CardWriteFile (int slot);
void MC_DeleteMode(int slot);
void WaitCardError(char *src, int error);
#endif

255
source/sdsupp.c Normal file
View File

@ -0,0 +1,255 @@
/****************************************************************************
* SD Card Support Functions
****************************************************************************/
#include <gccore.h>
#include <network.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
//#include <sdcard.h>
#include <fat.h>
#include <sys/dir.h>
#include "sdsupp.h"
#include "freetype.h"
#include "gci.h"
#define PAGESIZE 20
#define PADCAL 80
/*** Memory Card FileBuffer ***/
extern u8 FileBuffer[];
extern u8 filelist[1024][1024];
extern u32 maxfile;
int SDSaveMCImage (){
char filename[1024];
char tfile[40];
char company[4];
char gamecode[6];
int bytesToWrite = 0;
//sd_file *handle;
FILE *handle;
GCI thisgci;
/*** Make a copy of the Card Dir ***/
memcpy (&thisgci, FileBuffer, sizeof (GCI));
memset( tfile, 0, 40 );
company[2] = 0;
gamecode[4] = 0;
memcpy (company, &thisgci.company, 2);
memcpy (gamecode, &thisgci.gamecode, 4);
memcpy (tfile, &thisgci.filename, CARD_FILENAMELEN);
sprintf (filename, "fatX:/%s", MCSAVES);
#ifdef HW_RVL
filename[3]=48+PI_INTERNAL_SD;
#else
filename[3]=48+PI_SDGECKO_A;
#endif
mkdir(filename, S_IREAD | S_IWRITE);
sprintf (filename, "fatX:/%s/%s-%s-%s.gci", MCSAVES, company, gamecode,tfile);
#ifdef HW_RVL
filename[3]=48+PI_INTERNAL_SD;
#else
filename[3]=48+PI_SDGECKO_A;
#endif
/*** Open SD Card file ***/
//handle = SDCARD_OpenFile (filename, "wb");
handle = fopen ( filename , "wb" );
if (handle <= 0){
char msg[100];
sprintf(msg, "Couldn't save %s", filename);
WaitPrompt (msg);
return 0;
}
bytesToWrite = (thisgci.filesize8 * 8192) + MCDATAOFFSET;
//SDCARD_WriteFile (handle, FileBuffer, bytesToWrite);
//SDCARD_CloseFile (handle);
fwrite (FileBuffer , 1 , bytesToWrite , handle );
fclose (handle);
return 1;
}
int SDLoadMCImage(char *sdfilename){
//sd_file *handle;
FILE *handle;
char filename[1024];
char msg[256];
//int offset = 0;
//int bytesToRead = 0;
long bytesToRead = 0;
/*** Make fullpath filename ***/
//sprintf (filename, "dev0:\\%s\\%s", MCSAVES, sdfilename);
sprintf (filename, "fatX:/%s/%s", MCSAVES, sdfilename);
#ifdef HW_RVL
filename[3]=48+PI_INTERNAL_SD;
#else
filename[3]=48+PI_SDGECKO_A;
#endif
//SDCARD_Init ();
/*** Does this file exist ? ***/
/*if (SDCARD_SeekFile(filename, 0, SDCARD_SEEK_SET) != SDCARD_ERROR_READY){
return 0;
}*/
/*** Open the SD Card file ***/
//handle = SDCARD_OpenFile (filename, "rb");
handle = fopen ( filename , "rb" );
if (handle <= 0){
sprintf(msg, "Couldn't open %s", filename);
WaitPrompt (msg);
return 0;
}
/* if (handle == NULL){
WaitPrompt ("Unable to open file!");
return 0;
}*/
// obtain file size:
fseek (handle , 0 , SEEK_END);
bytesToRead = ftell (handle);
rewind (handle);
//bytesToRead = SDCARD_GetFileSize(handle);
if (bytesToRead <= 0){
sprintf(msg, "Incorrect file size %ld .", bytesToRead);
WaitPrompt (msg);
//WaitPrompt("Incorrect file size.");
return 0;
}
/*** Read the file ***/
//SDCARD_ReadFile (handle, FileBuffer, bytesToRead);
fread (FileBuffer,1,bytesToRead,handle);
//sprintf(msg, "Offset: %d", bytesToRead);
//WaitPrompt (msg);
/*** Close the file ***/
//SDCARD_CloseFile (handle);
fclose (handle);
return bytesToRead;
}
int SDLoadMCImageHeader(char *sdfilename){
FILE *handle;
char filename[1024];
char msg[256];
//int offset = 0;
//int bytesToRead = 0;
long bytesToRead = 0;
int header_size = 64;
/*** Make fullpath filename ***/
sprintf (filename, "fatX:/%s/%s", MCSAVES, sdfilename);
#ifdef HW_RVL
filename[3]=48+PI_INTERNAL_SD;
#else
filename[3]=48+PI_SDGECKO_A;
#endif
/*** Open the SD Card file ***/
//handle = SDCARD_OpenFile (filename, "rb");
handle = fopen ( filename , "rb" );
if (handle <= 0){
sprintf(msg, "Couldn't open %s", filename);
WaitPrompt (msg);
return 0;
}
// obtain file size:
fseek (handle , 0 , SEEK_END);
bytesToRead = ftell (handle);
rewind (handle);
if (bytesToRead < 64){//We don't want to read something smaller than the header
sprintf(msg, "Incorrect file size %ld . Not GCI File", bytesToRead);
WaitPrompt (msg);
//WaitPrompt("Incorrect file size.");
return 0;
}
/*** Read the file header ***/
fread (FileBuffer,1,header_size,handle);
/*** Close the file ***/
fclose (handle);
return bytesToRead;
}
/****************************************************************************
* SDGetFileList
*
* Get the directory listing from SD Card
****************************************************************************/
int SDGetFileList (){
int filecount = 0;
DIR_ITER * dir;
static char namefile[256*4]; // reserva espacio suficiente para UTF-8
static struct stat filestat;
char filename[1024];
sprintf (filename, "fatX:/%s/", MCSAVES);
#ifdef HW_RVL
filename[3]=48+PI_INTERNAL_SD;
#else
filename[3]=48+PI_SDGECKO_A;
#endif
dir = diropen(filename);
while(1)
{
if(dirnext(dir, namefile, &filestat)!=0) break; // si no hay mas entradas en el directorio, sal
if(filestat.st_mode & S_IFDIR) // es el nombre de un directorio
{// namefile contiene el nombre del directorio en formato UTF-8,que puede ser "." o ".." tambien
}
else
{// namefile contiene el nombre del fichero en formato UTF-8
strcpy (filelist[filecount], namefile);
filecount++;
}
}
dirclose(dir); // cierra el directorio
maxfile = filecount;
return filecount;
/* int entries = 0;
int filecount = 0;
char filename[1024];
//DIR *sddir = NULL;
DIR_ITER *sddir = NULL;
SDCARD_Init ();
sprintf (filename, "dev0:\\%s\\", MCSAVES);
entries = SDCARD_ReadDir (filename, &sddir);
while (entries){
strcpy (filelist[filecount], sddir[filecount].fname);
filecount++;
entries--;
}
free(sddir);
maxfile = filecount;
return filecount;
*/
}

6
source/sdsupp.h Normal file
View File

@ -0,0 +1,6 @@
#define MCSAVES "MCBACKUP"
int SDSaveMCImage ();
int SDLoadMCImage(char *sdfilename);
int SDLoadMCImageHeader(char *sdfilename);
int SDGetFileList ();

BIN
source/ttf/font.ttf Normal file

Binary file not shown.

BIN
source/wiibk.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 844 KiB