Adapted from my indirect coords test case.
Last active
April 18, 2021 06:28
-
-
Save Pokechu22/8396169343eab4f759cbaa279fb66d78 to your computer and use it in GitHub Desktop.
More testing for https://github.com/dolphin-emu/dolphin/pull/9651
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdbool.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <malloc.h> | |
#include <math.h> | |
#include <gccore.h> | |
#include <fat.h> | |
#include <time.h> | |
#include <sys/stat.h> | |
#include <sdcard/wiisd_io.h> | |
#include <png.h> | |
#include <zlib.h> | |
#include <ogc/consol.h> | |
#include <ogc/tpl.h> | |
#include <ogc/stm.h> | |
#include "textures_tpl.h" | |
#include "textures.h" | |
#define DEFAULT_FIFO_SIZE (256*1024) | |
#define NUM_FRAMES 4 | |
typedef struct tagcamera { | |
guVector pos; | |
guVector up; | |
guVector view; | |
}camera; | |
f32 square[] ATTRIBUTE_ALIGN(32) = | |
{ | |
// x y z | |
-50, 50, 0, // 0 | |
50, 50, 0, // 1 | |
50, -50, 0, // 2 | |
-50, -50, 0, // 3 | |
}; | |
static void *xfb = NULL; | |
static u8 *console_buffer = NULL; | |
static u32 *efb_buffer = NULL; // For screenshots | |
static uLong frame_crcs[NUM_FRAMES]; | |
static u32 do_copy = GX_FALSE; | |
GXRModeObj *rmode; | |
GXTexObj image_base_160_tex, image_base_256_tex; | |
GXTexObj image_ind_tex, image_ind_greyer_tex, image_ind_trans_tex; | |
#define NUM_BASE 2 | |
GXTexObj* base_texs[NUM_BASE] = {&image_base_160_tex, &image_base_256_tex}; | |
const char* base_names[NUM_BASE] = {"160x160", "256x256"}; | |
#define NUM_IND 3 | |
GXTexObj* ind_texs[NUM_IND] = {&image_ind_tex, &image_ind_greyer_tex, &image_ind_trans_tex}; | |
const char* ind_names[NUM_IND] = {"Normal", "Greyer", "Transp"}; | |
const char* matrix_names[2] = {"Luigi", "Ident"}; | |
TPLFile spriteTPL; | |
camera cam = {{0.0F, 0.0F, 0.0F}, | |
{0.0F, 1.0F, 0.0F}, | |
{0.0F, 0.0F, -1.0F}}; | |
static void draw_vert(u8 pos, f32 s, f32 t); | |
static void draw_square(Mtx v); | |
void run_test(int ind_stages, bool use_matrix, bool add_prev); | |
void save_screenshot(char* dir, int frame_counter, int ind_stages, bool use_matrix, bool add_prev); | |
static void save_rgba_png(char* fn, u32 *buffer, u16 width, u16 height); | |
static void copy_to_xfb(u32 count); | |
int main() { | |
Mtx p; // perspective matrix | |
GXColor background = {0, 0, 0, 0xff}; | |
VIDEO_Init(); | |
rmode = VIDEO_GetPreferredMode(NULL); | |
PAD_Init(); | |
xfb = MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode)); | |
// Characters are 16 pixels tall, and the XFB uses 2 bytes per pixel | |
console_buffer = malloc(2*rmode->fbWidth*16); | |
CON_Init(console_buffer, 0, 0, rmode->fbWidth, 16, rmode->fbWidth*VI_DISPLAY_PIX_SZ); | |
VIDEO_Configure(rmode); | |
VIDEO_SetNextFramebuffer(xfb); | |
VIDEO_SetPostRetraceCallback(copy_to_xfb); | |
VIDEO_SetBlack(FALSE); | |
VIDEO_Flush(); | |
VIDEO_WaitVSync(); | |
if(rmode->viTVMode&VI_NON_INTERLACE) VIDEO_WaitVSync(); | |
void *gp_fifo = NULL; | |
gp_fifo = MEM_K0_TO_K1(memalign(32,DEFAULT_FIFO_SIZE)); | |
memset(gp_fifo,0,DEFAULT_FIFO_SIZE); | |
GX_Init(gp_fifo,DEFAULT_FIFO_SIZE); | |
GX_SetCopyClear(background, 0x00ffffff); | |
GX_SetViewport(0,0,rmode->fbWidth,rmode->efbHeight,0,1); | |
GX_SetDispCopyYScale((f32)rmode->xfbHeight/(f32)rmode->efbHeight); | |
GX_SetScissor(0,0,rmode->fbWidth,rmode->efbHeight); | |
GX_SetDispCopySrc(0,0,rmode->fbWidth,rmode->efbHeight); | |
GX_SetDispCopyDst(rmode->fbWidth,rmode->xfbHeight); | |
GX_SetCopyFilter(rmode->aa,rmode->sample_pattern,GX_TRUE,rmode->vfilter); | |
GX_SetFieldMode(rmode->field_rendering,((rmode->viHeight==2*rmode->xfbHeight)?GX_ENABLE:GX_DISABLE)); | |
if (rmode->aa) { | |
GX_SetPixelFmt(GX_PF_RGB565_Z16, GX_ZC_LINEAR); | |
} else { | |
GX_SetPixelFmt(GX_PF_RGB8_Z24, GX_ZC_LINEAR); | |
} | |
GX_SetCullMode(GX_CULL_NONE); | |
GX_CopyDisp(xfb,GX_TRUE); | |
GX_SetDispCopyGamma(GX_GM_1_0); | |
guPerspective(p, 60, 1.33F, 10.0F, 1000.0F); | |
GX_LoadProjectionMtx(p, GX_PERSPECTIVE); | |
GX_InvalidateTexAll(); | |
TPL_OpenTPLFromMemory(&spriteTPL, (void *)textures_tpl,textures_tpl_size); | |
TPL_GetTexture(&spriteTPL,image_base_160,&image_base_160_tex); | |
TPL_GetTexture(&spriteTPL,image_base_256,&image_base_256_tex); | |
TPL_GetTexture(&spriteTPL,image_ind,&image_ind_tex); | |
TPL_GetTexture(&spriteTPL,image_ind_greyer,&image_ind_greyer_tex); | |
TPL_GetTexture(&spriteTPL,image_ind_trans,&image_ind_trans_tex); | |
fatMountSimple("sd", &__io_wiisd); | |
time_t rawtime; | |
time(&rawtime); | |
struct tm* curtime = localtime(&rawtime); | |
char screenshotfolder[100]; | |
strftime(screenshotfolder, sizeof(screenshotfolder), "sd:/Test_%H%M%S", curtime); | |
mkdir(screenshotfolder, 0777); | |
efb_buffer = malloc(rmode->fbWidth*rmode->efbHeight*sizeof(u32)); | |
printf("\x1b[30;0m\x1b[47;1m"); // Switch to black text on a white background. | |
for (u32 iteration = 0; iteration < 2*2*2; iteration++) { | |
memset(frame_crcs, 0, sizeof(frame_crcs)); | |
for (u32 frame_counter = 0; frame_counter < NUM_FRAMES; frame_counter++) { | |
// Compute configuration -- done each frame so that the loops can be swapped to make recording a FIFO easier | |
u32 number = iteration; | |
int ind_stages = (number % 2); number /= 2; | |
bool use_matrix = (number % 2); number /= 2; | |
bool add_prev = (number % 2); number /= 2; | |
// Newline first to avoid having the only visible line be blank | |
printf("\nFrame: %02d; Ind stages: %d; Matrix: %c; Add prev: %c", frame_counter, | |
ind_stages, use_matrix ? 'Y' : 'N', add_prev ? 'Y' : 'N'); | |
run_test(ind_stages, use_matrix, add_prev); | |
GX_DrawDone(); | |
save_screenshot(screenshotfolder, frame_counter, ind_stages, use_matrix, add_prev); | |
do_copy = GX_TRUE; | |
VIDEO_WaitVSync(); | |
PAD_ScanPads(); | |
if(PAD_ButtonsDown(0) & PAD_BUTTON_START) { | |
exit(0); | |
} | |
} | |
} | |
STM_ShutdownToStandby(); | |
return 0; | |
} | |
void draw_vert(u8 pos, f32 s, f32 t) { | |
GX_Position1x8(pos); | |
GX_TexCoord2f32(s*.6, t*.4); | |
} | |
void draw_square(Mtx v) { | |
Mtx m; // model matrix. | |
Mtx mv; // modelview matrix. | |
guMtxIdentity(m); | |
guMtxTransApply(m, m, 0, 0, -100); | |
guMtxConcat(v,m,mv); | |
GX_LoadPosMtxImm(mv, GX_PNMTX0); | |
GX_Begin(GX_QUADS, GX_VTXFMT0, 4); | |
draw_vert(0, 0.0, 0.0); | |
draw_vert(1, 1.0, 0.0); | |
draw_vert(2, 1.0, 1.0); | |
draw_vert(3, 0.0, 1.0); | |
GX_End(); | |
} | |
void run_test(int ind_stages, bool use_matrix, bool add_prev) { | |
Mtx v; // view matrix | |
GXTexObj* base_tex = base_texs[1]; | |
GXTexObj* ind_tex = ind_texs[0]; | |
// Actually configure and render | |
GX_SetNumChans(0); | |
GX_SetNumTexGens(1); | |
GX_SetNumIndStages(ind_stages); | |
GX_SetNumTevStages(2); | |
GX_ClearVtxDesc(); | |
GX_SetVtxDesc(GX_VA_POS, GX_INDEX8); | |
GX_SetVtxDesc(GX_VA_TEX0, GX_DIRECT); | |
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0); | |
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0); | |
GX_SetArray(GX_VA_POS, square, 3*sizeof(f32)); | |
GX_SetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY); | |
GX_SetIndTexOrder(GX_INDTEXSTAGE0, GX_TEXCOORD0, GX_TEXMAP1); | |
// This is what Luigi's Mansion does | |
f32 offset_mtx[2][3] = {{0.009765625f, 0.009765625f, 0}, {0.009765625f, 0.009765625f, 0}}; | |
GX_SetIndTexMatrix(GX_ITM_0, offset_mtx, 1); | |
GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLORNULL); | |
GX_SetTevOp(GX_TEVSTAGE0, GX_DECAL); | |
GX_SetTevDirect(GX_TEVSTAGE0); | |
//GX_SetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD0, GX_TEXMAP_NULL, GX_COLORNULL); | |
GX_SetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD0, GX_TEXMAP0, GX_COLORNULL); | |
GX_SetTevOp(GX_TEVSTAGE1, GX_DECAL); | |
GX_SetTevIndirect(GX_TEVSTAGE1, GX_INDTEXSTAGE0, GX_ITF_8, GX_ITB_STU, use_matrix ? GX_ITM_0 : GX_ITM_OFF, GX_ITW_OFF, GX_ITW_OFF, add_prev, GX_FALSE, GX_ITBA_OFF); | |
GX_LoadTexObj(base_tex, GX_TEXMAP0); | |
GX_LoadTexObj(ind_tex, GX_TEXMAP1); | |
GX_SetViewport(0,0,rmode->fbWidth,rmode->efbHeight,0,1); | |
guLookAt(v, &cam.pos, &cam.up, &cam.view); | |
GX_InvVtxCache(); | |
GX_Flush(); | |
draw_square(v); | |
} | |
void save_screenshot(char* dir, int frame_counter, int ind_stages, bool use_matrix, bool add_prev) { | |
// Based on Open Homebrew Channel code (GPLv2): | |
// https://github.com/fail0verflow/hbc/blob/a8e5f6c0f7e484c7f7112967eee6eee47b27d9ac/channel/channelapp/source/gfx.c#L506-L538 | |
// https://github.com/fail0verflow/hbc/blob/a8e5f6c0f7e484c7f7112967eee6eee47b27d9ac/channel/channelapp/source/view.c#L252-L269 | |
u16 x, y; | |
GXColor c; | |
u32 val; | |
u32 *p = efb_buffer; | |
for (y = 0; y < rmode->efbHeight; ++y) { | |
for (x = 0; x < rmode->fbWidth; ++x) { | |
GX_PeekARGB(x, y, &c); | |
val = ((u32) c.a) << 24; | |
val |= ((u32) c.r) << 16; | |
val |= ((u32) c.g) << 8; | |
val |= c.b; | |
*p++ = val; | |
} | |
} | |
uLong crc = crc32(0L, Z_NULL, 0); | |
crc = crc32(crc, (u8*)efb_buffer, rmode->fbWidth*rmode->efbHeight*sizeof(u32)); | |
frame_crcs[frame_counter] = crc; | |
// Check if the screenshot matches. | |
for (u32 i = 0; i < frame_counter; i++) { | |
if (frame_crcs[i] == crc) { | |
// This result has already been seen | |
return; | |
} | |
} | |
char filename[256]; | |
snprintf(filename, sizeof(filename), "%s/F%02d_%d%c%c.png", | |
dir, frame_counter, ind_stages, use_matrix ? 'Y' : 'N', add_prev ? 'Y' : 'N'); | |
save_rgba_png(filename, efb_buffer, rmode->fbWidth, rmode->efbHeight); | |
} | |
static void save_rgba_png(char* fn, u32 *buffer, u16 width, u16 height) { | |
// Code from Open Homebrew Channel (with x -> width and y -> height): | |
// https://github.com/fail0verflow/hbc/blob/a8e5f6c0f7e484c7f7112967eee6eee47b27d9ac/channel/channelapp/source/tex.c#L182-L261 | |
FILE *fp = NULL; | |
png_structp png_ptr = NULL; | |
png_infop info_ptr; | |
png_bytep *row_pointers; | |
u16 i; | |
row_pointers = (png_bytep *) malloc(height * sizeof(png_bytep)); | |
fp = fopen(fn, "wb"); | |
if (!fp) { | |
// gprintf("couldnt open %s for writing\n", fn); | |
goto exit; | |
} | |
setbuf(fp, NULL); | |
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0); | |
if (!png_ptr) { | |
// gprintf ("png_create_write_struct failed\n"); | |
goto exit; | |
} | |
info_ptr = png_create_info_struct(png_ptr); | |
if (!info_ptr) { | |
// gprintf ("png_create_info_struct failed\n"); | |
goto exit; | |
} | |
if (setjmp(png_jmpbuf(png_ptr))) { | |
// gprintf ("setjmp failed\n"); | |
goto exit; | |
} | |
png_init_io(png_ptr, fp); | |
png_set_compression_level(png_ptr, Z_BEST_COMPRESSION); | |
png_set_IHDR(png_ptr, info_ptr, width, height, 8, | |
PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE, | |
PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); | |
png_write_info(png_ptr, info_ptr); | |
for (i = 0; i < height; ++i) | |
row_pointers[i] = (png_bytep) (buffer + i * width); | |
png_set_swap_alpha(png_ptr); | |
png_write_image(png_ptr, row_pointers); | |
png_write_end(png_ptr, info_ptr); | |
// gprintf("saved %s\n", fn); | |
exit: | |
if (png_ptr) | |
png_destroy_write_struct(&png_ptr, (png_infopp)NULL); | |
free(row_pointers); | |
fclose(fp); | |
} | |
// copy efb to xfb when ready | |
static void copy_to_xfb(u32 count) { | |
if(do_copy==GX_TRUE) { | |
GX_SetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE); | |
GX_SetColorUpdate(GX_TRUE); | |
GX_CopyDisp(xfb,GX_TRUE); | |
GX_Flush(); | |
// Display the console at the top... by copying it into the xfb. | |
// This requires "defer EFB copies to RAM" to be unchecked in Dolphin. | |
// It does not work on the FIFO player at all. | |
for (int i = 0; i < 6; i++) { | |
// Loop is needed to make things show up properly on hardware | |
// Otherwise it just ends up getting cut off in a weird way. | |
// This might just be a timing thing and not something related to the framebuffer? | |
memcpy(xfb+2*rmode->fbWidth*16, console_buffer, 2*rmode->fbWidth*16); | |
} | |
// This one doesn't need to be in a loop (though it is influenced by the number | |
// of times the above loop runs) | |
memcpy(xfb+2*rmode->fbWidth*448, console_buffer, 2*rmode->fbWidth*16); | |
do_copy = GX_FALSE; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Original implementation (bash), didn't give very nice results | |
# function compareImages { | |
# # $1 is input dir 1, $2 is input dir 2, $3 is output dir | |
# for file in $(cd $1; ls *.png); do | |
# # Uses imagemagick | |
# compare $1/$file $2/$file $3/$file | |
# done | |
# } | |
# I also tried https://stackoverflow.com/a/8505681 but it was WAY too slow | |
# From https://stackoverflow.com/a/45362102 | |
import cv2 | |
import os | |
import sys | |
assert len(sys.argv) == 4 | |
dira = sys.argv[1] | |
dirb = sys.argv[2] | |
outdir = sys.argv[3] | |
for f in os.listdir(dira): | |
if f.lower().endswith("png"): | |
a = cv2.imread(os.path.join(dira, f)) | |
b = cv2.imread(os.path.join(dirb, f)) | |
cv2.imwrite(os.path.join(outdir, f), cv2.bitwise_xor(a, b)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#--------------------------------------------------------------------------------- | |
# Clear the implicit built in rules | |
#--------------------------------------------------------------------------------- | |
.SUFFIXES: | |
.SECONDARY: | |
#--------------------------------------------------------------------------------- | |
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)) | |
BUILD := build | |
SOURCES := . | |
DATA := | |
TEXTURES := . | |
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 := -logc -lm -lfat -lpng -lz | |
#--------------------------------------------------------------------------------- | |
# list of directories containing libraries, this must be the top level containing | |
# include and lib | |
#--------------------------------------------------------------------------------- | |
LIBDIRS := $(PORTLIBS) | |
#--------------------------------------------------------------------------------- | |
# 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)) \ | |
$(foreach dir,$(TEXTURES),$(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)/*.*))) | |
SCFFILES := $(foreach dir,$(TEXTURES),$(notdir $(wildcard $(dir)/*.scf))) | |
TPLFILES := $(SCFFILES:.scf=.tpl) | |
#--------------------------------------------------------------------------------- | |
# use CXX for linking C++ projects, CC for standard C | |
#--------------------------------------------------------------------------------- | |
ifeq ($(strip $(CPPFILES)),) | |
export LD := $(CC) | |
else | |
export LD := $(CXX) | |
endif | |
export OFILES_BIN := $(addsuffix .o,$(BINFILES)) $(addsuffix .o,$(TPLFILES)) | |
export OFILES_SOURCES := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(sFILES:.s=.o) $(SFILES:.S=.o) | |
export OFILES := $(OFILES_BIN) $(OFILES_SOURCES) | |
export HFILES := $(addsuffix .h,$(subst .,_,$(BINFILES))) $(addsuffix .h,$(subst .,_,$(TPLFILES))) | |
#--------------------------------------------------------------------------------- | |
# 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 | |
#--------------------------------------------------------------------------------- | |
else | |
#--------------------------------------------------------------------------------- | |
# main targets | |
#--------------------------------------------------------------------------------- | |
$(OUTPUT).dol: $(OUTPUT).elf | |
$(OUTPUT).elf: $(OFILES) | |
$(OFILES_SOURCES) : $(HFILES) | |
#--------------------------------------------------------------------------------- | |
# This rule links in binary data with the .bin extension | |
#--------------------------------------------------------------------------------- | |
%.bin.o %_bin.h : %.bin | |
#--------------------------------------------------------------------------------- | |
@echo $(notdir $<) | |
@$(bin2o) | |
#--------------------------------------------------------------------------------- | |
%.tpl.o %_tpl.h : %.tpl | |
#--------------------------------------------------------------------------------- | |
@echo $(notdir $<) | |
@$(bin2o) | |
-include $(DEPSDIR)/*.d | |
#--------------------------------------------------------------------------------- | |
endif | |
#--------------------------------------------------------------------------------- | |
#--------------------------------------------------------------------------------- | |
run: | |
wiiload $(TARGET).dol |
View raw
(Sorry about that, but we can’t show files that are this big right now.)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment