├── .gitignore ├── Makefile ├── asm ├── clr_blend_fast.s ├── clr_fade_fast.s ├── div_lut.s ├── sin_lut.s ├── tonc_bios.s ├── tonc_bios_ex.s ├── tonc_isr_master.s ├── tonc_isr_nest.s ├── tonc_memcpy.s ├── tonc_memset.s └── tonc_nocash.s ├── base.c ├── base.h ├── include ├── tonc.h ├── tonc_asminc.h ├── tonc_bios.h ├── tonc_core.h ├── tonc_input.h ├── tonc_irq.h ├── tonc_legacy.h ├── tonc_libgba.h ├── tonc_math.h ├── tonc_memdef.h ├── tonc_memmap.h ├── tonc_nocash.h ├── tonc_oam.h ├── tonc_surface.h ├── tonc_text.h ├── tonc_tte.h ├── tonc_types.h └── tonc_video.h ├── libtonc.dox ├── libtonc.txt ├── src ├── font │ ├── sys8.png │ ├── sys8.s │ ├── verdana10.png │ ├── verdana10.s │ ├── verdana9.png │ ├── verdana9.s │ ├── verdana9_b4.png │ ├── verdana9_b4.s │ ├── verdana9b.png │ ├── verdana9b.s │ ├── verdana9i.png │ └── verdana9i.s ├── pre1.3 │ ├── tonc_bitmap.c │ ├── tonc_text.c │ ├── tonc_text_bm.c │ ├── tonc_text_map.c │ ├── tonc_text_oam.c │ └── toncfont.s ├── tonc_bg.c ├── tonc_bg_affine.c ├── tonc_bmp16.c ├── tonc_bmp8.c ├── tonc_color.c ├── tonc_core.c ├── tonc_input.c ├── tonc_irq.c ├── tonc_math.c ├── tonc_oam.c ├── tonc_obj_affine.c ├── tonc_sbmp16.c ├── tonc_sbmp8.c ├── tonc_schr4c.c ├── tonc_schr4r.c ├── tonc_surface.c ├── tonc_video.c └── tte │ ├── ase_drawg.c │ ├── bmp16_drawg.c │ ├── bmp16_drawg_b1cs.c │ ├── bmp8_drawg.c │ ├── bmp8_drawg_b1cs.c │ ├── bmp8_drawg_b1cts_fast.s │ ├── chr4c_drawg_b1cts.c │ ├── chr4c_drawg_b1cts_fast.s │ ├── chr4c_drawg_b4cts.c │ ├── chr4c_drawg_b4cts_fast.s │ ├── chr4r_drawg_b1cts.c │ ├── chr4r_drawg_b1cts_fast.s │ ├── obj_drawg.c │ ├── se_drawg.c │ ├── tte_init_ase.c │ ├── tte_init_bmp.c │ ├── tte_init_chr4c.c │ ├── tte_init_chr4r.c │ ├── tte_init_obj.c │ ├── tte_init_se.c │ ├── tte_iohook.c │ ├── tte_main.c │ └── tte_types.s ├── todo.txt └── toncfont.bmp /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | lib 3 | *.bz2 4 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Makefile for tonclib. 3 | # 4 | 5 | #--------------------------------------------------------------------------------- 6 | .SUFFIXES: 7 | #--------------------------------------------------------------------------------- 8 | 9 | ifeq ($(strip $(DEVKITARM)),) 10 | $(error "Please set DEVKITARM in your environment. export DEVKITARM=devkitARM) 11 | endif 12 | ifeq ($(strip $(DEVKITPRO)),) 13 | $(error "Please set DEVKITPRO in your environment. export DEVKITPRO=devkitPro) 14 | endif 15 | include $(DEVKITARM)/gba_rules 16 | 17 | BUILD := build 18 | SRCDIRS := asm src src/font src/tte src/pre1.3 19 | INCDIRS := include 20 | DATADIRS := data 21 | 22 | DATESTRING := $(shell date +%Y)$(shell date +%m)$(shell date +%d) 23 | 24 | ARCH := -mthumb -mthumb-interwork 25 | RARCH := -mthumb-interwork -mthumb 26 | IARCH := -mthumb-interwork -marm 27 | 28 | bTEMPS := 0 # Save gcc temporaries (.i and .s files) 29 | bDEBUG2 := 0 # Generate debug info (bDEBUG2? Not a full DEBUG flag. Yet) 30 | 31 | VERSION := 1.4.3 32 | 33 | #--------------------------------------------------------------------------------- 34 | # Options for code generation 35 | #--------------------------------------------------------------------------------- 36 | 37 | CBASE := $(INCLUDE) -Wall -fno-strict-aliasing #-fno-tree-loop-optimize 38 | CBASE += -O2 39 | 40 | RCFLAGS := $(CBASE) $(RARCH) 41 | ICFLAGS := $(CBASE) $(IARCH) -mlong-calls #-fno-gcse 42 | CFLAGS := $(RCFLAGS) 43 | 44 | ASFLAGS := $(INCLUDE) -Wa,--warn $(ARCH) 45 | 46 | # --- Save temporary files ? --- 47 | ifeq ($(strip $(bTEMPS)), 1) 48 | RCFLAGS += -save-temps 49 | ICFLAGS += -save-temps 50 | CFLAGS += -save-temps 51 | CXXFLAGS += -save-temps 52 | endif 53 | 54 | # --- Debug info ? --- 55 | 56 | ifeq ($(strip $(bDEBUG2)), 1) 57 | CFLAGS += -g 58 | LDFLAGS += -g 59 | endif 60 | 61 | #--------------------------------------------------------------------------------- 62 | # Path to tools - this can be deleted if you set the path in windows 63 | #--------------------------------------------------------------------------------- 64 | 65 | export PATH := $(DEVKITARM)/bin:$(PATH) 66 | 67 | #--------------------------------------------------------------------------------- 68 | 69 | ifneq ($(BUILD),$(notdir $(CURDIR))) 70 | 71 | export TARGET := $(CURDIR)/lib/libtonc.a 72 | 73 | export VPATH := $(foreach dir,$(DATADIRS),$(CURDIR)/$(dir)) $(foreach dir,$(SRCDIRS),$(CURDIR)/$(dir)) 74 | 75 | ICFILES := $(foreach dir,$(SRCDIRS),$(notdir $(wildcard $(dir)/*.iwram.c))) 76 | RCFILES := $(foreach dir,$(SRCDIRS),$(notdir $(wildcard $(dir)/*.c))) 77 | CFILES := $(ICFILES) $(RCFILES) 78 | 79 | SFILES := $(foreach dir,$(SRCDIRS),$(notdir $(wildcard $(dir)/*.s))) 80 | BINFILES := $(foreach dir,$(DATADIRS),$(notdir $(wildcard $(dir)/*.*))) 81 | 82 | export OFILES := $(addsuffix .o,$(BINFILES)) $(CFILES:.c=.o) $(SFILES:.s=.o) 83 | export INCLUDE := $(foreach dir,$(INCDIRS),-I$(CURDIR)/$(dir)) 84 | export DEPSDIR := $(CURDIR)/build 85 | 86 | .PHONY: $(BUILD) clean docs 87 | 88 | $(BUILD): 89 | @[ -d lib ] || mkdir -p lib 90 | @[ -d $@ ] || mkdir -p $@ 91 | @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile 92 | 93 | docs: 94 | doxygen libtonc.dox 95 | 96 | clean: 97 | @echo clean ... 98 | @rm -fr $(BUILD) 99 | 100 | install: 101 | @mkdir -p $(DESTDIR)$(DEVKITPRO)/libtonc/lib 102 | @cp -rv include $(DESTDIR)$(DEVKITPRO)/libtonc/include 103 | @cp -v lib/libtonc.a $(DESTDIR)$(DEVKITPRO)/libtonc/lib/ 104 | 105 | #------------------------------------------------------------------------------- 106 | dist: 107 | #------------------------------------------------------------------------------- 108 | @tar -cvjf libtonc-src-$(VERSION).tar.bz2 asm src include \ 109 | Makefile todo.txt libtonc.dox base.c base.h 110 | 111 | #--------------------------------------------------------------------------------- 112 | 113 | else 114 | 115 | DEPENDS := $(OFILES:.o=.d) 116 | 117 | #--------------------------------------------------------------------------------- 118 | 119 | %.a : 120 | 121 | $(TARGET): $(OFILES) 122 | 123 | %.a : $(OFILES) 124 | @echo Building $@ 125 | @rm -f $@ 126 | @$(AR) -crs $@ $^ 127 | $(PREFIX)nm -Sn $@ > $(basename $(notdir $@)).map 128 | 129 | %.iwram.o : %.iwram.c 130 | @echo $(notdir $<) 131 | $(CC) -MMD -MP -MF $(DEPSDIR)/$(@:.o=.d) $(ICFLAGS) -c $< -o $@ 132 | 133 | %.o : %.c 134 | @echo $(notdir $<) 135 | $(CC) -MMD -MP -MF $(DEPSDIR)/$*.d $(RCFLAGS) -c $< -o $@ 136 | 137 | -include $(DEPENDS) 138 | 139 | endif 140 | 141 | #--------------------------------------------------------------------------------- 142 | -------------------------------------------------------------------------------- /asm/clr_blend_fast.s: -------------------------------------------------------------------------------- 1 | // 2 | // Color blend with 33 alpha levels 3 | // 4 | //! \file tonc_memcpy.s 5 | //! \author J Vijn 6 | //! \date 20071130 - 20090801 7 | 8 | #include "tonc_asminc.h" 9 | 10 | #ifndef CLR_ROUND 11 | #define CLR_ROUND 1 12 | #endif 13 | 14 | /* 15 | void clr_blend_fast(COLOR *srca, COLOR *srcb, COLOR *dst, 16 | int nclrs, u32 alpha) IWRAM_CODE; 17 | */ 18 | //! Blends color arrays \a srca and \a srcb into \a dst. 19 | /*! \param srca Source array A. 20 | \param srcb Source array B 21 | \param dst Destination array. 22 | \param nclrs Number of colors. 23 | \param alpha Blend weight (range: 0-32). 24 | \note u32 version, 2 clrs/loop. Loop: 18i/32c, Barrel shifter FTW. 25 | \note Properly rounds the blending. If you don't want that, remove 26 | the references to lr. 27 | */ 28 | BEGIN_FUNC_ARM(clr_blend_fast, CSEC_IWRAM) 29 | movs r3, r3, lsr #1 @ adjust nclrs for u32 run 30 | bxeq lr @ quit on nclrs=0 31 | ldr r12, [sp] @ get alpha from stack 32 | stmfd sp!, {r4-r10, lr} 33 | #if(CLR_ROUND==1) 34 | ldr lr, =0x00200401 @ -1-|1-1 35 | rsb r7, lr, lr, lsl #5 @ MASKLO: -g-|b-r 36 | #else 37 | ldr r7, =0x03E07C1F @ MASKLO: -g-|b-r 38 | #endif 39 | mov r6, r7, lsl #5 @ MASKHI: g-|b-r- 40 | .Lbld_fast_loop: 41 | ldr r8, [r0], #4 @ a= *pa++ 42 | ldr r9, [r1], #4 @ b= *pb++ 43 | @ --- -g-|b-r 44 | and r4, r6, r8, lsl #5 @ x/32: (-g-|b-r) 45 | and r5, r7, r9 @ y: -g-|b-r 46 | sub r5, r5, r4, lsr #5 @ z: y-x 47 | mla r4, r5, r12, r4 @ z: (y-x)*w + x*32 48 | #if(CLR_ROUND==1) 49 | add r4, r4, lr, lsl #4 @ round 50 | #endif 51 | and r10, r7, r4, lsr #5 @ blend(-g-|b-r) 52 | @ --- b-r|-g- (rotated by 16 for great awesome) 53 | and r4, r6, r8, ror #11 @ x/32: -g-|b-r (ror16) 54 | and r5, r7, r9, ror #16 @ y: -g-|b-r (ror16) 55 | sub r5, r5, r4, lsr #5 @ z: y-x 56 | mla r4, r5, r12, r4 @ z: (y-x)*w + x*32 57 | #if(CLR_ROUND==1) 58 | add r4, r4, lr, lsl #4 @ round 59 | #endif 60 | and r4, r7, r4, lsr #5 @ blend(-g-|b-r (ror16)) 61 | @ --- mix -g-|b-r and b-r|-g- 62 | orr r10, r10, r4, ror #16 63 | @ --- write blended, loop 64 | str r10, [r2], #4 @ *dst++= c 65 | subs r3, r3, #1 66 | bgt .Lbld_fast_loop 67 | ldmfd sp!, {r4-r10, lr} 68 | bx lr 69 | END_FUNC(clr_blend_fast) 70 | 71 | 72 | @ EOF 73 | -------------------------------------------------------------------------------- /asm/clr_fade_fast.s: -------------------------------------------------------------------------------- 1 | // 2 | // Color fade with 33 alpha levels 3 | // 4 | //! \file tonc_memcpy.s 5 | //! \author J Vijn 6 | //! \date 20071130 - 20071130 7 | 8 | #include "tonc_asminc.h" 9 | 10 | #ifndef CLR_ROUND 11 | #define CLR_ROUND 1 12 | #endif 13 | 14 | /* 15 | void clr_fade_fast(COLOR *src, COLOR clr, COLOR *dst, 16 | int nclrs, u32 alpha) IWRAM_CODE; 17 | */ 18 | //! Fades color arrays \a srca to \a clr into \a dst. 19 | /*! \param src Source array. 20 | * \param clr Final color (at alpha=32). 21 | * \param dst Destination array. 22 | * \param nclrs Number of colors. 23 | * \param alpha Blend weight (range: 0-32). 24 | * \note u32 version, 2 clrs/loop. Loop: 18i/32c, Barrel shifter FTW. 25 | */ 26 | .section .iwram,"ax", %progbits 27 | .align 2 28 | .arm 29 | .global clr_fade_fast 30 | clr_fade_fast: 31 | movs r3, r3, lsr #1 @ adjust nclrs for u32 run 32 | bxeq lr @ quit on nclrs=0 33 | ldr r12, [sp] @ get alpha from stack 34 | stmfd sp!, {r4-r10, lr} 35 | #if(CLR_ROUND==1) 36 | ldr lr, =0x00200401 @ -1-|1-1 37 | rsb r7, lr, lr, lsl #5 @ MASKLO: -g-|b-r 38 | #else 39 | ldr r7, =0x03E07C1F @ MASKLO: -g-|b-r 40 | #endif 41 | mov r6, r7, lsl #5 @ MASKHI: g-|b-r- 42 | 43 | @ Precalc y1 and y2 44 | orr r1, r1, r1, lsl #16 45 | and r9, r7, r1, ror #16 @ precalc: y2= -g-|b-r (ror16) 46 | and r1, r7, r1 @ precalc: y1= -g-|b-r 47 | .Lfade_fast_loop: 48 | ldr r8, [r0], #4 @ a= *pa++ 49 | @ --- -g-|b-r 50 | and r4, r6, r8, lsl #5 @ x/32: (-g-|b-r) 51 | sub r5, r1, r4, lsr #5 @ z: y1-x 52 | mla r4, r5, r12, r4 @ z: (y1-x)*w + x*32 53 | #if(CLR_ROUND==1) 54 | add r4, r4, lr, lsl #4 @ round 55 | #endif 56 | and r10, r7, r4, lsr #5 @ blend(-g-|b-r) 57 | @ --- b-r|-g- (rotated by 16 for great awesome) 58 | and r4, r6, r8, ror #11 @ x/32: -g-|b-r (ror16) 59 | sub r5, r9, r4, lsr #5 @ z: y2-x 60 | mla r4, r5, r12, r4 @ z: (y2-x)*w + x*32 61 | #if(CLR_ROUND==1) 62 | add r4, r4, lr, lsl #4 @ round 63 | #endif 64 | and r4, r7, r4, lsr #5 @ blend(-g-|b-r (ror16)) 65 | @ --- mix -g-|b-r and b-r|-g- 66 | orr r10, r10, r4, ror #16 67 | @ --- write faded, loop 68 | str r10, [r2], #4 @ *dst++= c 69 | subs r3, r3, #1 70 | bgt .Lfade_fast_loop 71 | ldmfd sp!, {r4-r10, lr} 72 | bx lr 73 | 74 | @ EOF 75 | -------------------------------------------------------------------------------- /asm/div_lut.s: -------------------------------------------------------------------------------- 1 | @ ====================================================================== 2 | @ Look-Up Tables 3 | @ div_lut: ceil(2^16/x) 4 | @ 5 | @ Exported by Cearn's excellut v1.0 6 | @ (comments, kudos, flames to daytshen@hotmail.com) 7 | @ 8 | @ ====================================================================== 9 | 10 | .section .rodata 11 | @ ----------------------------------------------------------------------- 12 | @ div_lut: a 257 long LUT of 32bit values in 16.16 format 13 | @ ceil(1/x) 14 | .global div_lut 15 | .align 2 16 | div_lut: 17 | .word 0x7FFFFFFF,0x00010000,0x00008000,0x00005556,0x00004000,0x00003334,0x00002AAB,0x00002493 18 | .word 0x00002000,0x00001C72,0x0000199A,0x00001746,0x00001556,0x000013B2,0x0000124A,0x00001112 19 | .word 0x00001000,0x00000F10,0x00000E39,0x00000D7A,0x00000CCD,0x00000C31,0x00000BA3,0x00000B22 20 | .word 0x00000AAB,0x00000A3E,0x000009D9,0x0000097C,0x00000925,0x000008D4,0x00000889,0x00000843 21 | .word 0x00000800,0x000007C2,0x00000788,0x00000751,0x0000071D,0x000006EC,0x000006BD,0x00000691 22 | .word 0x00000667,0x0000063F,0x00000619,0x000005F5,0x000005D2,0x000005B1,0x00000591,0x00000573 23 | .word 0x00000556,0x0000053A,0x0000051F,0x00000506,0x000004ED,0x000004D5,0x000004BE,0x000004A8 24 | .word 0x00000493,0x0000047E,0x0000046A,0x00000457,0x00000445,0x00000433,0x00000422,0x00000411 25 | 26 | .word 0x00000400,0x000003F1,0x000003E1,0x000003D3,0x000003C4,0x000003B6,0x000003A9,0x0000039C 27 | .word 0x0000038F,0x00000382,0x00000376,0x0000036A,0x0000035F,0x00000354,0x00000349,0x0000033E 28 | .word 0x00000334,0x0000032A,0x00000320,0x00000316,0x0000030D,0x00000304,0x000002FB,0x000002F2 29 | .word 0x000002E9,0x000002E1,0x000002D9,0x000002D1,0x000002C9,0x000002C1,0x000002BA,0x000002B2 30 | .word 0x000002AB,0x000002A4,0x0000029D,0x00000296,0x00000290,0x00000289,0x00000283,0x0000027D 31 | .word 0x00000277,0x00000271,0x0000026B,0x00000265,0x0000025F,0x0000025A,0x00000254,0x0000024F 32 | .word 0x0000024A,0x00000244,0x0000023F,0x0000023A,0x00000235,0x00000231,0x0000022C,0x00000227 33 | .word 0x00000223,0x0000021E,0x0000021A,0x00000215,0x00000211,0x0000020D,0x00000209,0x00000205 34 | 35 | .word 0x00000200,0x000001FD,0x000001F9,0x000001F5,0x000001F1,0x000001ED,0x000001EA,0x000001E6 36 | .word 0x000001E2,0x000001DF,0x000001DB,0x000001D8,0x000001D5,0x000001D1,0x000001CE,0x000001CB 37 | .word 0x000001C8,0x000001C4,0x000001C1,0x000001BE,0x000001BB,0x000001B8,0x000001B5,0x000001B3 38 | .word 0x000001B0,0x000001AD,0x000001AA,0x000001A7,0x000001A5,0x000001A2,0x0000019F,0x0000019D 39 | .word 0x0000019A,0x00000198,0x00000195,0x00000193,0x00000190,0x0000018E,0x0000018B,0x00000189 40 | .word 0x00000187,0x00000184,0x00000182,0x00000180,0x0000017E,0x0000017B,0x00000179,0x00000177 41 | .word 0x00000175,0x00000173,0x00000171,0x0000016F,0x0000016D,0x0000016B,0x00000169,0x00000167 42 | .word 0x00000165,0x00000163,0x00000161,0x0000015F,0x0000015D,0x0000015B,0x00000159,0x00000158 43 | 44 | .word 0x00000156,0x00000154,0x00000152,0x00000151,0x0000014F,0x0000014D,0x0000014B,0x0000014A 45 | .word 0x00000148,0x00000147,0x00000145,0x00000143,0x00000142,0x00000140,0x0000013F,0x0000013D 46 | .word 0x0000013C,0x0000013A,0x00000139,0x00000137,0x00000136,0x00000134,0x00000133,0x00000131 47 | .word 0x00000130,0x0000012F,0x0000012D,0x0000012C,0x0000012A,0x00000129,0x00000128,0x00000126 48 | .word 0x00000125,0x00000124,0x00000122,0x00000121,0x00000120,0x0000011F,0x0000011D,0x0000011C 49 | .word 0x0000011B,0x0000011A,0x00000119,0x00000117,0x00000116,0x00000115,0x00000114,0x00000113 50 | .word 0x00000112,0x00000110,0x0000010F,0x0000010E,0x0000010D,0x0000010C,0x0000010B,0x0000010A 51 | .word 0x00000109,0x00000108,0x00000107,0x00000106,0x00000105,0x00000104,0x00000103,0x00000102 52 | .word 0x00000100 53 | 54 | .size div_lut, .-div_lut -------------------------------------------------------------------------------- /asm/sin_lut.s: -------------------------------------------------------------------------------- 1 | @ ====================================================================== 2 | @ Look-Up Tables 3 | @ sin_lut: sin(x*pi/256) 4 | @ 5 | @ Exported by Cearn's excellut v1.0 6 | @ (comments, kudos, flames to daytshen@hotmail.com) 7 | @ 8 | @ ====================================================================== 9 | 10 | .section .rodata 11 | @ ----------------------------------------------------------------------- 12 | @ sin_lut: a 514 long LUT of 16bit values in 4.12 format 13 | @ sin(x*pi/256) 14 | .global sin_lut 15 | .align 2 16 | sin_lut: 17 | .hword 0x0000,0x0032,0x0064,0x0096,0x00C8,0x00FB,0x012D,0x015F 18 | .hword 0x0191,0x01C3,0x01F5,0x0227,0x0259,0x028A,0x02BC,0x02ED 19 | .hword 0x031F,0x0350,0x0381,0x03B2,0x03E3,0x0413,0x0444,0x0474 20 | .hword 0x04A5,0x04D5,0x0504,0x0534,0x0563,0x0593,0x05C2,0x05F0 21 | .hword 0x061F,0x064D,0x067B,0x06A9,0x06D7,0x0704,0x0731,0x075E 22 | .hword 0x078A,0x07B7,0x07E2,0x080E,0x0839,0x0864,0x088F,0x08B9 23 | .hword 0x08E3,0x090D,0x0936,0x095F,0x0987,0x09B0,0x09D7,0x09FF 24 | .hword 0x0A26,0x0A4D,0x0A73,0x0A99,0x0ABE,0x0AE3,0x0B08,0x0B2C 25 | 26 | .hword 0x0B50,0x0B73,0x0B96,0x0BB8,0x0BDA,0x0BFC,0x0C1D,0x0C3E 27 | .hword 0x0C5E,0x0C7D,0x0C9D,0x0CBB,0x0CD9,0x0CF7,0x0D14,0x0D31 28 | .hword 0x0D4D,0x0D69,0x0D84,0x0D9F,0x0DB9,0x0DD2,0x0DEB,0x0E04 29 | .hword 0x0E1C,0x0E33,0x0E4A,0x0E60,0x0E76,0x0E8B,0x0EA0,0x0EB4 30 | .hword 0x0EC8,0x0EDB,0x0EED,0x0EFF,0x0F10,0x0F21,0x0F31,0x0F40 31 | .hword 0x0F4F,0x0F5D,0x0F6B,0x0F78,0x0F85,0x0F91,0x0F9C,0x0FA7 32 | .hword 0x0FB1,0x0FBA,0x0FC3,0x0FCB,0x0FD3,0x0FDA,0x0FE1,0x0FE7 33 | .hword 0x0FEC,0x0FF0,0x0FF4,0x0FF8,0x0FFB,0x0FFD,0x0FFE,0x0FFF 34 | 35 | .hword 0x1000,0x0FFF,0x0FFE,0x0FFD,0x0FFB,0x0FF8,0x0FF4,0x0FF0 36 | .hword 0x0FEC,0x0FE7,0x0FE1,0x0FDA,0x0FD3,0x0FCB,0x0FC3,0x0FBA 37 | .hword 0x0FB1,0x0FA7,0x0F9C,0x0F91,0x0F85,0x0F78,0x0F6B,0x0F5D 38 | .hword 0x0F4F,0x0F40,0x0F31,0x0F21,0x0F10,0x0EFF,0x0EED,0x0EDB 39 | .hword 0x0EC8,0x0EB4,0x0EA0,0x0E8B,0x0E76,0x0E60,0x0E4A,0x0E33 40 | .hword 0x0E1C,0x0E04,0x0DEB,0x0DD2,0x0DB9,0x0D9F,0x0D84,0x0D69 41 | .hword 0x0D4D,0x0D31,0x0D14,0x0CF7,0x0CD9,0x0CBB,0x0C9D,0x0C7D 42 | .hword 0x0C5E,0x0C3E,0x0C1D,0x0BFC,0x0BDA,0x0BB8,0x0B96,0x0B73 43 | 44 | .hword 0x0B50,0x0B2C,0x0B08,0x0AE3,0x0ABE,0x0A99,0x0A73,0x0A4D 45 | .hword 0x0A26,0x09FF,0x09D7,0x09B0,0x0987,0x095F,0x0936,0x090D 46 | .hword 0x08E3,0x08B9,0x088F,0x0864,0x0839,0x080E,0x07E2,0x07B7 47 | .hword 0x078A,0x075E,0x0731,0x0704,0x06D7,0x06A9,0x067B,0x064D 48 | .hword 0x061F,0x05F0,0x05C2,0x0593,0x0563,0x0534,0x0504,0x04D5 49 | .hword 0x04A5,0x0474,0x0444,0x0413,0x03E3,0x03B2,0x0381,0x0350 50 | .hword 0x031F,0x02ED,0x02BC,0x028A,0x0259,0x0227,0x01F5,0x01C3 51 | .hword 0x0191,0x015F,0x012D,0x00FB,0x00C8,0x0096,0x0064,0x0032 52 | 53 | .hword 0x0000,0xFFCE,0xFF9C,0xFF6A,0xFF38,0xFF05,0xFED3,0xFEA1 54 | .hword 0xFE6F,0xFE3D,0xFE0B,0xFDD9,0xFDA7,0xFD76,0xFD44,0xFD13 55 | .hword 0xFCE1,0xFCB0,0xFC7F,0xFC4E,0xFC1D,0xFBED,0xFBBC,0xFB8C 56 | .hword 0xFB5B,0xFB2B,0xFAFC,0xFACC,0xFA9D,0xFA6D,0xFA3E,0xFA10 57 | .hword 0xF9E1,0xF9B3,0xF985,0xF957,0xF929,0xF8FC,0xF8CF,0xF8A2 58 | .hword 0xF876,0xF849,0xF81E,0xF7F2,0xF7C7,0xF79C,0xF771,0xF747 59 | .hword 0xF71D,0xF6F3,0xF6CA,0xF6A1,0xF679,0xF650,0xF629,0xF601 60 | .hword 0xF5DA,0xF5B3,0xF58D,0xF567,0xF542,0xF51D,0xF4F8,0xF4D4 61 | 62 | .hword 0xF4B0,0xF48D,0xF46A,0xF448,0xF426,0xF404,0xF3E3,0xF3C2 63 | .hword 0xF3A2,0xF383,0xF363,0xF345,0xF327,0xF309,0xF2EC,0xF2CF 64 | .hword 0xF2B3,0xF297,0xF27C,0xF261,0xF247,0xF22E,0xF215,0xF1FC 65 | .hword 0xF1E4,0xF1CD,0xF1B6,0xF1A0,0xF18A,0xF175,0xF160,0xF14C 66 | .hword 0xF138,0xF125,0xF113,0xF101,0xF0F0,0xF0DF,0xF0CF,0xF0C0 67 | .hword 0xF0B1,0xF0A3,0xF095,0xF088,0xF07B,0xF06F,0xF064,0xF059 68 | .hword 0xF04F,0xF046,0xF03D,0xF035,0xF02D,0xF026,0xF01F,0xF019 69 | .hword 0xF014,0xF010,0xF00C,0xF008,0xF005,0xF003,0xF002,0xF001 70 | 71 | .hword 0xF000,0xF001,0xF002,0xF003,0xF005,0xF008,0xF00C,0xF010 72 | .hword 0xF014,0xF019,0xF01F,0xF026,0xF02D,0xF035,0xF03D,0xF046 73 | .hword 0xF04F,0xF059,0xF064,0xF06F,0xF07B,0xF088,0xF095,0xF0A3 74 | .hword 0xF0B1,0xF0C0,0xF0CF,0xF0DF,0xF0F0,0xF101,0xF113,0xF125 75 | .hword 0xF138,0xF14C,0xF160,0xF175,0xF18A,0xF1A0,0xF1B6,0xF1CD 76 | .hword 0xF1E4,0xF1FC,0xF215,0xF22E,0xF247,0xF261,0xF27C,0xF297 77 | .hword 0xF2B3,0xF2CF,0xF2EC,0xF309,0xF327,0xF345,0xF363,0xF383 78 | .hword 0xF3A2,0xF3C2,0xF3E3,0xF404,0xF426,0xF448,0xF46A,0xF48D 79 | 80 | .hword 0xF4B0,0xF4D4,0xF4F8,0xF51D,0xF542,0xF567,0xF58D,0xF5B3 81 | .hword 0xF5DA,0xF601,0xF629,0xF650,0xF679,0xF6A1,0xF6CA,0xF6F3 82 | .hword 0xF71D,0xF747,0xF771,0xF79C,0xF7C7,0xF7F2,0xF81E,0xF849 83 | .hword 0xF876,0xF8A2,0xF8CF,0xF8FC,0xF929,0xF957,0xF985,0xF9B3 84 | .hword 0xF9E1,0xFA10,0xFA3E,0xFA6D,0xFA9D,0xFACC,0xFAFC,0xFB2B 85 | .hword 0xFB5B,0xFB8C,0xFBBC,0xFBED,0xFC1D,0xFC4E,0xFC7F,0xFCB0 86 | .hword 0xFCE1,0xFD13,0xFD44,0xFD76,0xFDA7,0xFDD9,0xFE0B,0xFE3D 87 | .hword 0xFE6F,0xFEA1,0xFED3,0xFF05,0xFF38,0xFF6A,0xFF9C,0xFFCE 88 | .hword 0x0000,0x0032 89 | 90 | .size sin_lut, .-sin_lut -------------------------------------------------------------------------------- /asm/tonc_bios.s: -------------------------------------------------------------------------------- 1 | // 2 | // Main GBA BIOS functions. 3 | // 4 | //! \file tonc_bios.s 5 | //! \author J Vijn 6 | //! \date 20071130 - 20090801 7 | 8 | #include "tonc_asminc.h" 9 | 10 | @ === SoftReset [00h] ================================================= 11 | @ DECL: void SoftReset(); 12 | @ DESC: 13 | BEGIN_FUNC_THUMB(SoftReset, CSEC_TEXT) 14 | swi 0x00 15 | bx lr 16 | END_FUNC(SoftReset) 17 | 18 | @ === RegisterRamReset [01h] ========================================== 19 | @ DECL: void RegisterRamReset(u32 flags); 20 | @ DESC: 21 | BEGIN_FUNC_THUMB(RegisterRamReset, CSEC_TEXT) 22 | swi 0x01 23 | bx lr 24 | END_FUNC(RegisterRamReset) 25 | 26 | @ === Halt [02h] ====================================================== 27 | @ DECL: void Halt(); 28 | @ DESC: 29 | BEGIN_FUNC_THUMB(Halt, CSEC_TEXT) 30 | swi 0x02 31 | bx lr 32 | END_FUNC(Halt) 33 | 34 | @ === Stop [03h] ====================================================== 35 | @ DECL: void Stop(); 36 | @ DESC: 37 | BEGIN_FUNC_THUMB(Stop, CSEC_TEXT) 38 | swi 0x03 39 | bx lr 40 | END_FUNC(Stop) 41 | 42 | @ === IntrWait [04h] ================================================== 43 | @ DECL: void IntrWait(u32 flagClear, u32 irq); 44 | @ DESC: 45 | BEGIN_FUNC_THUMB(IntrWait, CSEC_TEXT) 46 | swi 0x04 47 | bx lr 48 | END_FUNC(IntrWait) 49 | 50 | @ === VBlankIntrWait [05h] ============================================ 51 | @ DECL: void VBlankIntrWait(); 52 | @ DESC: 53 | BEGIN_FUNC_THUMB(VBlankIntrWait, CSEC_TEXT) 54 | swi 0x05 55 | bx lr 56 | END_FUNC(VBlankIntrWait) 57 | 58 | @ === Div [06h] ======================================================= 59 | @ DECL: s32 Div(s32 num, s32 den); 60 | @ DESC: 61 | BEGIN_FUNC_THUMB(Div, CSEC_TEXT) 62 | swi 0x06 63 | bx lr 64 | END_FUNC(Div) 65 | 66 | @ === DivArm [07h] ==================================================== 67 | @ DECL: s32 DivArm(s32 den, s32 num); 68 | @ DESC: 69 | BEGIN_FUNC_THUMB(DivArm, CSEC_TEXT) 70 | swi 0x07 71 | bx lr 72 | END_FUNC(DivArm) 73 | 74 | @ === Sqrt [08h] ====================================================== 75 | @ DECL: u32 Sqrt(u32 num); 76 | @ DESC: 77 | BEGIN_FUNC_THUMB(Sqrt, CSEC_TEXT) 78 | swi 0x08 79 | bx lr 80 | END_FUNC(Sqrt) 81 | 82 | @ === ArcTan [09h] ==================================================== 83 | @ DECL: s16 ArcTan(s16 dydx); 84 | @ DESC: 85 | BEGIN_FUNC_THUMB(ArcTan, CSEC_TEXT) 86 | swi 0x09 87 | bx lr 88 | END_FUNC(ArcTan) 89 | 90 | @ === ArcTan2 [0Ah] =================================================== 91 | @ DECL: s16 ArcTan2(s16 x, s16 y); 92 | @ DESC: 93 | BEGIN_FUNC_THUMB(ArcTan2, CSEC_TEXT) 94 | swi 0x0A 95 | bx lr 96 | END_FUNC(ArcTan2) 97 | 98 | @ === CpuSet [0Bh] ==================================================== 99 | @ DECL: void CpuSet(const void *src, void *dst, u32 mode); 100 | @ DESC: 101 | BEGIN_FUNC_THUMB(CpuSet, CSEC_TEXT) 102 | swi 0x0B 103 | bx lr 104 | END_FUNC(CpuSet) 105 | 106 | @ === CpuFastSet [0Ch] ================================================ 107 | @ DECL: void CpuFastSet(const void *src, void *dst, u32 mode); 108 | @ DESC: 109 | BEGIN_FUNC_THUMB(CpuFastSet, CSEC_TEXT) 110 | swi 0x0C 111 | bx lr 112 | END_FUNC(CpuFastSet) 113 | 114 | @ === BiosCheckSum [0Dh] ================================================ 115 | @ DECL: u32 BiosCheckSum(); 116 | @ DESC: 117 | BEGIN_FUNC_THUMB(BiosCheckSum, CSEC_TEXT) 118 | swi 0x0D 119 | bx lr 120 | END_FUNC(BiosCheckSum) 121 | 122 | @ === BgAffineSet [0Eh] =============================================== 123 | @ DECL: void ObjAffineSet(const ObjAffineSource *src, void *dst, s32 num, s32 offset); 124 | @ DESC: 125 | BEGIN_FUNC_THUMB(BgAffineSet, CSEC_TEXT) 126 | swi 0x0E 127 | bx lr 128 | END_FUNC(BgAffineSet) 129 | 130 | @ === ObjAffineSet [0Fh] ============================================== 131 | @ DECL: void BgAffineSet(const BGAffineSource *src, BGAffineDest *dst, s32 num); 132 | @ DESC: 133 | BEGIN_FUNC_THUMB(ObjAffineSet, CSEC_TEXT) 134 | swi 0x0F 135 | bx lr 136 | END_FUNC(ObjAffineSet) 137 | 138 | @ === BitUnPack [10h] ================================================= 139 | @ DECL: void BitUnPack(const void *src, void *dst, BUP *bup); 140 | @ DESC: 141 | BEGIN_FUNC_THUMB(BitUnPack, CSEC_TEXT) 142 | swi 0x10 143 | bx lr 144 | END_FUNC(BitUnPack) 145 | 146 | @ === LZ77UnCompWram [11h] ============================================ 147 | @ DECL: void LZ77UnCompWram(const void *src, void *dst); 148 | @ DESC: 149 | BEGIN_FUNC_THUMB(LZ77UnCompWram, CSEC_TEXT) 150 | swi 0x11 151 | bx lr 152 | END_FUNC(LZ77UnCompWram) 153 | 154 | @ === LZ77UnCompVram [12h] ============================================ 155 | @ DECL: void LZ77UnCompVram(const void *src, void *dst); 156 | @ DESC: 157 | BEGIN_FUNC_THUMB(LZ77UnCompVram, CSEC_TEXT) 158 | swi 0x12 159 | bx lr 160 | END_FUNC(LZ77UnCompVram) 161 | 162 | @ === HuffUnComp [13h] ================================================ 163 | @ DECL: void HuffUnComp(const void *src, void *dst); 164 | @ DESC: 165 | BEGIN_FUNC_THUMB(HuffUnComp, CSEC_TEXT) 166 | swi 0x13 167 | bx lr 168 | END_FUNC(HuffUnComp) 169 | 170 | @ === RLUnCompWram [14h] ============================================== 171 | @ DECL: void RLUnCompWram(const void *src, void *dst); 172 | @ DESC: 173 | BEGIN_FUNC_THUMB(RLUnCompWram, CSEC_TEXT) 174 | swi 0x14 175 | bx lr 176 | END_FUNC(RLUnCompWram) 177 | 178 | @ === RLUnCompVram [15h] ============================================== 179 | @ DECL: void RLUnCompVram(const void *src, void *dst); 180 | @ DESC: 181 | BEGIN_FUNC_THUMB(RLUnCompVram, CSEC_TEXT) 182 | swi 0x15 183 | bx lr 184 | END_FUNC(RLUnCompVram) 185 | 186 | @ === Diff8bitUnFilterWram [16h] ====================================== 187 | @ DECL: void Diff8bitUnFilterWram(const void *src, void *dst); 188 | @ DESC: 189 | BEGIN_FUNC_THUMB(Diff8bitUnFilterWram, CSEC_TEXT) 190 | swi 0x16 191 | bx lr 192 | END_FUNC(Diff8bitUnFilterWram) 193 | 194 | @ === Diff8bitUnFilterVram [17h] ====================================== 195 | @ DECL: void Diff8bitUnFilterVram(const void *src, void *dst); 196 | @ DESC: 197 | BEGIN_FUNC_THUMB(Diff8bitUnFilterVram, CSEC_TEXT) 198 | swi 0x17 199 | bx lr 200 | END_FUNC(Diff8bitUnFilterVram) 201 | 202 | @ === Diff16bitUnFilter [18h] ========================================= 203 | @ DECL: void Diff16bitUnFilter(const void *src, void *dst); 204 | @ DESC: 205 | BEGIN_FUNC_THUMB(Diff16bitUnFilter, CSEC_TEXT) 206 | swi 0x18 207 | bx lr 208 | END_FUNC(Diff16bitUnFilter) 209 | 210 | @ === SoundBias [19h] ================================================= 211 | @ DECL: void SoundBias(u32 bias); 212 | @ DESC: 213 | BEGIN_FUNC_THUMB(SoundBias, CSEC_TEXT) 214 | swi 0x19 215 | bx lr 216 | END_FUNC(SoundBias) 217 | 218 | @ === SoundDriverInit [1Ah] =========================================== 219 | @ DECL: void SoundDriverInit(void *src); 220 | @ DESC: 221 | BEGIN_FUNC_THUMB(SoundDriverInit, CSEC_TEXT) 222 | swi 0x1A 223 | bx lr 224 | END_FUNC(SoundDriverInit) 225 | 226 | @ === SoundDriverMode [1Bh] =========================================== 227 | @ DECL: void SoundDriverMode(u32 mode); 228 | @ DESC: 229 | BEGIN_FUNC_THUMB(SoundDriverMode, CSEC_TEXT) 230 | swi 0x1B 231 | bx lr 232 | END_FUNC(SoundDriverMode) 233 | 234 | @ === SoundDriverMain [1Ch] =========================================== 235 | @ DECL: void SoundDriverMain(); 236 | @ DESC: 237 | BEGIN_FUNC_THUMB(SoundDriverMain, CSEC_TEXT) 238 | swi 0x1C 239 | bx lr 240 | END_FUNC(SoundDriverMain) 241 | 242 | @ === SoundDriverVSync [1Dh] ========================================== 243 | @ DECL: void SoundDriverVSync(); 244 | @ DESC: 245 | BEGIN_FUNC_THUMB(SoundDriverVSync, CSEC_TEXT) 246 | swi 0x1D 247 | bx lr 248 | END_FUNC(SoundDriverVSync) 249 | 250 | @ === SoundChannelClear [1Eh] ========================================= 251 | @ DECL: void SoundChannelClear(); 252 | @ DESC: 253 | BEGIN_FUNC_THUMB(SoundChannelClear, CSEC_TEXT) 254 | swi 0x1E 255 | bx lr 256 | END_FUNC(SoundChannelClear) 257 | 258 | @ === MidiKey2Freq [1Fh] ============================================== 259 | @ DECL: u32 MidiKey2Freq(void *wa, u8 mk, u8 fp); 260 | @ DESC: 261 | BEGIN_FUNC_THUMB(MidiKey2Freq, CSEC_TEXT) 262 | swi 0x1F 263 | bx lr 264 | END_FUNC(MidiKey2Freq) 265 | 266 | @ === MultiBoot [25h] ================================================= 267 | @ DECL: int MultiBoot(MultiBootParam* mb, u32 mode); 268 | @ DESC: 269 | BEGIN_FUNC_THUMB(MultiBoot, CSEC_TEXT) 270 | swi 0x25 271 | bx lr 272 | END_FUNC(MultiBoot) 273 | 274 | @ === SoundDriverVSyncOff [28h] ======================================= 275 | @ DECL: void SoundDriverVSyncOff(); 276 | @ DESC: 277 | BEGIN_FUNC_THUMB(SoundDriverVSyncOff, CSEC_TEXT) 278 | swi 0x28 279 | bx lr 280 | END_FUNC(SoundDriverVSyncOff) 281 | 282 | @ === SoundDriverVSyncOn [29h] ======================================== 283 | @ DECL: void SoundDriverVSyncOn(); 284 | @ DESC: 285 | BEGIN_FUNC_THUMB(SoundDriverVSyncOn, CSEC_TEXT) 286 | swi 0x29 287 | bx lr 288 | END_FUNC(SoundDriverVSyncOn) 289 | 290 | -------------------------------------------------------------------------------- /asm/tonc_bios_ex.s: -------------------------------------------------------------------------------- 1 | // 2 | // Additional BIOS functions 3 | // 4 | //! \file tonc_bios_ex.s 5 | //! \author J Vijn 6 | //! \date 20060508 - 20090801 7 | 8 | .file "tonc_bios_ex.s" 9 | 10 | #include "tonc_asminc.h" 11 | 12 | @ === VBlankIntrDelay [05h] =========================================== 13 | @ DECL: void VBlankIntrDelay(u32 count); 14 | @ DESC: wait count frames 15 | @ NOTE: swi 5 uses r0, which is why I need r4 here 16 | BEGIN_FUNC_THUMB(VBlankIntrDelay, CSEC_TEXT) 17 | push {r4} 18 | sub r4, r0, #0 19 | beq .LVIDelay_done 20 | .LVIDelay_loop: 21 | swi 0x05 22 | sub r4, #1 23 | bhi .LVIDelay_loop 24 | .LVIDelay_done: 25 | pop {r4} 26 | bx lr 27 | END_FUNC(VBlankIntrDelay) 28 | 29 | 30 | @ === DivSafe [06h] =================================================== 31 | @ DECL: int DivSafe(int num, int den); 32 | @ DESC: a div by 0 safe version 33 | BEGIN_FUNC_THUMB(DivSafe, CSEC_TEXT) 34 | cmp r1, #0 35 | beq .Ldiv_bad 36 | swi 0x06 37 | bx lr 38 | .Ldiv_bad: 39 | mvn r1, r1 @ 0xFFFF:FFFF 40 | lsr r1, r1, #1 @ 0x7FFF:FFFF 41 | asr r0, r0, #31 @ r0= r0<0 ? -1 : 0 42 | sub r0, r1, r0 43 | bx lr 44 | END_FUNC(DivSafe) 45 | 46 | @ === Mod [06h] ======================================================= 47 | @ DECL: int Mod(int num, int den); 48 | @ DESC: 49 | BEGIN_FUNC_THUMB(Mod, CSEC_TEXT) 50 | swi 0x06 51 | mov r0, r1 52 | bx lr 53 | END_FUNC(Mod) 54 | 55 | @ === DivAbs [06h] ==================================================== 56 | @ DECL: u32 DivAbs(int num, int den); 57 | @ DESC: 58 | BEGIN_FUNC_THUMB(DivAbs, CSEC_TEXT) 59 | swi 0x06 60 | mov r0, r3 61 | bx lr 62 | END_FUNC(DivAbs) 63 | 64 | @ === DivArmMod [07h] ================================================= 65 | @ DECL: int DivArmMod(int den, int num); 66 | @ DESC: 67 | BEGIN_FUNC_THUMB(DivArmMod, CSEC_TEXT) 68 | swi 0x07 69 | mov r0, r1 70 | bx lr 71 | END_FUNC(DivArmMod) 72 | 73 | @ === DivArmAbs [07h] ==================================================== 74 | @ DECL: u32 DivArmAbs(int den, int num); 75 | @ DESC: 76 | BEGIN_FUNC_THUMB(DivArmAbs, CSEC_TEXT) 77 | swi 0x07 78 | mov r0, r3 79 | bx lr 80 | END_FUNC(DivArmAbs) 81 | 82 | 83 | @ === CpuFastFill [0Ch] =============================================== 84 | @ DECL: void CpuFastFill(u32 wd, void *dst, u32 count); 85 | @ DESC: 86 | BEGIN_FUNC_THUMB(CpuFastFill, CSEC_TEXT) 87 | push {r0} @ push wd on stack 88 | mov r0, #128 89 | lsl r0, r0, #17 90 | orr r2, r2, r0 @ add fill flag 91 | mov r0, sp @ point to stack (where wd is) 92 | swi 0x0C 93 | add sp, sp, #4 @ 'pop' 94 | bx lr 95 | END_FUNC(CpuFastFill) 96 | 97 | @ EOF 98 | -------------------------------------------------------------------------------- /asm/tonc_isr_master.s: -------------------------------------------------------------------------------- 1 | // 2 | // Default ISR for interrupts. No automatic nestings. 3 | // 4 | //! \file tonc_isr_master.s 5 | //! \author J Vijn 6 | //! \date 20080320 - 20090801 7 | // 8 | // === NOTES === 9 | 10 | #include "tonc_asminc.h" 11 | 12 | .file "tonc_isr_master.s" 13 | .extern __isr_table; 14 | 15 | /*! \fn IWRAM_CODE void isr_master() 16 | \brief Default irq dispatcher (no automatic nesting) 17 | */ 18 | @ Register list 19 | @ r0 : ®_IE 20 | @ r1 : __isr_table / isr 21 | @ r2 : IF & IE 22 | @ r3 : tmp 23 | @ ip : (IF,IE) 24 | BEGIN_FUNC_ARM(isr_master, CSEC_IWRAM) 25 | @ Read IF/IE 26 | mov r0, #0x04000000 27 | ldr ip, [r0, #0x200]! 28 | and r2, ip, ip, lsr #16 @ irq= IE & IF 29 | 30 | @ Acknowledge irq in IF and for BIOS 31 | strh r2, [r0, #2] 32 | ldr r3, [r0, #-0x208] 33 | orr r3, r3, r2 34 | str r3, [r0, #-0x208] 35 | 36 | @ Search for irq. 37 | ldr r1, =__isr_table 38 | 39 | .Lirq_search: 40 | ldr r3, [r1], #8 41 | tst r3, r2 42 | bne .Lpost_search @ Found one, break off search 43 | cmp r3, #0 44 | bne .Lirq_search @ Not here; try next irq 45 | 46 | @ Search over : return if no isr, otherwise continue. 47 | .Lpost_search: 48 | ldrne r1, [r1, #-4] @ isr= __isr_table[ii-1].isr 49 | cmpne r1, #0 50 | bxeq lr @ If no isr: quit 51 | 52 | @ --- If we're here, we have an isr --- 53 | 54 | ldr r3, [r0, #8] @ Read IME 55 | strb r0, [r0, #8] @ Clear IME 56 | bic r2, ip, r2 57 | strh r2, [r0] @ Clear current irq in IE 58 | 59 | mrs r2, spsr 60 | stmfd sp!, {r2-r3, ip, lr} @ sprs, IME, (IE,IF), lr_irq 61 | 62 | @ Set mode to usr 63 | mrs r3, cpsr 64 | bic r3, r3, #0xDF 65 | orr r3, r3, #0x1F 66 | msr cpsr, r3 67 | 68 | @ Call isr 69 | stmfd sp!, {r0,lr} @ ®_IE, lr_sys 70 | mov lr, pc 71 | bx r1 72 | ldmfd sp!, {r0,lr} @ ®_IE, lr_sys 73 | 74 | @ --- Unwind --- 75 | strb r0, [r0, #8] @ Clear IME again (safety) 76 | 77 | @ Reset mode to irq 78 | mrs r3, cpsr 79 | bic r3, r3, #0xDF 80 | orr r3, r3, #0x92 81 | msr cpsr, r3 82 | 83 | ldmfd sp!, {r2-r3, ip, lr} @ sprs, IME, (IE,IF), lr_irq 84 | msr spsr, r2 @ Restore spsr 85 | strh ip, [r0] @ Restore IE 86 | str r3, [r0, #8] @ Restore IME 87 | 88 | bx lr 89 | END_FUNC(isr_master) 90 | 91 | @ EOF 92 | 93 | -------------------------------------------------------------------------------- /asm/tonc_isr_nest.s: -------------------------------------------------------------------------------- 1 | // 2 | // Main ISR for prioritized nested interrupts 3 | // 4 | //! \file tonc_isr_nest.s 5 | //! \author J Vijn 6 | //! \date 20060909 - 20061025 7 | // 8 | // === NOTES === 9 | 10 | #include "tonc_asminc.h" 11 | 12 | .file "tonc_isr_nest.s" 13 | .extern __isr_table; 14 | 15 | /*! \fn IWRAM_CODE void isr_master_nest() 16 | \brief Main ISR for using prioritized nested interrupts 17 | */ 18 | BEGIN_FUNC_ARM(isr_master_nest, CSEC_IWRAM) 19 | mov r3, #0x04000000 20 | ldr r2, [r3, #0x200]! 21 | and r2, r2, r2, lsr #16 @ irq_curr= IE & IF 22 | 23 | @ REG_IFBIOS |= irq_curr 24 | ldr r1, [r3, #-0x208] 25 | orr r1, r1, r2 26 | str r1, [r3, #-0x208] 27 | 28 | @ --- Find raised irq in __isr_table --- 29 | @ r0 := IRQ_REC *pir= __isr_table 30 | @ r12:= irq_prio (higher priority irqs) 31 | ldr r0, =__isr_table 32 | mov r12, #0 33 | .Lirq_search: 34 | ldr r1, [r0], #8 35 | tst r1, r2 36 | bne .Lirq_found @ Found it, break off search 37 | orr r12, r12, r1 38 | cmp r1, #0 39 | bne .Lirq_search @ Not here; try next irq_rec 40 | 41 | @ --- No irq or ISR: just ack and return --- 42 | .Lirq_none: 43 | strh r2, [r3, #2] @ REG_IF= irq_curr (is this right?) 44 | bx lr 45 | 46 | @ If we're here, we found the irq; check for ISR 47 | .Lirq_found: 48 | ldr r0, [r0, #-4] @ isr= pir[ii-1].isr 49 | cmp r0, #0 50 | streqh r1, [r3, #2] @ No ISR: ack and return 51 | bxeq lr 52 | 53 | @ --- ISR found, prep for nested irqs --- 54 | @ {r0,r1,r3,r12} == { isr(), irq_flag, ®_IE, irq_prio } 55 | 56 | @ r2 := ieif= REG_IE|(irq_flag<<16); REG_IE &= irq_prio; 57 | ldrh r2, [r3] 58 | and r12, r12, r2 59 | strh r12, [r3] 60 | orr r2, r2, r1, lsl #16 61 | 62 | mrs r12, spsr 63 | stmfd sp!, {r2, r12, lr} @ sp_irq,{ieif, spsr, lr_irq} 64 | 65 | str r3, [r3, #8] @ REG_IME=0 (yeah ugly, I know) 66 | @ Set CPU to SYS-mode, re-enable IRQ 67 | mrs r2, cpsr 68 | bic r2, r2, #0xDF 69 | orr r2, r2, #0x1F 70 | msr cpsr, r2 71 | 72 | stmfd sp!, {r3, lr} @ sp_sys, {®_IE, lr_sys} 73 | mov r2, #1 74 | str r2, [r3, #8] @ REG_IME= 1 75 | adr lr, .Lpost_isr 76 | bx r0 77 | 78 | @ --- Unroll preparation --- 79 | .Lpost_isr: 80 | ldmfd sp!, {r3, lr} @ sp_sys, {®_IE, lr_sys} 81 | ldr r0, [r3, #8] 82 | str r3, [r3, #8] @ REG_IME=0 again 83 | 84 | @ Restore CPU to IRQ-mode, disable IRQ 85 | mrs r2, cpsr 86 | bic r2, r2, #0xDF 87 | orr r2, r2, #0x92 88 | msr cpsr, r2 89 | 90 | ldmfd sp!, {r2, r12, lr} @ sp_irq,{ieif, spsr, lr_irq} 91 | msr spsr, r12 92 | 93 | str r2, [r3] @ REG_IE/REG_IF= ieif 94 | str r0, [r3, #8] @ Restore REG_IME 95 | bx lr 96 | END_FUNC(isr_master_nest) 97 | 98 | @ EOF 99 | -------------------------------------------------------------------------------- /asm/tonc_memcpy.s: -------------------------------------------------------------------------------- 1 | // 2 | // Alignment-safe and fast memcpy routines 3 | // 4 | //! \file tonc_memcpy.s 5 | //! \author J Vijn 6 | //! \date 20060508 - 20090801 7 | // 8 | // === NOTES === 9 | @ * 20050924: Lower overhead for all; reduced i-count for u16 loops. 10 | @ * These are 16/32bit memset and memcpy. The 32bit versions are in 11 | @ iwram for maximum effect and pretty much do what CpuFastSet does, 12 | @ except that it'll work for non multiples of 8 words too. Speed 13 | @ is as good as CpuFastSet, but with a little less overhead. 14 | @ * The 16bit versions call the 32bit ones if possible and/or desirable. 15 | @ They are thumb/ROM functions but did them in asm anyway because 16 | @ GCC goes haywire with the use of registers resulting in a much 17 | @ higher overhead (i.e., detrimental for low counts) 18 | @ * Crossover with inline while(nn--) loops (not for(ii++), which are 19 | @ much slower): 20 | @ memcpy32: ~4 21 | @ memcpy16: ~8 22 | 23 | #include "tonc_asminc.h" 24 | 25 | .file "tonc_memcpy.s" 26 | 27 | @ === void memcpy32(void *dst, const void *src, u32 wdn); ============= 28 | /*! \fn void memcpy32(void *dst, const void *src, u32 wdn) CODE_IN_IWRAM; 29 | \brief Fast-copy by words. 30 | \param dst Destination address. 31 | \param src Source address. 32 | \param wdn Number of words. 33 | \note \a src and \a dst must be word aligned. 34 | \note \a r0 and \a r1 return as \a dst + \a wdn and \a src + \a wdn. 35 | */ 36 | /* Reglist: 37 | r0, r1: dst, src 38 | r2: wdn, then wdn>>3 39 | r3-r10: data buffer 40 | r12: wdn&7 41 | */ 42 | BEGIN_FUNC_ARM(memcpy32, CSEC_IWRAM) 43 | and r12, r2, #7 44 | movs r2, r2, lsr #3 45 | beq .Lres_cpy32 46 | push {r4-r10} 47 | @ copy 32byte chunks with 8fold xxmia 48 | .Lmain_cpy32: 49 | ldmia r1!, {r3-r10} 50 | stmia r0!, {r3-r10} 51 | subs r2, r2, #1 52 | bhi .Lmain_cpy32 53 | pop {r4-r10} 54 | @ and the residual 0-7 words 55 | .Lres_cpy32: 56 | subs r12, r12, #1 57 | ldmcsia r1!, {r3} 58 | stmcsia r0!, {r3} 59 | bhi .Lres_cpy32 60 | bx lr 61 | END_FUNC(memcpy32) 62 | 63 | @ === void memcpy16(void *dst, const void *src, u32 hwn); ============= 64 | /*! \fn void memcpy16(void *dst, const void *src, u32 hwn); 65 | \brief Copy for halfwords. 66 | Uses memcpy32() if \a hwn>6 and 67 | \a src and \a dst are aligned equally. 68 | \param dst Destination address. 69 | \param src Source address. 70 | \param wdn Number of halfwords to fill. 71 | \note \a dst and \a src must be halfword aligned. 72 | \note \a r0 and \a r1 return as \a dst + \a hwn and \a src + \a hwn. 73 | */ 74 | /* Reglist: 75 | r0, r1: dst, src 76 | r2, r4: wdn 77 | r3: tmp; and data buffer 78 | */ 79 | 80 | BEGIN_FUNC_THUMB(memcpy16, CSEC_TEXT) 81 | push {r4, lr} 82 | @ under 5 hwords -> std cpy 83 | cmp r2, #5 84 | bls .Ltail_cpy16 85 | @ unreconcilable alignment -> std cpy 86 | @ if (dst^src)&2 -> alignment impossible 87 | mov r3, r0 88 | eor r3, r1 89 | lsl r3, r3, #31 @ (dst^src), bit 1 into carry 90 | bcs .Ltail_cpy16 @ (dst^src)&2 : must copy by halfword 91 | @ src and dst have same alignment -> word align 92 | lsl r3, r0, #31 93 | bcc .Lmain_cpy16 @ ~src&2 : already word aligned 94 | @ aligning is necessary: copy 1 hword and align 95 | ldrh r3, [r1] 96 | strh r3, [r0] 97 | add r0, #2 98 | add r1, #2 99 | sub r2, r2, #1 100 | @ right, and for the REAL work, we're gonna use memcpy32 101 | .Lmain_cpy16: 102 | lsl r4, r2, #31 103 | lsr r2, r2, #1 104 | ldr r3, =memcpy32 105 | bl .Llong_bl 106 | @ NOTE: r0,r1 are altered by memcpy32, but in exactly the right 107 | @ way, so we can use them as is. 108 | lsr r2, r4, #31 109 | beq .Lend_cpy16 110 | .Ltail_cpy16: 111 | sub r2, #1 112 | bcc .Lend_cpy16 @ r2 was 0, bug out 113 | lsl r2, r2, #1 114 | .Lres_cpy16: 115 | ldrh r3, [r1, r2] 116 | strh r3, [r0, r2] 117 | sub r2, r2, #2 118 | bcs .Lres_cpy16 119 | .Lend_cpy16: 120 | pop {r4} 121 | pop {r3} 122 | .Llong_bl: 123 | bx r3 124 | END_FUNC(memcpy16) 125 | 126 | @ EOF 127 | -------------------------------------------------------------------------------- /asm/tonc_memset.s: -------------------------------------------------------------------------------- 1 | // 2 | // Alignment-safe and fast memset routines 3 | // 4 | //! \file tonc_memcpy.s 5 | //! \author J Vijn 6 | //! \date 20060508 - 20090801 7 | // 8 | // === NOTES === 9 | @ * 20050924: Lower overhead for all; reduced i-count for u16 loops. 10 | @ * These are 16/32bit memset and memcpy. The 32bit versions are in 11 | @ iwram for maximum effect and pretty much do what CpuFastSet does, 12 | @ except that it'll work for non multiples of 8 words too. Speed 13 | @ is as good as CpuFastSet, but with a little less overhead. 14 | @ * The 16bit versions call the 32bit ones if possible and/or desirable. 15 | @ They are thumb/ROM functions but did them in asm anyway because 16 | @ GCC goes haywire with the use of registers resulting in a much 17 | @ higher overhead (i.e., detrimental for low counts) 18 | @ * Crossover with inline while(nn--) loops (not for(ii++), which are 19 | @ much slower): 20 | @ memset32: ~5 21 | @ memset16: ~8 22 | 23 | .file "tonc_memset.s" 24 | 25 | #include "tonc_asminc.h" 26 | 27 | @ === void memset32(void *dst, u32 src, u32 wdn); ===================== 28 | /*! \fn void memset32(void *dst, u32 src, u32 wdn) IWRAM_CODE; 29 | \brief Fast-fill by words. 30 | \param dst Destination address. 31 | \param src Fill word (not address). 32 | \param wdn Number of words to fill. 33 | \note \a dst must be word aligned. 34 | \note \a r0 returns as \a dst + \a wdn. 35 | */ 36 | /* Reglist: 37 | r0, r1: dst, src 38 | r2: wdn, then wdn>>3 39 | r3-r10: data buffer 40 | r12: wdn&7 41 | */ 42 | BEGIN_FUNC_ARM(memset32, CSEC_IWRAM) 43 | and r12, r2, #7 44 | movs r2, r2, lsr #3 45 | beq .Lres_set32 46 | push {r4-r9} 47 | @ set 32byte chunks with 8fold xxmia 48 | mov r3, r1 49 | mov r4, r1 50 | mov r5, r1 51 | mov r6, r1 52 | mov r7, r1 53 | mov r8, r1 54 | mov r9, r1 55 | .Lmain_set32: 56 | stmia r0!, {r1, r3-r9} 57 | subs r2, r2, #1 58 | bhi .Lmain_set32 59 | pop {r4-r9} 60 | @ residual 0-7 words 61 | .Lres_set32: 62 | subs r12, r12, #1 63 | stmhsia r0!, {r1} 64 | bhi .Lres_set32 65 | bx lr 66 | END_FUNC(memset32) 67 | 68 | @ === void memset16(void *dst, u16 src, u32 hwn); ===================== 69 | /*! \fn void memset16(void *dst, u16 src, u32 hwn); 70 | \brief Fill for halfwords. 71 | Uses memset32() if \a hwn>5 72 | \param dst Destination address. 73 | \param src Source halfword (not address). 74 | \param wdn Number of halfwords to fill. 75 | \note \a dst must be halfword aligned. 76 | \note \a r0 returns as \a dst + \a hwn. 77 | */ 78 | /* Reglist: 79 | r0, r1: dst, src 80 | r2, r4: wdn 81 | r3: tmp; and data buffer 82 | */ 83 | BEGIN_FUNC_THUMB(memset16, CSEC_TEXT) 84 | push {r4, lr} 85 | @ under 6 hwords -> std set 86 | cmp r2, #5 87 | bls .Ltail_set16 88 | @ dst not word aligned: copy 1 hword and align 89 | lsl r3, r0, #31 90 | bcc .Lmain_set16 91 | strh r1, [r0] 92 | add r0, #2 93 | sub r2, r2, #1 94 | @ Again, memset32 does the real work 95 | .Lmain_set16: 96 | lsl r4, r1, #16 97 | orr r1, r4 98 | lsl r4, r2, #31 99 | lsr r2, r2, #1 100 | ldr r3, =memset32 101 | bl .Llong_bl 102 | @ NOTE: r0 is altered by memset32, but in exactly the right 103 | @ way, so we can use is as is. r1 is now doubled though. 104 | lsr r2, r4, #31 105 | beq .Lend_set16 106 | lsr r1, #16 107 | .Ltail_set16: 108 | sub r2, #1 109 | bcc .Lend_set16 @ r2 was 0, bug out 110 | lsl r2, r2, #1 111 | .Lres_set16: 112 | strh r1, [r0, r2] 113 | sub r2, r2, #2 114 | bcs .Lres_set16 115 | .Lend_set16: 116 | pop {r4} 117 | pop {r3} 118 | .Llong_bl: 119 | bx r3 120 | END_FUNC(memset16) 121 | 122 | 123 | @ EOF 124 | -------------------------------------------------------------------------------- /asm/tonc_nocash.s: -------------------------------------------------------------------------------- 1 | // 2 | // No$gba debugger messaging 3 | // 4 | //! \file tonc_nocash.s 5 | //! \author J Vijn 6 | //! \date 20080422 - 20080422 7 | 8 | #include "tonc_asminc.h" 9 | 10 | /* DECLARATIONS: 11 | int nocash_puts(const char *str); 12 | EWRAM_CODE void nocash_message(); 13 | extern EWRAM_DATA char nocash_buffer[80]; 14 | */ 15 | 16 | .global nocash_puts 17 | .global nocash_message 18 | .global nocash_buffer 19 | 20 | BEGIN_FUNC_THUMB(nocash_puts, CSEC_TEXT) 21 | push {r4, lr} 22 | ldr r4,=nocash_message @ Get messenger address 23 | ldr r1,=nocash_buffer @ Get buffer address 24 | 25 | mov r2, #0 26 | mov r12, r2 27 | 28 | @ Iterate over loop parts 29 | .Lmsg_loop: 30 | mov r2, #0 31 | 32 | @ Copy up to 80 chars and print 33 | .Lmsg_cpy: @ for(ii=0; ii<80; ii++) 34 | ldrb r3, [r0, r2] @ if((dst[ii]=src[ii]) == '\0') 35 | strb r3, [r1, r2] @ break; 36 | cmp r3, #0 37 | beq .Lmsg_print 38 | add r2, #1 39 | cmp r2, #80 40 | bne .Lmsg_cpy 41 | 42 | @ Print message 43 | .Lmsg_print: 44 | bl .Lmsg_far_call 45 | 46 | @ If not at end, continue with next part of string 47 | add r0, r2 48 | add r12, r2 49 | cmp r3, #0 50 | bne .Lmsg_loop 51 | 52 | @ Full string done. Set result and return 53 | mov r0, r12 54 | pop {r4} 55 | pop {r1} 56 | bx r1 57 | .Lmsg_far_call: 58 | bx r4 59 | END_FUNC(nocash_puts) 60 | 61 | BEGIN_FUNC_THUMB(nocash_message, CSEC_EWRAM) 62 | mov r12, r12 @ first ID 63 | b .Lmsg_end @ skip the text section 64 | .hword 0x6464 @ second ID 65 | .hword 0 @ flags 66 | nocash_buffer: 67 | .space 82 @ Message buffer 68 | 69 | .Lmsg_end: 70 | bx lr 71 | END_FUNC(nocash_message) 72 | 73 | @ EOF 74 | -------------------------------------------------------------------------------- /base.c: -------------------------------------------------------------------------------- 1 | // 2 | // [[ ]] 3 | // 4 | //! \file [[ ]] 5 | //! \author J Vijn 6 | //! \date 20079021 - 20079021 7 | // 8 | /* === NOTES === 9 | */ 10 | 11 | #include "tonc_memmap.h" 12 | 13 | // -------------------------------------------------------------------- 14 | // CONSTANTS 15 | // -------------------------------------------------------------------- 16 | 17 | // -------------------------------------------------------------------- 18 | // CLASSES 19 | // -------------------------------------------------------------------- 20 | 21 | 22 | // -------------------------------------------------------------------- 23 | // GLOBALS 24 | // -------------------------------------------------------------------- 25 | 26 | 27 | 28 | // -------------------------------------------------------------------- 29 | // PROTOTYPES 30 | // -------------------------------------------------------------------- 31 | 32 | 33 | // -------------------------------------------------------------------- 34 | // MACROS 35 | // -------------------------------------------------------------------- 36 | // === INLINES========================================================= 37 | 38 | // -------------------------------------------------------------------- 39 | // FUNCTIONS 40 | // -------------------------------------------------------------------- 41 | 42 | 43 | // EOF 44 | -------------------------------------------------------------------------------- /base.h: -------------------------------------------------------------------------------- 1 | // 2 | // [[ ]] 3 | // 4 | //! \file [[ ]] 5 | //! \author J Vijn 6 | //! \date 20060508 - 20060508 7 | // 8 | /* === NOTES === 9 | */ 10 | 11 | #ifndef TONC_XXX 12 | #define TONC_XXX 13 | 14 | #include "tonc_memmap.h" 15 | 16 | // -------------------------------------------------------------------- 17 | // CONSTANTS 18 | // -------------------------------------------------------------------- 19 | // -------------------------------------------------------------------- 20 | // MACROS 21 | // -------------------------------------------------------------------- 22 | 23 | // -------------------------------------------------------------------- 24 | // CLASSES 25 | // -------------------------------------------------------------------- 26 | 27 | 28 | // -------------------------------------------------------------------- 29 | // GLOBALS 30 | // -------------------------------------------------------------------- 31 | 32 | 33 | // -------------------------------------------------------------------- 34 | // PROTOTYPES 35 | // -------------------------------------------------------------------- 36 | 37 | 38 | 39 | // -------------------------------------------------------------------- 40 | // INLINES 41 | // -------------------------------------------------------------------- 42 | 43 | 44 | #endif // TONC_XXX 45 | 46 | // EOF 47 | -------------------------------------------------------------------------------- /include/tonc.h: -------------------------------------------------------------------------------- 1 | // 2 | // Main tonc header 3 | // 4 | //! \file tonc.h 5 | //! \author J Vijn 6 | //! \date 20060508 - 20080825 7 | // 8 | // === NOTES === 9 | 10 | 11 | #ifndef TONC_MAIN 12 | #define TONC_MAIN 13 | 14 | #ifdef __cplusplus 15 | extern "C" { 16 | #endif 17 | 18 | #include "tonc_types.h" 19 | #include "tonc_memmap.h" 20 | #include "tonc_memdef.h" 21 | 22 | #include "tonc_bios.h" 23 | #include "tonc_core.h" 24 | #include "tonc_input.h" 25 | #include "tonc_irq.h" 26 | #include "tonc_math.h" 27 | #include "tonc_oam.h" 28 | #include "tonc_tte.h" 29 | #include "tonc_video.h" 30 | #include "tonc_surface.h" 31 | 32 | #include "tonc_nocash.h" 33 | 34 | // For old times' sake 35 | #include "tonc_text.h" 36 | 37 | #ifdef __cplusplus 38 | }; 39 | #endif 40 | 41 | // --- Doxygen modules: --- 42 | 43 | /*! \defgroup grpBios Bios Calls */ 44 | /*! \defgroup grpCore Core */ 45 | /*! \defgroup grpDma DMA */ 46 | /*! \defgroup grpInput Input */ 47 | /*! \defgroup grpIrq Interrupt */ 48 | /*! \defgroup grpMath Math */ 49 | /*! \defgroup grpMemmap Memory Map */ 50 | /*! \defgroup grpAudio Sound */ 51 | /*! \defgroup grpTTE Tonc Text Engine */ 52 | /*! \defgroup grpText Old Text */ 53 | /*! \defgroup grpTimer Timer */ 54 | /*! \defgroup grpVideo Video */ 55 | 56 | 57 | 58 | /*! \mainpage Tonclib 1.4 (20080825) 59 |

60 | Tonclib is the library accompanying the set of GBA tutorials known 61 | as Tonc Initially, it 62 | was just a handful of macros and functions for dealing with the 63 | GBA hardware: the memory map and its bits, affine transformation 64 | code and things like that. More recently, more general items 65 | have been added like tonccpy() and toncset(), the TSurface system 66 | and TTE. All these items should provide a firm basis on which to 67 | build GBA software. 68 |

69 | */ 70 | 71 | #endif // TONC_MAIN 72 | 73 | -------------------------------------------------------------------------------- /include/tonc_asminc.h: -------------------------------------------------------------------------------- 1 | // 2 | // tonc_asminc.h : header file with goodies for assembly. 3 | // 4 | //! \file tonc_asminc.h 5 | //! \author J Vijn 6 | //! \date 20081019 - 20120519 7 | // 8 | /* === NOTES === 9 | * Cleaned up the macros so that they work with comma-directives as well. 10 | * For use in assembly only! 11 | */ 12 | 13 | #ifndef TONC_ASMINC_H 14 | #define TONC_ASMINC_H 15 | 16 | #if !__ASSEMBLER__ 17 | #error This header file is for use in assembly only! 18 | #endif // /asm only 19 | 20 | 21 | // -------------------------------------------------------------------- 22 | // MACROS 23 | // -------------------------------------------------------------------- 24 | 25 | #define DEF_SIZE(_name) .size _name, .-_name 26 | 27 | //! \name Section definitions for assembly. 28 | //\{ 29 | 30 | #define CSEC_TEXT .text //!< Standard code section directive. 31 | #define CSEC_EWRAM .section .ewram , "ax", %progbits //!< EWRAM code section directive. 32 | #define CSEC_IWRAM .section .iwram, "ax", %progbits //!< IWRAM code section directive. 33 | 34 | #define DSEC_DATA .data //tonc:keys. 26 | */ 27 | 28 | /*! \{ */ 29 | 30 | 31 | // -------------------------------------------------------------------- 32 | // CONSTANTS 33 | // -------------------------------------------------------------------- 34 | 35 | 36 | typedef enum eKeyIndex 37 | { 38 | KI_A=0, KI_B, KI_SELECT, KI_START, 39 | KI_RIGHT, KI_LEFT, KI_UP, KI_DOWN, 40 | KI_R, KI_L, KI_MAX 41 | } eKeyIndex; 42 | 43 | #define KEY_FULL 0xFFFFFFFF //!< Define for checking all keys. 44 | 45 | 46 | // -------------------------------------------------------------------- 47 | // MACROS 48 | // -------------------------------------------------------------------- 49 | 50 | 51 | // Check which of the specified keys are down or up right now 52 | 53 | #define KEY_DOWN_NOW(key) (~(REG_KEYINPUT) & key) 54 | #define KEY_UP_NOW(key) ( (REG_KEYINPUT) & key) 55 | 56 | // test whether all keys are pressed, released, whatever. 57 | // Example use: 58 | // KEY_EQ(key_hit, KEY_L | KEY_R) 59 | // will be true if and only if KEY_L and KEY_R are _both_ being pressed 60 | #define KEY_EQ(key_fun, keys) ( key_fun(keys) == (keys) ) 61 | 62 | #define KEY_TRIBOOL(fnKey, plus, minus) \ 63 | ( bit_tribool(fnKey(KEY_FULL), plus, minus) ) 64 | 65 | 66 | // -------------------------------------------------------------------- 67 | // GLOBALS 68 | // -------------------------------------------------------------------- 69 | 70 | 71 | extern u16 __key_curr, __key_prev; 72 | 73 | 74 | // -------------------------------------------------------------------- 75 | // PROTOTYPES 76 | // -------------------------------------------------------------------- 77 | 78 | 79 | void key_wait_for_clear(u32 key); // wait for keys to be up 80 | 81 | //! \name Basic synchonous keystates 82 | //\{ 83 | void key_poll(); 84 | INLINE u32 key_curr_state(void); 85 | INLINE u32 key_prev_state(void); 86 | 87 | INLINE u32 key_is_down(u32 key); 88 | INLINE u32 key_is_up(u32 key); 89 | 90 | INLINE u32 key_was_down(u32 key); 91 | INLINE u32 key_was_up(u32 key); 92 | //\} 93 | 94 | //! \name Transitional keystates 95 | //\{ 96 | INLINE u32 key_transit(u32 key); 97 | INLINE u32 key_held(u32 key); 98 | INLINE u32 key_hit(u32 key); 99 | INLINE u32 key_released(u32 key); 100 | //\} 101 | 102 | //! \name Tribools 103 | //\{ 104 | INLINE int key_tri_horz(void); 105 | INLINE int key_tri_vert(void); 106 | INLINE int key_tri_shoulder(void); 107 | INLINE int key_tri_fire(void); 108 | //\} 109 | 110 | //! \name Key repeats 111 | //\{ 112 | u32 key_repeat(u32 keys); 113 | 114 | void key_repeat_mask(u32 mask); 115 | void key_repeat_limits(uint delay, uint repeat); 116 | //\} 117 | 118 | void key_wait_till_hit(u16 key); 119 | 120 | 121 | // -------------------------------------------------------------------- 122 | // INLINES 123 | // -------------------------------------------------------------------- 124 | 125 | 126 | //! Get current keystate 127 | INLINE u32 key_curr_state(void) { return __key_curr; } 128 | 129 | //! Get previous key state 130 | INLINE u32 key_prev_state(void) { return __key_prev; } 131 | 132 | //! Gives the keys of \a key that are currently down 133 | INLINE u32 key_is_down(u32 key) { return __key_curr & key; } 134 | 135 | //! Gives the keys of \a key that are currently up 136 | INLINE u32 key_is_up(u32 key) { return ~__key_curr & key; } 137 | 138 | //! Gives the keys of \a key that were previously down 139 | INLINE u32 key_was_down(u32 key) { return __key_prev & key; } 140 | 141 | //! Gives the keys of \a key that were previously down 142 | INLINE u32 key_was_up(u32 key) { return ~__key_prev & key; } 143 | 144 | 145 | 146 | //! Gives the keys of \a key that are different from before 147 | INLINE u32 key_transit(u32 key) 148 | { return ( __key_curr ^ __key_prev) & key; } 149 | 150 | //! Gives the keys of \a key that are being held down 151 | INLINE u32 key_held(u32 key) 152 | { return ( __key_curr & __key_prev) & key; } 153 | 154 | //! Gives the keys of \a key that are pressed (down now but not before) 155 | INLINE u32 key_hit(u32 key) 156 | { return ( __key_curr &~ __key_prev) & key; } 157 | 158 | //! Gives the keys of \a key that are being released 159 | INLINE u32 key_released(u32 key) 160 | { return (~__key_curr & __key_prev) & key; } 161 | 162 | 163 | 164 | //! Horizontal tribool (right,left)=(+,-) 165 | INLINE int key_tri_horz(void) 166 | { return bit_tribool(__key_curr, KI_RIGHT, KI_LEFT); } 167 | 168 | //! Vertical tribool (down,up)=(+,-) 169 | INLINE int key_tri_vert(void) 170 | { return bit_tribool(__key_curr, KI_DOWN, KI_UP); } 171 | 172 | //! Shoulder-button tribool (R,L)=(+,-) 173 | INLINE int key_tri_shoulder(void) 174 | { return bit_tribool(__key_curr, KI_R, KI_L); } 175 | 176 | //! Fire-button tribool (A,B)=(+,-) 177 | INLINE int key_tri_fire(void) 178 | { return bit_tribool(__key_curr, KI_A, KI_B); } 179 | 180 | 181 | /* \} */ 182 | 183 | 184 | #endif // TONC_INPUT 185 | -------------------------------------------------------------------------------- /include/tonc_irq.h: -------------------------------------------------------------------------------- 1 | // 2 | // Interrupt header 3 | // 4 | //! \file tonc_irq.h 5 | //! \author J Vijn 6 | //! \date 20060508 - 20080326 7 | // 8 | // === NOTES === 9 | 10 | 11 | #ifndef TONC_IRQ 12 | #define TONC_IRQ 13 | 14 | #include "tonc_memmap.h" 15 | #include "tonc_memdef.h" 16 | 17 | 18 | // -------------------------------------------------------------------- 19 | // CONSTANTS 20 | // -------------------------------------------------------------------- 21 | 22 | 23 | /*! \addtogroup grpIrq 24 | \brief Hardware interrupt management. 25 | 26 | 27 | For details, see 28 | tonc:irq 29 | */ 30 | /*! \{ */ 31 | 32 | //! IRQ indices, to be used in most functions. 33 | typedef enum eIrqIndex 34 | { 35 | II_VBLANK=0,II_HBLANK, II_VCOUNT, II_TIMER0, 36 | II_TIMER1, II_TIMER2, II_TIMER3, II_SERIAL, 37 | II_DMA0, II_DMA1, II_DMA2, II_DMA3, 38 | II_KEYPAD, II_GAMEPAK, II_MAX 39 | } eIrqIndex; 40 | 41 | 42 | //! \name Options for irq_set 43 | //\{ 44 | 45 | #define ISR_LAST 0x0040 //!< Last isr in line (Lowest priority) 46 | #define ISR_REPLACE 0x0080 //!< Replace old isr if existing (prio ignored) 47 | 48 | #define ISR_PRIO_MASK 0x003F //!< 49 | #define ISR_PRIO_SHIFT 0 50 | #define ISR_PRIO(n) ((n)< screen) functions, could be useful 69 | // inverses (prototypes) 70 | INLINE void obj_aff_scale_inv(OBJ_AFFINE *oa, FIXED wx, FIXED wy); 71 | INLINE void obj_aff_rotate_inv(OBJ_AFFINE *oa, u16 theta); 72 | INLINE void obj_aff_shearx_inv(OBJ_AFFINE *oa, FIXED hx); 73 | INLINE void obj_aff_sheary_inv(OBJ_AFFINE *oa, FIXED hy); 74 | 75 | /*! \} */ 76 | 77 | 78 | // -------------------------------------------------------------------- 79 | // INLINES 80 | // -------------------------------------------------------------------- 81 | 82 | 83 | /*! \addtogroup grpVideoObj */ 84 | /*! \{ */ 85 | 86 | //! Set the attributes of an object. 87 | INLINE OBJ_ATTR *obj_set_attr(OBJ_ATTR *obj, u16 a0, u16 a1, u16 a2) 88 | { 89 | obj->attr0= a0; obj->attr1= a1; obj->attr2= a2; 90 | return obj; 91 | } 92 | 93 | //! Set the position of \a obj 94 | INLINE void obj_set_pos(OBJ_ATTR *obj, int x, int y) 95 | { 96 | BFN_SET(obj->attr0, y, ATTR0_Y); 97 | BFN_SET(obj->attr1, x, ATTR1_X); 98 | } 99 | 100 | //! Copies \a count OAM entries from \a src to \a dst. 101 | INLINE void oam_copy(OBJ_ATTR *dst, const OBJ_ATTR *src, uint count) 102 | { memcpy32(dst, src, count*2); } 103 | 104 | //! Hide an object. 105 | INLINE void obj_hide(OBJ_ATTR *obj) 106 | { BFN_SET2(obj->attr0, ATTR0_HIDE, ATTR0_MODE); } 107 | 108 | //! Unhide an object. 109 | /*! \param obj Object to unhide. 110 | * \param mode Object mode to unhide to. Necessary because this affects 111 | * the affine-ness of the object. 112 | */ 113 | INLINE void obj_unhide(OBJ_ATTR *obj, u16 mode) 114 | { BFN_SET2(obj->attr0, mode, ATTR0_MODE); } 115 | 116 | 117 | //! Get object's sizes as a byte array 118 | INLINE const u8 *obj_get_size(const OBJ_ATTR *obj) 119 | { return oam_sizes[obj->attr0>>14][obj->attr1>>14]; } 120 | 121 | //! Get object's width 122 | INLINE int obj_get_width(const OBJ_ATTR *obj) 123 | { return obj_get_size(obj)[0]; } 124 | 125 | //! Gets object's height 126 | INLINE int obj_get_height(const OBJ_ATTR *obj) 127 | { return obj_get_size(obj)[1]; } 128 | 129 | 130 | // --- Affine only --- 131 | 132 | 133 | //! Set the elements of an \a object affine matrix. 134 | INLINE void obj_aff_set(OBJ_AFFINE *oaff, 135 | FIXED pa, FIXED pb, FIXED pc, FIXED pd) 136 | { 137 | oaff->pa= pa; oaff->pb= pb; 138 | oaff->pc= pc; oaff->pd= pd; 139 | } 140 | 141 | //! Set an object affine matrix to the identity matrix 142 | INLINE void obj_aff_identity(OBJ_AFFINE *oaff) 143 | { 144 | oaff->pa= 0x0100l; oaff->pb= 0; 145 | oaff->pc= 0; oaff->pd= 0x0100; 146 | } 147 | 148 | //! Set an object affine matrix for scaling. 149 | INLINE void obj_aff_scale(OBJ_AFFINE *oaff, FIXED sx, FIXED sy) 150 | { 151 | oaff->pa= sx; oaff->pb= 0; 152 | oaff->pc= 0; oaff->pd= sy; 153 | } 154 | 155 | INLINE void obj_aff_shearx(OBJ_AFFINE *oaff, FIXED hx) 156 | { 157 | oaff->pa= 0x0100; oaff->pb= hx; 158 | oaff->pc= 0; oaff->pd= 0x0100; 159 | } 160 | 161 | INLINE void obj_aff_sheary(OBJ_AFFINE *oaff, FIXED hy) 162 | { 163 | oaff->pa= 0x0100; oaff->pb= 0; 164 | oaff->pc= hy; oaff->pd= 0x0100; 165 | } 166 | 167 | 168 | // --- Inverse operations --- 169 | 170 | INLINE void obj_aff_scale_inv(OBJ_AFFINE *oaff, FIXED wx, FIXED wy) 171 | { obj_aff_scale(oaff, ((1<<24)/wx)>>8, ((1<<24)/wy)>>8); } 172 | 173 | INLINE void obj_aff_rotate_inv(OBJ_AFFINE *oaff, u16 theta) 174 | { obj_aff_rotate(oaff, -theta); } 175 | 176 | INLINE void obj_aff_shearx_inv(OBJ_AFFINE *oaff, FIXED hx) 177 | { obj_aff_shearx(oaff, -hx); } 178 | 179 | INLINE void obj_aff_sheary_inv(OBJ_AFFINE *oaff, FIXED hy) 180 | { obj_aff_sheary(oaff, -hy); } 181 | 182 | 183 | /*! \} */ 184 | 185 | #endif // TONC_OAM 186 | 187 | -------------------------------------------------------------------------------- /include/tonc_text.h: -------------------------------------------------------------------------------- 1 | // 2 | // Text system header file 3 | // 4 | //! \file tonc_text.h 5 | //! \author J Vijn 6 | //! \date 20060605 - 20060605 7 | // 8 | // === NOTES === 9 | // 10 | /* === NOTES === 11 | * 20070822: These routines have been superceded by TTE. 12 | * This file is NOT meant to contain the Mother Of All Text Systems. 13 | Rather, this contains the bases to build text-systems on, 14 | whether they are map-based, bitmap-based or sprite-based. 15 | * Text systems tend to be a little fickle, I'll probably add things 16 | over time. 17 | * On use. There are 'standard' initialisers, the txt_init_xxx 18 | things, that set up default conditions: using toncfont, 8x8 chars, 19 | palettes, that sort of thing. For the rest, just use xxx_puts to 20 | write a string and xxx_clrs to clear it again. If you want other 21 | fonts or an other charmap you can change it, within limits. 22 | */ 23 | 24 | 25 | #ifndef TONC_TEXT 26 | #define TONC_TEXT 27 | 28 | #include "tonc_memmap.h" 29 | #include "tonc_memdef.h" 30 | #include "tonc_core.h" 31 | 32 | /*! \addtogroup grpText 33 | \deprecated While potentially still useful, TTE is considerably 34 | more advanced. Use that instead. 35 | */ 36 | 37 | /*! \defgroup grpTextTile Tilemap text 38 | * \ingroup grpText 39 | */ 40 | 41 | /*! \defgroup grpTextBm Bitmap text 42 | * \ingroup grpText 43 | */ 44 | 45 | /*! \defgroup grpTextObj Object text 46 | * \ingroup grpText 47 | */ 48 | 49 | 50 | // -------------------------------------------------------------------- 51 | // CONSTANTS 52 | // -------------------------------------------------------------------- 53 | 54 | 55 | #define toncfontTilesLen 768 56 | 57 | 58 | // -------------------------------------------------------------------- 59 | // CLASSES 60 | // -------------------------------------------------------------------- 61 | 62 | 63 | //! 64 | typedef struct tagTXT_BASE 65 | { 66 | u16 *dst0; //!< writing buffer starting point 67 | u32 *font; // pointer to font used 68 | u8 *chars; // character map (chars as in letters, not tiles) 69 | u8 *cws; // char widths (for VWF) 70 | u8 dx,dy; // letter distances 71 | u16 flags; // for later 72 | u8 extra[12]; // ditto 73 | } ALIGN4 TXT_BASE; 74 | 75 | 76 | // -------------------------------------------------------------------- 77 | // GLOBALS 78 | // -------------------------------------------------------------------- 79 | 80 | 81 | extern const u32 toncfontTiles[192]; 82 | 83 | extern TXT_BASE __txt_base, *gptxt; 84 | extern u8 txt_lut[256]; 85 | 86 | extern u16 *vid_page; 87 | 88 | 89 | // -------------------------------------------------------------------- 90 | // PROTOTYPES 91 | // -------------------------------------------------------------------- 92 | 93 | 94 | // --- overall (tonc_text.c) --- 95 | 96 | /*! \addtogroup grpText 97 | \brief Text writers for all modes and objects. 98 | 99 | There are three types of text writers here: 100 |
    101 |
  • Tilemap (se_ routines) 102 |
  • Bitmap (bm_ and mx_ routines) 103 |
  • Object (obj_ routines) 104 |
105 | Each of these has an initializer, a char writer, and string writer 106 | and a string clearer. The general interface for all of these is 107 | foo(x, y, string/char, special), Where x and y are the 108 | positions in pixels, and special depends on the mode-type: 109 | it can be a color, base screenentry or whatever.
110 | The clearing routines also use a string parameter, which is used to 111 | indicate the exact area to clear. You're free to clear the whole 112 | buffer if you like. 113 | */ 114 | /*! \{ */ 115 | 116 | void txt_init_std(); 117 | void txt_bup_1toX(void *dstv, const void *srcv, u32 len, int bpp, u32 base); 118 | 119 | /*! \} */ 120 | 121 | 122 | //! \addtogroup grpTextTile 123 | /*! \{ */ 124 | 125 | // --- Tilemap text (tonc_text_map.c) --- 126 | void txt_init_se(int bgnr, u16 bgcnt, SCR_ENTRY se0, u32 clrs, u32 base); 127 | void se_putc(int x, int y, int c, SCR_ENTRY se0); 128 | void se_puts(int x, int y, const char *str, SCR_ENTRY se0); 129 | void se_clrs(int x, int y, const char *str, SCR_ENTRY se0); 130 | 131 | /*! \} */ 132 | 133 | 134 | // --- Bitmap text (tonc_text_bm.c) --- 135 | 136 | //! \addtogroup grpTextBm 137 | /*! \{ */ 138 | 139 | //! \name Mode-independent functions 140 | //\{ 141 | void bm_putc(int x, int y, int c, COLOR clr); 142 | void bm_puts(int x, int y, const char *str, COLOR clr); 143 | void bm_clrs(int x, int y, const char *str, COLOR clr); 144 | //\} 145 | 146 | //! \name Mode 3 functions 147 | //\{ 148 | INLINE void m3_putc(int x, int y, int c, COLOR clr); 149 | INLINE void m3_puts(int x, int y, const char *str, COLOR clr); 150 | INLINE void m3_clrs(int x, int y, const char *str, COLOR clr); 151 | //\} 152 | 153 | //! \name Mode 4 functions 154 | //\{ 155 | INLINE void m4_putc(int x, int y, int c, u8 clrid); 156 | INLINE void m4_puts(int x, int y, const char *str, u8 clrid); 157 | INLINE void m4_clrs(int x, int y, const char *str, u8 clrid); 158 | //\} 159 | 160 | //! \name Mode 5 functions 161 | //\{ 162 | INLINE void m5_putc(int x, int y, int c, COLOR clr); 163 | INLINE void m5_puts(int x, int y, const char *str, COLOR clr); 164 | INLINE void m5_clrs(int x, int y, const char *str, COLOR clr); 165 | //\} 166 | 167 | // \name Internal routines 168 | //\{ 169 | void bm16_putc(u16 *dst, int c, COLOR clr, int pitch); 170 | void bm16_puts(u16 *dst, const char *str, COLOR clr, int pitch); 171 | void bm16_clrs(u16 *dst, const char *str, COLOR clr, int pitch); 172 | 173 | void bm8_putc(u16 *dst, int c, u8 clrid); 174 | void bm8_puts(u16 *dst, const char *str, u8 clrid); 175 | //\} 176 | 177 | 178 | /*! \} */ 179 | 180 | 181 | // --- Object text (tonc_text_oam.c) --- 182 | 183 | //! \addtogroup grpTextObj 184 | /*! \{ */ 185 | 186 | INLINE void obj_putc2(int x, int y, int c, u16 attr2, 187 | OBJ_ATTR *obj0); 188 | INLINE void obj_puts2(int x, int y, const char *str, u16 attr2, 189 | OBJ_ATTR *obj0); 190 | 191 | void txt_init_obj(OBJ_ATTR *obj0, u16 attr2, u32 clrs, u32 base); 192 | void obj_putc(int x, int y, int c, u16 attr2); 193 | void obj_puts(int x, int y, const char *str, u16 attr2); 194 | void obj_clrs(int x, int y, const char *str); 195 | 196 | /*! \} */ 197 | 198 | 199 | // -------------------------------------------------------------------- 200 | // MACROS 201 | // -------------------------------------------------------------------- 202 | 203 | // === INLINES========================================================= 204 | 205 | 206 | // --- Bitmap text --- 207 | 208 | //! Write character \a c to (x, y) in color \a clr in mode 3 209 | INLINE void m3_putc(int x, int y, int c, COLOR clr) 210 | { bm16_putc(&vid_mem[y*240+x], c, clr, 240); } 211 | 212 | //! Write string \a str to (x, y) in color \a clr in mode 3 213 | INLINE void m3_puts(int x, int y, const char *str, COLOR clr) 214 | { bm16_puts(&vid_mem[y*240+x], str, clr, 240); } 215 | 216 | //! Clear the space used by string \a str at (x, y) in color \a clr in mode 3 217 | INLINE void m3_clrs(int x, int y, const char *str, COLOR clr) 218 | { bm16_clrs(&vid_mem[y*240+x], str, clr, 240); } 219 | 220 | 221 | 222 | //! Write character \a c to (x, y) in color-index \a clrid in mode 4 223 | INLINE void m4_putc(int x, int y, int c, u8 clrid) 224 | { bm8_putc(&vid_page[(y*240+x)>>1], c, clrid); } 225 | 226 | //! Write string \a str to (x, y) in color-index \a clrid in mode 4 227 | INLINE void m4_puts(int x, int y, const char *str, u8 clrid) 228 | { bm8_puts(&vid_page[(y*240+x)>>1], str, clrid); } 229 | 230 | //! Clear the space used by string \a str at (x, y) in color-index \a clrid in mode 4 231 | INLINE void m4_clrs(int x, int y, const char *str, u8 clrid) 232 | { 233 | gptxt->dx >>= 1; 234 | bm16_clrs(&vid_page[(y*240+x)>>1], str, dup8(clrid), 120); 235 | gptxt->dx <<= 1; 236 | } 237 | 238 | //! Write character \a c to (x, y) in color \a clr in mode 5 239 | INLINE void m5_putc(int x, int y, int c, COLOR clr) 240 | { bm16_putc(&vid_page[y*160+x], c, clr, 160); } 241 | 242 | //! Write string \a str to (x, y) in color \a clr in mode 5 243 | INLINE void m5_puts(int x, int y, const char *str, COLOR clr) 244 | { bm16_puts(&vid_page[y*160+x], str, clr, 160); } 245 | 246 | //! Clear the space used by string \a str at (x, y) in color \a clr in mode 5 247 | INLINE void m5_clrs(int x, int y, const char *str, COLOR clr) 248 | { bm16_clrs(&vid_page[y*160+x], str, clr, 160); } 249 | 250 | 251 | 252 | // --- Object text --- 253 | 254 | //! Write character \a c to (x, y) in color \a clr using objects \a obj0 and on 255 | INLINE void obj_putc2(int x, int y, int c, u16 attr2, 256 | OBJ_ATTR *obj0) 257 | { 258 | gptxt->dst0= (u16*)obj0; 259 | obj_putc(x, y, c, attr2); 260 | } 261 | 262 | //! Write string \a str to (x, y) in color \a clr using objects \a obj0 and on 263 | INLINE void obj_puts2(int x, int y, const char *str, u16 attr2, 264 | OBJ_ATTR *obj0) 265 | { 266 | gptxt->dst0= (u16*)obj0; 267 | obj_puts(x, y, str, attr2); 268 | } 269 | 270 | #endif // TONC_TEXT 271 | -------------------------------------------------------------------------------- /include/tonc_tte.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devkitPro/libtonc/ccc03fa321e56f51aed5e2ee1d6e3df3d1cbc803/include/tonc_tte.h -------------------------------------------------------------------------------- /libtonc.txt: -------------------------------------------------------------------------------- 1 | 2 | ---------------------------------------------------------- 3 | // \\ 4 | || TTT q cc || 5 | || TT qq c c bb || 6 | || TT qq c c lll b b || 7 | || TT ooo qqq cc l i i b b || 8 | || TT o q c c lll i i b b || 9 | || TT o q c c l ii b b || 10 | || TTTTTTTT ooo q c cccc llll i i b || 11 | || i i b b || 12 | || ii b || 13 | || || 14 | ||============================================================|| 15 | || libtonc || 16 | || part of TONC: GBA Programming in rot 13 || 17 | || v a0 || 18 | || 20050316-20091221, J Vijn || 19 | \\___________________________________________________________// 20 | 21 | 22 | A revamped libtonc. It's actually changed quite a bit since the 23 | first incarnations. I've renamed a good deal of the defines, 24 | structures and functions, added some text functions and tried to 25 | make things a little bit faster. 26 | 27 | // === NOTES === 28 | 29 | * I'm making liberal use of typedefs and structs this time around. 30 | In fact, you can pretty much say I've typedef'd the crap out of 31 | it. Used lots and lots of structures too. Structs are good. They, 32 | well structure things so that accessing becomse easier (tile_mem). 33 | Also, it allows the compiler to optimise certain things like copies 34 | (TILE struct) and clustered register accesses (DMACHN and BGAFF). 35 | Yes, this creates a bit of a learning curve, but it's worth it. 36 | * Macros. Yes, the C preprocessor is evil, but there's always been 37 | a lot of gray area in game programming *cough* global variables 38 | *cough*. Don't get scared by the bitfield macros BF_MSK and 39 | BF_UNMSK. The pretty much do what bit-fields do. Only faster. 40 | Btw, the "do {} while(0)" is just a construct that is used to keep 41 | multi-statement macros safe (after an if for example). No trace of 42 | loopiness will remain in the final binary if compiled with 43 | optimisations. 44 | * You will find that a number of the defines have an underscore prefix. 45 | You will also find that this always concerns 0 defines (i.e., default 46 | values). I do this so you can tell that they are the default values 47 | and won't do something silly like reg&0 when checking for a bit or 48 | reg|=0 when setting one. 49 | * Broken record advice: GBA is a 32bit machine. Use int if you can, 50 | char or short if you must. You are NOT saving space by using u8 or 51 | u16 as variables. In fact, probably just the opposite, and it's 52 | slower too. 53 | 54 | 55 | 56 | // Notes to self: 57 | * check DMA flags once more 58 | * swi_ex names? 59 | * text stuff should be singletons 60 | * timer: TM_ or TMR_ ? 61 | * INT_ALL ??? 62 | * IN_SBSS !! 63 | * Oi! Where'd by xxx_BUILDs go? -------------------------------------------------------------------------------- /src/font/sys8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devkitPro/libtonc/ccc03fa321e56f51aed5e2ee1d6e3df3d1cbc803/src/font/sys8.png -------------------------------------------------------------------------------- /src/font/sys8.s: -------------------------------------------------------------------------------- 1 | 2 | @{{BLOCK(sys8) 3 | 4 | .section .rodata 5 | .align 2 6 | .global sys8Font 7 | sys8Font: 8 | .word sys8Glyphs, 0, 0 9 | .hword 32, 96 10 | .byte 8, 8 11 | .byte 8, 8 12 | .hword 8 13 | .byte 1, 0 14 | 15 | .section .rodata 16 | .align 2 17 | .global sys8Glyphs @ 768 unsigned chars 18 | sys8Glyphs: 19 | .word 0x00000000,0x00000000,0x18181818,0x00180018,0x00003636,0x00000000,0x367F3636,0x0036367F 20 | .word 0x3C067C18,0x00183E60,0x1B356600,0x0033566C,0x6E16361C,0x00DE733B,0x000C1818,0x00000000 21 | .word 0x0C0C1830,0x0030180C,0x3030180C,0x000C1830,0xFF3C6600,0x0000663C,0x7E181800,0x00001818 22 | .word 0x00000000,0x0C181800,0x7E000000,0x00000000,0x00000000,0x00181800,0x183060C0,0x0003060C 23 | .word 0x7E76663C,0x003C666E,0x181E1C18,0x00181818,0x3060663C,0x007E0C18,0x3860663C,0x003C6660 24 | .word 0x33363C38,0x0030307F,0x603E067E,0x003C6660,0x3E060C38,0x003C6666,0x3060607E,0x00181818 25 | .word 0x3C66663C,0x003C6666,0x7C66663C,0x001C3060,0x00181800,0x00181800,0x00181800,0x0C181800 26 | .word 0x06186000,0x00006018,0x007E0000,0x0000007E,0x60180600,0x00000618,0x3060663C,0x00180018 27 | 28 | .word 0x5A5A663C,0x003C067A,0x7E66663C,0x00666666,0x3E66663E,0x003E6666,0x06060C78,0x00780C06 29 | .word 0x6666361E,0x001E3666,0x1E06067E,0x007E0606,0x1E06067E,0x00060606,0x7606663C,0x007C6666 30 | .word 0x7E666666,0x00666666,0x1818183C,0x003C1818,0x60606060,0x003C6660,0x0F1B3363,0x0063331B 31 | .word 0x06060606,0x007E0606,0x6B7F7763,0x00636363,0x7B6F6763,0x00636373,0x6666663C,0x003C6666 32 | .word 0x3E66663E,0x00060606,0x3333331E,0x007E3B33,0x3E66663E,0x00666636,0x3C0E663C,0x003C6670 33 | .word 0x1818187E,0x00181818,0x66666666,0x003C6666,0x66666666,0x00183C3C,0x6B636363,0x0063777F 34 | .word 0x183C66C3,0x00C3663C,0x183C66C3,0x00181818,0x0C18307F,0x007F0306,0x0C0C0C3C,0x003C0C0C 35 | .word 0x180C0603,0x00C06030,0x3030303C,0x003C3030,0x00663C18,0x00000000,0x00000000,0x003F0000 36 | 37 | .word 0x00301818,0x00000000,0x603C0000,0x007C667C,0x663E0606,0x003E6666,0x063C0000,0x003C0606 38 | .word 0x667C6060,0x007C6666,0x663C0000,0x003C067E,0x0C3E0C38,0x000C0C0C,0x667C0000,0x3C607C66 39 | .word 0x663E0606,0x00666666,0x18180018,0x00301818,0x30300030,0x1E303030,0x36660606,0x0066361E 40 | .word 0x18181818,0x00301818,0x7F370000,0x0063636B,0x663E0000,0x00666666,0x663C0000,0x003C6666 41 | .word 0x663E0000,0x06063E66,0x667C0000,0x60607C66,0x663E0000,0x00060606,0x063C0000,0x003E603C 42 | .word 0x0C3E0C0C,0x00380C0C,0x66660000,0x007C6666,0x66660000,0x00183C66,0x63630000,0x00367F6B 43 | .word 0x36630000,0x0063361C,0x66660000,0x0C183C66,0x307E0000,0x007E0C18,0x0C181830,0x00301818 44 | .word 0x18181818,0x00181818,0x3018180C,0x000C1818,0x003B6E00,0x00000000,0x00000000,0x00000000 45 | 46 | @}}BLOCK(sys8) 47 | -------------------------------------------------------------------------------- /src/font/verdana10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devkitPro/libtonc/ccc03fa321e56f51aed5e2ee1d6e3df3d1cbc803/src/font/verdana10.png -------------------------------------------------------------------------------- /src/font/verdana10.s: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devkitPro/libtonc/ccc03fa321e56f51aed5e2ee1d6e3df3d1cbc803/src/font/verdana10.s -------------------------------------------------------------------------------- /src/font/verdana9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devkitPro/libtonc/ccc03fa321e56f51aed5e2ee1d6e3df3d1cbc803/src/font/verdana9.png -------------------------------------------------------------------------------- /src/font/verdana9.s: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devkitPro/libtonc/ccc03fa321e56f51aed5e2ee1d6e3df3d1cbc803/src/font/verdana9.s -------------------------------------------------------------------------------- /src/font/verdana9_b4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devkitPro/libtonc/ccc03fa321e56f51aed5e2ee1d6e3df3d1cbc803/src/font/verdana9_b4.png -------------------------------------------------------------------------------- /src/font/verdana9_b4.s: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devkitPro/libtonc/ccc03fa321e56f51aed5e2ee1d6e3df3d1cbc803/src/font/verdana9_b4.s -------------------------------------------------------------------------------- /src/font/verdana9b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devkitPro/libtonc/ccc03fa321e56f51aed5e2ee1d6e3df3d1cbc803/src/font/verdana9b.png -------------------------------------------------------------------------------- /src/font/verdana9b.s: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devkitPro/libtonc/ccc03fa321e56f51aed5e2ee1d6e3df3d1cbc803/src/font/verdana9b.s -------------------------------------------------------------------------------- /src/font/verdana9i.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devkitPro/libtonc/ccc03fa321e56f51aed5e2ee1d6e3df3d1cbc803/src/font/verdana9i.png -------------------------------------------------------------------------------- /src/font/verdana9i.s: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devkitPro/libtonc/ccc03fa321e56f51aed5e2ee1d6e3df3d1cbc803/src/font/verdana9i.s -------------------------------------------------------------------------------- /src/pre1.3/tonc_bitmap.c: -------------------------------------------------------------------------------- 1 | // 2 | // Bitmap mode functionality 3 | // 4 | //! \file tonc_bitmap.c 5 | //! \author J Vijn 6 | //! \date 20060604 - 20060604 7 | // 8 | /* === NOTES === 9 | * 20070822. These are old routines, which have been replaced by 10 | 'bmp8_' and 'bmp16' variants. 11 | */ 12 | 13 | #include "tonc_memmap.h" 14 | #include "tonc_core.h" 15 | #include "tonc_video.h" 16 | 17 | // --- Internal drawing routines -------------------------------------- 18 | 19 | // --- 8bit bitmap --- 20 | 21 | //! Draw a horizontal line in 8bit mode; internal routine. 22 | /*! \param dst Destination buffer. 23 | * \param width Length of line. 24 | * \param clrid Color index to draw. 25 | * \note Does not do normalization or bounds checks. 26 | */ 27 | void bm8_hline(u8 *dst, int width, u8 clrid) 28 | { 29 | // TODO: add normalization 30 | 31 | u16 *phw= (u16*)((u32)dst&~1); 32 | if( (u32)dst&1 ) 33 | { 34 | *phw= (*phw & 0xFF) + (clrid<<8); 35 | width--; phw++; 36 | } 37 | if(width&1) 38 | phw[width>>1]= (phw[width>>1]&~0xFF) + clrid; 39 | width >>= 1; 40 | if(width) 41 | memset16(phw, dup8(clrid), width); 42 | } 43 | 44 | //! Draw a vertical line in 8bit mode; internal routine. 45 | /*! \param dst Destination buffer. 46 | * \param height Length of line. 47 | * \param clrid Color index to draw. 48 | * \param pitch Pitch of buffer. 49 | * \note Does not do normalization or bounds checks. 50 | */ 51 | void bm8_vline(u8 *dst, int height, u8 clrid, int pitch) 52 | { 53 | u16 *phw= (u16*)((u32)dst&~1); 54 | pitch >>= 1; 55 | if( (u32)dst&1 ) 56 | { 57 | while(height--) 58 | { *phw= (*phw& 0xFF) + (clrid<<8); phw += pitch; } 59 | } 60 | else 61 | { 62 | while(height--) 63 | { *phw= (*phw&~0xFF) + clrid; phw += pitch; } 64 | } 65 | } 66 | 67 | //! Draw a rectangle in 8bit mode; internal routine. 68 | /*! \param dst Destination buffer. 69 | * \param width Rectangle width. 70 | * \param height Rectangle height. 71 | * \param clrid Color index to draw. 72 | * \param pitch Pitch of buffer. 73 | * \note Does not do normalization or bounds checks. 74 | */ 75 | void bm8_rect(u8 *dst, int width, int height, u8 clrid, int pitch) 76 | { 77 | int h; 78 | u16 *dst16, pxl; 79 | pitch >>= 1; 80 | if( (u32)dst&1 ) // crap, unaligned pixel on left 81 | { 82 | dst16= (u16*)((u32)dst&~1); 83 | h= height; 84 | while(h--) 85 | { *dst16= (*dst16&0xFF)|(clrid<<8); dst16 += pitch; } 86 | // adjust for drawn line 87 | width--; 88 | dst++; 89 | } 90 | // dst is even here 91 | 92 | if(width&1) // crap, unaligned pixel on right 93 | { 94 | dst16= (u16*)&dst[width&~1]; 95 | h= height; 96 | while(h--) 97 | { *dst16= (*dst16&0xFF00)|clrid; dst16 += pitch; } 98 | // no adjustment required ... yet 99 | } 100 | 101 | width >>= 1; 102 | if(width == 0) 103 | return; 104 | 105 | dst16= (u16*)dst; 106 | pxl= clrid|(clrid<<8); 107 | 108 | while(height--) // main stint 109 | { 110 | memset16(dst16, pxl, width); 111 | dst16 += pitch; 112 | } 113 | } 114 | 115 | //! Draw a rectangle border in 8bit mode; internal routine 116 | /*! \param dst Destination buffer. 117 | * \param width Frame width. 118 | * \param height Frame height. 119 | * \param clrid Color index to draw. 120 | * \param pitch Pitch of buffer. 121 | * \note Does not do normalization or bounds checks. 122 | */ 123 | void bm8_frame(u8 *dst, int width, int height, u8 clrid, int pitch) 124 | { 125 | // left and right lines 126 | bm8_vline(dst, height, clrid, pitch); 127 | bm8_vline(&dst[width-1], height, clrid, pitch); 128 | 129 | if((u32)dst&1) 130 | { dst++; width--; } 131 | width >>= 1; 132 | if(width==0) 133 | return; 134 | // top and bottom lines (if necessary) 135 | memset16(dst, dup8(clrid), width); 136 | if(height>1) 137 | memset16(&dst[pitch], dup8(clrid), width); 138 | } 139 | 140 | // --- 16bit bitmap --- 141 | 142 | //! Draw a horizontal line in 16bit mode; internal routine 143 | /*! \param dst Destination buffer. 144 | * \param width Length of line. 145 | * \param clr Color to draw. 146 | * \note Does not do normalization or bounds checks. 147 | */ 148 | void bm16_hline(u16 *dst, int width, u16 clr) 149 | { 150 | memset16(dst, clr, width); 151 | } 152 | 153 | //! Draw a vertical line in 16bit mode; internal routine 154 | /*! \param dst Destination buffer. 155 | * \param height Length of line. 156 | * \param clr Color to draw. 157 | * \param pitch Pitch of buffer. 158 | * \note Does not do normalization or bounds checks. 159 | */ 160 | void bm16_vline(u16 *dst, int height, u16 clr, int pitch) 161 | { 162 | while(height--) 163 | { 164 | *dst= clr; 165 | dst += pitch; 166 | } 167 | } 168 | 169 | //! Draw a line in 16bit mode; internal routine 170 | /*! \param dst Destination buffer. 171 | * \param dx Horizontal line length. 172 | * \param dy Vertical line length. 173 | * \param clr Color to draw. 174 | * \param pitch Pitch of buffer. 175 | */ 176 | void bm16_line(u16 *dst, int dx, int dy, COLOR clr, int pitch) 177 | { 178 | int ii, xstep, ystep, dd; 179 | 180 | // --- Normalization --- 181 | 182 | if(dx<0) 183 | { xstep= -1; dx= -dx; } 184 | else 185 | xstep= +1; 186 | 187 | if(dy<0) 188 | { ystep= -pitch; dy= -dy; } 189 | else 190 | ystep= +pitch; 191 | 192 | // --- Drawing --- 193 | 194 | if(dy == 0) // Horizontal 195 | { 196 | for(ii=0; ii<=dx; ii++) 197 | dst[ii*xstep]= clr; 198 | } 199 | else if(dx == 0) // Vertical 200 | { 201 | for(ii=0; ii<=dy; ii++) 202 | dst[ii*ystep]= clr; 203 | } 204 | else if(dx>=dy) // Diagonal, slope <= 1 205 | { 206 | dd= 2*dy - dx; 207 | 208 | for(ii=0; ii<=dx; ii++) 209 | { 210 | *dst= clr; 211 | if(dd >= 0) 212 | { dd -= 2*dx; dst += ystep; } 213 | 214 | dd += 2*dy; 215 | dst += xstep; 216 | } 217 | } 218 | else // Diagonal, slope > 1 219 | { 220 | dd= 2*dx - dy; 221 | 222 | for(ii=0; ii<=dy; ii++) 223 | { 224 | *dst= clr; 225 | if(dd >= 0) 226 | { dd -= 2*dy; dst += xstep; } 227 | 228 | dd += 2*dx; 229 | dst += ystep; 230 | } 231 | } 232 | } 233 | 234 | 235 | //! Draw a rectangle in 16bit mode; internal routine. 236 | /*! \param dst Destination buffer. 237 | * \param width Rectangle width. 238 | * \param height Rectangle height. 239 | * \param clr Color to draw. 240 | * \param pitch Pitch of buffer. 241 | * \note No bound checks; normalization switches TL and RB coords 242 | */ 243 | void bm16_rect(u16 *dst, int width, int height, u16 clr, int pitch) 244 | { 245 | if(width<0) 246 | { dst += width; width= -width; } 247 | 248 | if(height<0) 249 | { dst += height*pitch; height= -height; } 250 | 251 | while(height--) 252 | { 253 | memset16(dst, clr, width); 254 | dst += pitch; 255 | } 256 | } 257 | 258 | //! Draw a rectangle border in 16bit mode; internal routine. 259 | /*! \param dst Destination buffer. 260 | * \param width Frame width. 261 | * \param height Frame height. 262 | * \param clr Color to draw. 263 | * \param pitch Pitch of buffer. 264 | * \note No bound checks; normalization switches TL and RB coords 265 | */ 266 | void bm16_frame(u16 *dst, int width, int height, u16 clr, int pitch) 267 | { 268 | if(width<0) 269 | { dst += width; width= -width; } 270 | 271 | if(height<0) 272 | { dst += height*pitch; height= -height; } 273 | 274 | // top line 275 | memset16(dst, clr, width); 276 | if(height<2) 277 | return; 278 | 279 | dst += pitch; 280 | // center lines 281 | while(--height) 282 | { 283 | *dst= clr; 284 | dst[width-1]= clr; 285 | dst += pitch; 286 | } 287 | // bottom line 288 | memset16(dst, clr, width); 289 | } 290 | -------------------------------------------------------------------------------- /src/pre1.3/tonc_text.c: -------------------------------------------------------------------------------- 1 | // 2 | // Text system file 3 | // 4 | //! \file tonc_text.c 5 | //! \author J Vijn 6 | //! \date 20060605 - 20060605 7 | // 8 | // === NOTES === 9 | // * Since BitUnPack doesn't always work properly (VBA), I've put 10 | // txt_bup_1toX in here to remedy that. Wish I didn't have to. 11 | 12 | #include "tonc_text.h" 13 | 14 | 15 | // -------------------------------------------------------------------- 16 | // GLOBALS 17 | // -------------------------------------------------------------------- 18 | 19 | 20 | u8 txt_lut[256]; 21 | 22 | TXT_BASE __txt_base; 23 | TXT_BASE *gptxt= &__txt_base; 24 | 25 | 26 | // -------------------------------------------------------------------- 27 | // FUNCTIONS 28 | // -------------------------------------------------------------------- 29 | 30 | 31 | void txt_init_std() 32 | { 33 | gptxt->dx= gptxt->dy= 8; 34 | 35 | gptxt->dst0= vid_mem; 36 | gptxt->font= (u32*)toncfontTiles; 37 | gptxt->chars= txt_lut; 38 | gptxt->cws= NULL; 39 | 40 | int ii; 41 | for(ii=0; ii<96; ii++) 42 | gptxt->chars[ii+32]= ii; 43 | } 44 | 45 | void txt_bup_1toX(void *dstv, const void *srcv, u32 len, int dstB, u32 base) 46 | { 47 | u32 *srcL= (u32*)srcv; 48 | u32 *dstL= (u32*)dstv; 49 | 50 | len= (len*dstB+3)>>2; // # dst words 51 | u32 bBase0= base&(1<<31); // add to 0 too? 52 | base &= ~(1<<31); 53 | 54 | 55 | u32 srcBuf=0, srcShift=32; 56 | u32 dstBuf , dstShift; 57 | 58 | while(len--) 59 | { 60 | if(srcShift >= 32) 61 | { 62 | srcBuf= *srcL++; 63 | srcShift= 0; 64 | } 65 | dstBuf=0; 66 | for(dstShift=0; dstShift<32; dstShift += dstB) 67 | { 68 | u32 wd= srcBuf&1; 69 | if(wd || bBase0) 70 | wd += base; 71 | dstBuf |= wd<>= 1; 74 | srcShift++; 75 | } 76 | 77 | *dstL++= dstBuf; 78 | } 79 | } 80 | 81 | // EOF 82 | -------------------------------------------------------------------------------- /src/pre1.3/tonc_text_bm.c: -------------------------------------------------------------------------------- 1 | // 2 | //! \file tonc_text_bm.c 3 | //! bitmap modes text system 4 | //! \date 20050317 - 20051009 5 | //! \author cearn 6 | // 7 | // === NOTES === 8 | 9 | #include "tonc_core.h" 10 | #include "tonc_text.h" 11 | 12 | 13 | // -------------------------------------------------------------------- 14 | // FUNCTIONS 15 | // -------------------------------------------------------------------- 16 | 17 | 18 | // === BITMAP TEXT ==================================================== 19 | 20 | //! Write character \a c to (x, y) in color \a clr in modes 3,4 or 5. 21 | void bm_putc(int x, int y, int c, COLOR clr) 22 | { 23 | switch(REG_DISPCNT&7) 24 | { 25 | case 3: 26 | m3_putc(x, y, c, clr); break; 27 | case 4: 28 | m4_putc(x, y, c, (u8)clr); break; 29 | case 5: 30 | m5_putc(x, y, c, clr); break; 31 | } 32 | } 33 | 34 | //! Internal 16bit char-printer for modes 3 and 5. 35 | /*! \param dst Destination buffer to write to. 36 | * \param c Character to print. 37 | * \param clr Color to use. 38 | * \param pitch Pitch (in pixels) of the destination buffer. 39 | */ 40 | void bm16_putc(u16 *dst, int ch, COLOR clr, int pitch) 41 | { 42 | if(ch == '\n') // line break 43 | return; 44 | 45 | int ix, iy; 46 | u32 row; 47 | u8 *pch= (u8*)&gptxt->font[2*gptxt->chars[ch]]; 48 | 49 | for(iy=0; iy<8; iy++) 50 | { 51 | row= pch[iy]; 52 | for(ix=0; row>0; row >>= 1, ix++) 53 | if(row&1) 54 | dst[iy*pitch+ix]= clr; 55 | } 56 | } 57 | 58 | //! Internal 8bit char-printer for mode 4. 59 | /*! \param dst Destination buffer to write to. 60 | * \param c Character to print. 61 | * \param clrid Colorindex to use. 62 | * \note \a dst must be halfword aligned for proper output. 63 | */ 64 | void bm8_putc(u16 *dst, int ch, u8 clrid) 65 | { 66 | if(ch == '\n') 67 | return; 68 | 69 | int ix, iy; 70 | u32 row, pxs; 71 | 72 | // point to glyph; each line is one byte 73 | u8 *pch= (u8*)&gptxt->font[2*gptxt->chars[ch]]; 74 | for(iy=0; iy<8; iy++) 75 | { 76 | row= pch[iy]; 77 | for(ix=0; row>0; row >>= 2, ix++) 78 | { 79 | pxs= dst[iy*120+ix]; 80 | if(row&1) 81 | pxs= (pxs&0xFF00) | clrid; 82 | if(row&2) 83 | pxs= (pxs&0x00FF) | (clrid<<8); 84 | 85 | dst[iy*120+ix]= pxs; 86 | } 87 | } 88 | } 89 | 90 | 91 | // --- put string --- 92 | 93 | 94 | //! Write string \a str to (x, y) in color \a clr in modes 3,4 or 5. 95 | void bm_puts(int x, int y, const char *str, COLOR clr) 96 | { 97 | switch(REG_DISPCNT&7) 98 | { 99 | case 3: 100 | m3_puts(x, y, str, clr); break; 101 | case 4: 102 | m4_puts(x, y, str, (u8)clr); break; 103 | case 5: 104 | m5_puts(x, y, str, clr); break; 105 | } 106 | } 107 | 108 | //! Internal 16bit string-printer for modes 3 and 5. 109 | /*! \param dst Destination buffer to write to. 110 | * \param str String to print. 111 | * \param clr Color to use. 112 | * \param pitch Pitch (in pixels) of the destination buffer. 113 | */ 114 | void bm16_puts(u16 *dst, const char *str, COLOR clr, int pitch) 115 | { 116 | int c, x=0; 117 | u8 *pch; 118 | 119 | while((c=*str++) != 0) 120 | { 121 | if(c == '\n') // line break 122 | { 123 | dst += pitch*gptxt->dy; 124 | x=0; 125 | } 126 | else // normal character 127 | { 128 | int ix, iy; 129 | u32 row; 130 | // point to glyph; each line is one byte 131 | pch= (u8*)&gptxt->font[2*gptxt->chars[c]]; 132 | for(iy=0; iy<8; iy++) 133 | { 134 | row= pch[iy]; 135 | for(ix=x; row>0; row >>= 1, ix++) 136 | if(row&1) 137 | dst[iy*pitch+ix]= clr; 138 | } 139 | x += gptxt->dx; 140 | } 141 | } 142 | } 143 | 144 | //! Internal 8bit string-printer for mode 4. 145 | /*! \param dst Destination buffer to write to. 146 | * \param str String to print. 147 | * \param clrid Colorindex to use. 148 | * \note \a dst must be halfword aligned for proper output. 149 | */ 150 | void bm8_puts(u16 *dst, const char *str, u8 clrid) 151 | { 152 | int c, x=0, dx= gptxt->dx>>1; 153 | 154 | while((c=*str++) != 0) 155 | { 156 | if(c == '\n') // line break 157 | { 158 | dst += 120*gptxt->dy; 159 | x=0; 160 | } 161 | else // normal character 162 | { 163 | int ix, iy; 164 | u32 row, pxs; 165 | 166 | // point to glyph; each line is one byte 167 | u8 *pch= (u8*)&gptxt->font[2*gptxt->chars[c]]; 168 | for(iy=0; iy<8; iy++) 169 | { 170 | row= pch[iy]; 171 | for(ix=x; row>0; row >>= 2, ix++) 172 | { 173 | pxs= dst[iy*120+ix]; 174 | if(row&1) 175 | pxs= (pxs&0xFF00) | clrid; 176 | if(row&2) 177 | pxs= (pxs&0x00FF) | (clrid<<8); 178 | 179 | dst[iy*120+ix]= pxs; 180 | } 181 | } 182 | x += dx; 183 | } 184 | } 185 | } 186 | 187 | 188 | // --- clear a string --- 189 | 190 | 191 | //! Clear string \a str from (x, y) in color \a clr in modes 3,4 or 5. 192 | void bm_clrs(int x, int y, const char *str, COLOR clr) 193 | { 194 | switch(REG_DISPCNT&7) 195 | { 196 | case 3: 197 | m3_clrs(x, y, str, clr); break; 198 | case 4: 199 | m4_clrs(x, y, str, (u8)clr); break; 200 | case 5: 201 | m5_clrs(x, y, str, clr); break; 202 | } 203 | } 204 | 205 | 206 | // NOTE: it's not worth separating '\0' here, that just gives extra code 207 | //! Internal 16bit string-clearer for modes 3 and 5. 208 | /*! \param dst Destination buffer to write to. 209 | * \param str String indicating the area to erase. 210 | * \param clr Color to use. 211 | * \param pitch Pitch (in pixels) of the destination buffer. 212 | */ 213 | void bm16_clrs(u16 *dst, const char *str, COLOR clr, int pitch) 214 | { 215 | int c, nx=0, ny; 216 | 217 | while(1) 218 | { 219 | c= *str++; 220 | if(c=='\n' || c=='\0') 221 | { 222 | if(nx>0) 223 | { 224 | nx *= gptxt->dx; 225 | ny= gptxt->dy; 226 | while(ny--) 227 | { 228 | memset16(dst, clr, nx); 229 | dst += pitch; 230 | } 231 | nx=0; 232 | } 233 | else 234 | dst += gptxt->dy*pitch; 235 | if(c=='\0') 236 | return; 237 | } 238 | else 239 | nx++; 240 | } 241 | 242 | } 243 | 244 | // EOF 245 | -------------------------------------------------------------------------------- /src/pre1.3/tonc_text_map.c: -------------------------------------------------------------------------------- 1 | // 2 | // Map text system file 3 | // 4 | //! \file tonc_text_map.c 5 | //! \author J Vijn 6 | //! \date 20060605 - 20060605 7 | // 8 | // === NOTES === 9 | 10 | #include "tonc_memdef.h" 11 | #include "tonc_core.h" 12 | #include "tonc_text.h" 13 | 14 | 15 | // -------------------------------------------------------------------- 16 | // FUNCTIONS 17 | // -------------------------------------------------------------------- 18 | 19 | 20 | // === TILE BG TEXT =================================================== 21 | 22 | //! Sets up internals for fixed-width tilemap text 23 | /*! \param bgnr Number of background to be used for text. 24 | * \param bgcnt Background control flags. 25 | * \param se0 Base screen entry. This allows a greater range in 26 | * capabilities, like offset tile-starts and palettes. 27 | * \param clrs Colors to use for the text. The palette entries 28 | * used depends on \a se0 and \a bupofs. 29 | * \param bupofs Flags for font bit-unpacking. Basically indicates 30 | * pixel values (and hence palette use). 31 | */ 32 | void txt_init_se(int bgnr, u16 bgcnt, SCR_ENTRY se0, u32 clrs, u32 bupofs) 33 | { 34 | REG_BGCNT[bgnr]= bgcnt; 35 | gptxt->dst0= se_mem[BFN_GET(bgcnt, BG_SBB)]; 36 | 37 | //ASM_CMT("pal"); 38 | // prep palette 39 | int bpp= (bgcnt&BG_8BPP) ? 8 : 4; 40 | if(bpp==4) 41 | { 42 | // Add shading to my 4bit fonts in an uber-1337 way 43 | // Are you expected to understand this? 44 | // Nah, didn't think so either :P 45 | COLOR *palbank= pal_bg_bank[BFN_GET(se0, SE_PALBANK)]; 46 | palbank[(bupofs+1)&15]= clrs&0xFFFF; 47 | palbank[(bupofs>>4)&15]= clrs>>16; 48 | } 49 | else 50 | pal_bg_mem[(bupofs+1)&255]= clrs&0xFFFF; 51 | 52 | // account for tile-size difference 53 | se0 &= SE_ID_MASK; 54 | if(bpp==8) 55 | se0 *= 2; 56 | //ASM_CMT("bup"); 57 | // bup the tiles 58 | //BUP bup= { toncfontTilesLen, 1, bpp, base }; 59 | //BitUnPack(toncfontTiles, &tile_mem[BFN_GET(bgcnt, BG_CBB)][tileofs], &bup); 60 | txt_bup_1toX(&tile_mem[BFN_GET(bgcnt, BG_CBB)][se0], 61 | toncfontTiles, toncfontTilesLen, bpp, bupofs); 62 | 63 | } 64 | 65 | //! Print character \a c on a tilemap at pixel (x, y) with base SE \a se0 66 | /*! \param x x-coordinate in pixels (rounded down to 8s). 67 | * \param y y-coordinate in pixels (rounded down to 8s). 68 | * \param c Character to print. 69 | * \param se0 Base screen entry, for offset font-tile starts and palettes. 70 | */ 71 | void se_putc(int x, int y, int c, SCR_ENTRY se0) 72 | { 73 | if(c == '\n') 74 | return; 75 | 76 | SCR_ENTRY *dst= &gptxt->dst0[(y>>3)*32+(x>>3)]; 77 | *dst= gptxt->chars[c] + se0; 78 | } 79 | 80 | //! Print string \a str on a tilemap at pixel (x, y) with base SE \a se0 81 | /*! \param x x-coordinate in pixels (rounded down to 8s). 82 | * \param y y-coordinate in pixels (rounded down to 8s). 83 | * \param str String to print. 84 | * \param se0 Base screen entry, for offset font-tile starts and palettes. 85 | */ 86 | void se_puts(int x, int y, const char *str, SCR_ENTRY se0) 87 | { 88 | int c; 89 | SCR_ENTRY *dst= &gptxt->dst0[(y>>3)*32+(x>>3)]; 90 | 91 | x=0; 92 | while((c=*str++) != 0) 93 | { 94 | if(c == '\n') // line break 95 | { dst += (x&~31) + 32; x= 0; } 96 | else 97 | dst[x++] = (gptxt->chars[c]) + se0; 98 | } 99 | } 100 | 101 | //! Clear string \a str from a tilemap at pixel (x, y) with SE \a se0 102 | /*! \param x x-coordinate in pixels (rounded down to 8s). 103 | * \param y y-coordinate in pixels (rounded down to 8s). 104 | * \param str String indicating which area is used. 105 | * \param se0 Screen entry to clear with 106 | */ 107 | void se_clrs(int x, int y, const char *str, SCR_ENTRY se0) 108 | { 109 | int c; 110 | SCR_ENTRY *dst= &gptxt->dst0[(y>>3)*32+(x>>3)]; 111 | 112 | x=0; 113 | while((c=*str++) != 0) 114 | { 115 | if(c == '\n') // line break 116 | { dst += (x&~31) + 32; x= 0; } 117 | else 118 | dst[x++] = se0; 119 | } 120 | } 121 | 122 | // EOF 123 | -------------------------------------------------------------------------------- /src/pre1.3/tonc_text_oam.c: -------------------------------------------------------------------------------- 1 | // 2 | // Object text system file 3 | // 4 | //! \file tonc_text_oam.c 5 | //! \author J Vijn 6 | //! \date 20060605 - 20060605 7 | // 8 | // === NOTES === 9 | 10 | #include "tonc_core.h" 11 | #include "tonc_oam.h" 12 | #include "tonc_text.h" 13 | 14 | 15 | // -------------------------------------------------------------------- 16 | // FUNCTIONS 17 | // -------------------------------------------------------------------- 18 | 19 | 20 | 21 | //! Sets up internals for fixed-width object text 22 | /*! \param obj0 Pointer to an object buffer to use for the characters. 23 | * \param attr2 Base attr2. This allows a greater range in 24 | * capabilities, like offset tile-starts and palettes. 25 | * \param clrs Colors to use for the text. The palette entries 26 | * used depends on \a se0 and \a bupofs. 27 | * \param bupofs Flags for font bit-unpacking. Basically indicates 28 | * pixel values (and hence palette use). 29 | */ 30 | void txt_init_obj(OBJ_ATTR *obj0, u16 attr2, u32 clrs, u32 bupofs) 31 | { 32 | gptxt->dst0= (u16*)obj0; 33 | 34 | // What the hell am I doing? Shading my 1bpp font :p 35 | // (A 0xnm offset for a 1-4 bup gives m+1 for the real nybbles 36 | // and n for the empty nybble on its right) 37 | COLOR *pbank= pal_obj_bank[BFN_GET(attr2, ATTR2_PALBANK)]; 38 | pbank[(bupofs+1)&15]= clrs&0xFFFF; 39 | pbank[(bupofs>>4)&15]= clrs>>16; 40 | 41 | //ASM_CMT("bup"); 42 | // bup the tiles 43 | //BUP bup= { toncfontTilesLen, 1, 4, bupofs}; 44 | //BitUnPack(toncfontTiles, &tile_mem[4][tileofs], &bup); 45 | txt_bup_1toX(&tile_mem[4][attr2&ATTR2_ID_MASK], toncfontTiles, 46 | toncfontTilesLen, 4, bupofs); 47 | } 48 | 49 | //! Print character \a c with objects (x, y) with base \a attr2 50 | /*! \param x x-coordinate in pixels 51 | * \param y y-coordinate in pixels. 52 | * \param c Character to print. 53 | * \param attr2 Base attr2, for offset font-tile starts and palettes. 54 | */ 55 | void obj_putc(int x, int y, int c, u16 attr2) 56 | { 57 | if(c == '\n') 58 | return; 59 | 60 | OBJ_ATTR *obj= (OBJ_ATTR*)gptxt->dst0; 61 | 62 | obj->attr0= y & ATTR0_Y_MASK; 63 | obj->attr1= x & ATTR1_X_MASK; 64 | obj->attr2= gptxt->chars[c] + attr2; 65 | } 66 | 67 | //! Print string \a str with objects at pixel (x, y) with base \a attr2 68 | /*! \param x x-coordinate in pixels 69 | * \param y y-coordinate in pixels. 70 | * \param str String to print. 71 | * \param attr2 Base attr2, for offset font-tile starts and palettes. 72 | */ 73 | void obj_puts(int x, int y, const char *str, u16 attr2) 74 | { 75 | int c, x0= x; 76 | OBJ_ATTR *obj= (OBJ_ATTR*)gptxt->dst0; 77 | 78 | while((c=*str++) != 0) 79 | { 80 | if(c == '\n') // line break 81 | { y += gptxt->dy; x= x0; } 82 | else 83 | { 84 | if(c != ' ') 85 | { 86 | obj->attr0= y & ATTR0_Y_MASK; 87 | obj->attr1= x & ATTR1_X_MASK; 88 | obj->attr2= gptxt->chars[c] + attr2; 89 | obj++; 90 | } 91 | x += gptxt->dx; 92 | } 93 | } 94 | } 95 | 96 | //! Clear an object-string \a str 97 | /*! \param x x-coordinate in pixels. 98 | * \param y y-coordinate in pixels. 99 | * \param str String indicating which area is used. 100 | */ 101 | void obj_clrs(int x, int y, const char *str) 102 | { 103 | int c; 104 | OBJ_ATTR *obj= (OBJ_ATTR*)gptxt->dst0; 105 | 106 | while((c=*str++) != 0) 107 | { 108 | if(c != '\n' && c != ' ') 109 | obj_hide(obj++); 110 | } 111 | } 112 | 113 | // EOF 114 | -------------------------------------------------------------------------------- /src/pre1.3/toncfont.s: -------------------------------------------------------------------------------- 1 | @======================================================================= 2 | @ 3 | @ toncfont, 128x48@1, 4 | @ + 96 tiles not compressed 5 | @ Total size: 768 = 768 6 | @ 7 | @ Time-stamp: 2006-05-09, 00:37:31 8 | @ Exported by Cearn's Usenti v1.7.4 9 | @ (comments, kudos, flames to "daytshen@hotmail.com") 10 | @ 11 | @======================================================================= 12 | 13 | .section .rodata 14 | .align 2 15 | .global toncfontTiles @ 768 bytes 16 | toncfontTiles: 17 | .word 0x00000000,0x00000000,0x18181818,0x00180018,0x00003636,0x00000000,0x367F3636,0x0036367F 18 | .word 0x3C067C18,0x00183E60,0x1B356600,0x0033566C,0x6E16361C,0x00DE733B,0x000C1818,0x00000000 19 | .word 0x0C0C1830,0x0030180C,0x3030180C,0x000C1830,0xFF3C6600,0x0000663C,0x7E181800,0x00001818 20 | .word 0x00000000,0x0C181800,0x7E000000,0x00000000,0x00000000,0x00181800,0x183060C0,0x0003060C 21 | .word 0x7E76663C,0x003C666E,0x181E1C18,0x00181818,0x3060663C,0x007E0C18,0x3860663C,0x003C6660 22 | .word 0x33363C38,0x0030307F,0x603E067E,0x003C6660,0x3E060C38,0x003C6666,0x3060607E,0x00181818 23 | .word 0x3C66663C,0x003C6666,0x7C66663C,0x001C3060,0x00181800,0x00181800,0x00181800,0x0C181800 24 | .word 0x06186000,0x00006018,0x007E0000,0x0000007E,0x60180600,0x00000618,0x3060663C,0x00180018 25 | 26 | .word 0x5A5A663C,0x003C067A,0x7E66663C,0x00666666,0x3E66663E,0x003E6666,0x06060C78,0x00780C06 27 | .word 0x6666361E,0x001E3666,0x1E06067E,0x007E0606,0x1E06067E,0x00060606,0x7606663C,0x007C6666 28 | .word 0x7E666666,0x00666666,0x1818183C,0x003C1818,0x60606060,0x003C6660,0x0F1B3363,0x0063331B 29 | .word 0x06060606,0x007E0606,0x6B7F7763,0x00636363,0x7B6F6763,0x00636373,0x6666663C,0x003C6666 30 | .word 0x3E66663E,0x00060606,0x3333331E,0x007E3B33,0x3E66663E,0x00666636,0x3C0E663C,0x003C6670 31 | .word 0x1818187E,0x00181818,0x66666666,0x003C6666,0x66666666,0x00183C3C,0x6B636363,0x0063777F 32 | .word 0x183C66C3,0x00C3663C,0x183C66C3,0x00181818,0x0C18307F,0x007F0306,0x0C0C0C3C,0x003C0C0C 33 | .word 0x180C0603,0x00C06030,0x3030303C,0x003C3030,0x00663C18,0x00000000,0x00000000,0x003F0000 34 | 35 | .word 0x00301818,0x00000000,0x603C0000,0x007C667C,0x663E0606,0x003E6666,0x063C0000,0x003C0606 36 | .word 0x667C6060,0x007C6666,0x663C0000,0x003C067E,0x0C3E0C38,0x000C0C0C,0x667C0000,0x3C607C66 37 | .word 0x663E0606,0x00666666,0x18180018,0x00301818,0x30300030,0x1E303030,0x36660606,0x0066361E 38 | .word 0x18181818,0x00301818,0x7F370000,0x0063636B,0x663E0000,0x00666666,0x663C0000,0x003C6666 39 | .word 0x663E0000,0x06063E66,0x667C0000,0x60607C66,0x663E0000,0x00060606,0x063C0000,0x003E603C 40 | .word 0x0C3E0C0C,0x00380C0C,0x66660000,0x007C6666,0x66660000,0x00183C66,0x63630000,0x00367F6B 41 | .word 0x36630000,0x0063361C,0x66660000,0x0C183C66,0x307E0000,0x007E0C18,0x0C181830,0x00301818 42 | .word 0x18181818,0x00181818,0x3018180C,0x000C1818,0x003B6E00,0x00000000,0x00000000,0x00000000 43 | 44 | -------------------------------------------------------------------------------- /src/tonc_bg.c: -------------------------------------------------------------------------------- 1 | // 2 | // Tiled background stuff 3 | // 4 | //! \file tonc_bg.c 5 | //! \author J Vijn 6 | //! \date 20061112 - 20061117 7 | // 8 | // === NOTES === 9 | // * Empty, isn't it :P 10 | 11 | 12 | #include "tonc_memmap.h" 13 | #include "tonc_video.h" 14 | 15 | 16 | // -------------------------------------------------------------------- 17 | // FUNCTIONS 18 | // -------------------------------------------------------------------- 19 | 20 | 21 | //! Create a framed rectangle. 22 | /*! In contrast to se_frame(), se_frame_ex() uses nine tiles starting at 23 | \a se0 for the frame, which indicate the borders and center for the 24 | window. 25 | \note Rectangle is nor normalized. 26 | */ 27 | void se_window(SCR_ENTRY *sbb, int left, int top, int right, int bottom, 28 | SCR_ENTRY se0) 29 | { 30 | int ix, iy; 31 | right -= (left+1); 32 | bottom -= (top+1); 33 | 34 | sbb += top*32+left; 35 | 36 | sbb[ 0]= se0; 37 | sbb[ right]= se0+2; 38 | sbb[bottom*32 ]= se0+6; 39 | sbb[bottom*32+right]= se0+8; 40 | 41 | // horizontal 42 | for(ix=1; ix>4, cc= lu_cos(alpha)>>4; 31 | 32 | bgaff->pa= cc; bgaff->pb=-ss; 33 | bgaff->pc= ss; bgaff->pd= cc; 34 | } 35 | 36 | //! Set bg matrix to 2d scaling, then counter-clockwise rotation. 37 | /*! 38 | \param bgaff Object affine struct to set. 39 | \param sx Horizontal scale (zoom). .8 fixed point. 40 | \param sy Vertical scale (zoom). .8 fixed point. 41 | \param alpha CCW angle. full-circle is 10000h. 42 | */ 43 | void bg_aff_rotscale(BG_AFFINE *bgaff, int sx, int sy, u16 alpha) 44 | { 45 | int ss= lu_sin(alpha), cc= lu_cos(alpha); 46 | 47 | bgaff->pa= cc*sx>>12; bgaff->pb=-ss*sx>>12; 48 | bgaff->pc= ss*sy>>12; bgaff->pd= cc*sy>>12; 49 | } 50 | 51 | //! Pre-multiply \a dst by \a src: D = S*D 52 | void bg_aff_premul(BG_AFFINE *dst, const BG_AFFINE *src) 53 | { 54 | FIXED tmp_a, tmp_b, tmp_c, tmp_d; 55 | tmp_a= dst->pa; tmp_b= dst->pb; 56 | tmp_c= dst->pc; tmp_d= dst->pd; 57 | 58 | dst->pa= (src->pa*tmp_a + src->pb*tmp_c)>>8; 59 | dst->pb= (src->pa*tmp_b + src->pb*tmp_d)>>8; 60 | dst->pc= (src->pc*tmp_a + src->pd*tmp_c)>>8; 61 | dst->pd= (src->pc*tmp_b + src->pd*tmp_d)>>8; 62 | } 63 | 64 | //! Post-multiply \a dst by \a src: D= D*S 65 | void bg_aff_postmul(BG_AFFINE *dst, const BG_AFFINE *src) 66 | { 67 | FIXED tmp_a, tmp_b, tmp_c, tmp_d; 68 | tmp_a= dst->pa; tmp_b= dst->pb; 69 | tmp_c= dst->pc; tmp_d= dst->pd; 70 | 71 | dst->pa= (tmp_a*src->pa + tmp_b*src->pc)>>8; 72 | dst->pb= (tmp_a*src->pb + tmp_b*src->pd)>>8; 73 | dst->pc= (tmp_c*src->pa + tmp_d*src->pc)>>8; 74 | dst->pd= (tmp_c*src->pb + tmp_d*src->pd)>>8; 75 | } 76 | 77 | //! Set bg matrix to 2d scaling, then counter-clockwise rotation. 78 | /*! 79 | \param bgaff Object affine struct to set. 80 | \param as Struct with scales and angle. 81 | */ 82 | void bg_aff_rotscale2(BG_AFFINE *bgaff, const AFF_SRC *as) 83 | { 84 | int ss= lu_sin(as->alpha), cc= lu_cos(as->alpha); 85 | 86 | bgaff->pa= cc*as->sx>>12; bgaff->pb=-ss*as->sx>>12; 87 | bgaff->pc= ss*as->sy>>12; bgaff->pd= cc*as->sy>>12; 88 | } 89 | 90 | //! Set bg affine matrix to a rot/scale around an arbitrary point. 91 | /*! Rotate and scale round an arbitrary point using the \a asx data. 92 | \param bgaff BG affine data to set. 93 | \param asx Affine source data: screen and texture origins, 94 | scales and angle. 95 | */ 96 | void bg_rotscale_ex(BG_AFFINE *bgaff, const AFF_SRC_EX *asx) 97 | { 98 | int sx= asx->sx, sy= asx->sy; 99 | int sina= lu_sin(asx->alpha), cosa= lu_cos(asx->alpha); 100 | 101 | FIXED pa, pb, pc, pd; 102 | pa= sx*cosa>>12; pb=-sx*sina>>12; // .8f 103 | pc= sy*sina>>12; pd= sy*cosa>>12; // .8f 104 | 105 | bgaff->pa= pa; bgaff->pb= pb; 106 | bgaff->pc= pc; bgaff->pd= pd; 107 | 108 | bgaff->dx= asx->tex_x - (pa*asx->scr_x + pb*asx->scr_y); 109 | bgaff->dy= asx->tex_y - (pc*asx->scr_x + pd*asx->scr_y); 110 | } 111 | 112 | // EOF 113 | -------------------------------------------------------------------------------- /src/tonc_bmp16.c: -------------------------------------------------------------------------------- 1 | // 2 | // 16bpp bitmap functionality 3 | // 4 | //! \file tonc_bmp16.c 5 | //! \author J Vijn 6 | //! \date 20060604 - 20070703 7 | // 8 | /* === NOTES === 9 | * 20070704. Tested except for bmp16_line 10 | */ 11 | 12 | #include "tonc_memmap.h" 13 | #include "tonc_core.h" 14 | #include "tonc_video.h" 15 | 16 | 17 | // -------------------------------------------------------------------- 18 | // FUNCTIONS 19 | // -------------------------------------------------------------------- 20 | 21 | //! Plot a single pixel on a 16-bit buffer 22 | /*! 23 | \param x X-coord. 24 | \param y Y-coord. 25 | \param clr Color. 26 | \param dstBase Canvas pointer (halfword-aligned plz). 27 | \param dstP Canvas pitch in bytes. 28 | \note Slow as fuck. Inline plotting functionality if possible. 29 | */ 30 | void bmp16_plot(int x, int y, u32 clr, void *dstBase, uint dstP) 31 | { 32 | u16 *dstL= (u16*)(dstBase+y*dstP + x*2); 33 | 34 | dstL[0]= clr; 35 | } 36 | 37 | 38 | //! Draw a horizontal line on an 16bit buffer 39 | /*! 40 | \param x1 First X-coord. 41 | \param y Y-coord. 42 | \param x2 Second X-coord. 43 | \param clr Color. 44 | \param dstBase Canvas pointer (halfword-aligned plz). 45 | \param dstP Canvas pitch in bytes. 46 | \note Does normalization, but not bounds checks. 47 | */ 48 | void bmp16_hline(int x1, int y, int x2, u32 clr, void *dstBase, uint dstP) 49 | { 50 | // --- Normalize --- 51 | if(x2x2) 107 | { xstep= -1; dx= x1-x2; } 108 | else 109 | { xstep= +1; dx= x2-x1; } 110 | 111 | if(y1>y2) 112 | { ystep= -dstP; dy= y1-y2; } 113 | else 114 | { ystep= +dstP; dy= y2-y1; } 115 | 116 | 117 | // --- Drawing --- 118 | 119 | if(dy == 0) // Horizontal 120 | { 121 | for(ii=0; ii<=dx; ii++) 122 | dstL[ii*xstep]= clr; 123 | } 124 | else if(dx == 0) // Vertical 125 | { 126 | for(ii=0; ii<=dy; ii++) 127 | dstL[ii*ystep]= clr; 128 | } 129 | else if(dx>=dy) // Diagonal, slope <= 1 130 | { 131 | dd= 2*dy - dx; 132 | 133 | for(ii=0; ii<=dx; ii++) 134 | { 135 | *dstL= clr; 136 | if(dd >= 0) 137 | { dd -= 2*dx; dstL += ystep; } 138 | 139 | dd += 2*dy; 140 | dstL += xstep; 141 | } 142 | } 143 | else // Diagonal, slope > 1 144 | { 145 | dd= 2*dx - dy; 146 | 147 | for(ii=0; ii<=dy; ii++) 148 | { 149 | *dstL= clr; 150 | if(dd >= 0) 151 | { dd -= 2*dy; dstL += xstep; } 152 | 153 | dd += 2*dx; 154 | dstL += ystep; 155 | } 156 | } 157 | } 158 | 159 | 160 | //! Draw a rectangle in 16bit mode; internal routine. 161 | /*! 162 | \param left Left side of rectangle; 163 | \param top Top side of rectangle. 164 | \param right Right side of rectangle. 165 | \param bottom Bottom side of rectangle. 166 | \param clr Color. 167 | \param dstBase Canvas pointer. 168 | \param dstP Canvas pitch in bytes 169 | \note Does normalization, but not bounds checks. 170 | */ 171 | void bmp16_rect(int left, int top, int right, int bottom, u32 clr, 172 | void *dstBase, uint dstP) 173 | { 174 | int tmp; 175 | 176 | // --- Normalization --- 177 | if(rightx2) 163 | { xstep= -1; dx= x1-x2; } 164 | else 165 | { xstep= +1; dx= x2-x1; } 166 | 167 | if(y1>y2) 168 | { ystep= -dstP; dy= y1-y2; } 169 | else 170 | { ystep= +dstP; dy= y2-y1; } 171 | 172 | 173 | // --- Drawing --- 174 | // NOTE: because xstep is alternating, you can do marvels 175 | // with mask-flips 176 | // NOTE: (mask>>31) is equivalent to (x&1) ? 0 : 1 177 | 178 | if(dx>=dy) // Diagonal, slope <= 1 179 | { 180 | dd= 2*dy - dx; 181 | 182 | for(ii=dx; ii>=0; ii--) 183 | { 184 | dstL= (u16*)(addr - (mask>>31)); 185 | *dstL= (*dstL &~ mask) | (clr & mask); 186 | 187 | if(dd >= 0) 188 | { dd -= 2*dx; addr += ystep; } 189 | 190 | dd += 2*dy; 191 | addr += xstep; 192 | mask = ~mask; 193 | } 194 | } 195 | else // # Diagonal, slope > 1 196 | { 197 | dd= 2*dx - dy; 198 | 199 | for(ii=dy; ii>=0; ii--) 200 | { 201 | dstL= (u16*)(addr - (mask>>31)); 202 | *dstL= (*dstL &~ mask) | (clr & mask); 203 | 204 | if(dd >= 0) 205 | { 206 | dd -= 2*dy; 207 | addr += xstep; 208 | mask = ~mask; 209 | } 210 | 211 | dd += 2*dx; 212 | addr += ystep; 213 | } 214 | } 215 | } 216 | 217 | 218 | //! Draw a rectangle in 8bit mode; internal routine. 219 | /*! 220 | \param left Left side of rectangle; 221 | \param top Top side of rectangle. 222 | \param right Right side of rectangle. 223 | \param bottom Bottom side of rectangle. 224 | \param clr Color-index. 225 | \param dstBase Canvas pointer. 226 | \param dstP Canvas pitch in bytes 227 | \note Does normalization, but not bounds checks. 228 | */ 229 | void bmp8_rect(int left, int top, int right, int bottom, u32 clr, 230 | void *dstBase, uint dstP) 231 | { 232 | int tmp, iy; 233 | 234 | // --- Normalization --- 235 | clr &= 0xFF; 236 | if(rightkeys= 0; // Clear repeats again 53 | 54 | if(rpt->delay) 55 | { 56 | // Change in masked keys: reset repeat 57 | // NOTE: this also counts as a repeat! 58 | if(key_transit(rpt->mask)) 59 | { 60 | rpt->count= rpt->delay; 61 | rpt->keys= __key_curr; 62 | } 63 | else 64 | rpt->count--; 65 | 66 | // Time's up: set repeats (for this frame) 67 | if(rpt->count == 0) 68 | { 69 | rpt->count= rpt->repeat; 70 | rpt->keys= __key_curr & rpt->mask; 71 | } 72 | } 73 | } 74 | 75 | //! Wait until \a key is hit. 76 | void key_wait_till_hit(u16 key) 77 | { 78 | while(1) 79 | { 80 | VBlankIntrWait(); 81 | key_poll(); 82 | if(key_hit(key)) 83 | return; 84 | } 85 | } 86 | 87 | // === Repeated keys functions === 88 | 89 | //! Get status of repeated keys. 90 | u32 key_repeat(u32 keys) 91 | { 92 | return __key_rpt.keys & keys; 93 | } 94 | 95 | //! Set repeat mask. Only these keys will be considered for repeats. 96 | void key_repeat_mask(u32 mask) 97 | { 98 | __key_rpt.mask= mask & KEY_MASK; 99 | } 100 | 101 | //! Set the delay and repeat limits for repeated keys 102 | /*! 103 | \param delay Set first repeat limit. If 0, repeats are off. 104 | \param repeat Sets later repeat limit. 105 | \note Both limits have a range of [0, 255]. If either argument 106 | is <0, the old value will be kept. 107 | */ 108 | void key_repeat_limits(uint delay, uint repeat) 109 | { 110 | REPEAT_REC *rpt= &__key_rpt; 111 | 112 | if(delay >= 0) 113 | rpt->delay= delay; 114 | if(repeat >= 0) 115 | rpt->repeat= repeat; 116 | 117 | rpt->count= delay; // Reset counter. 118 | } 119 | -------------------------------------------------------------------------------- /src/tonc_irq.c: -------------------------------------------------------------------------------- 1 | // 2 | // Interrupt source code 3 | // 4 | //! \file tonc_irq.c 5 | //! \author J Vijn 6 | //! \date 20060908 - 20060928 7 | // 8 | // === NOTES === 9 | // * General note: every irq function should start with 10 | // saving/clearing REG_IME and end with restoring it. If it doesn't 11 | // it's a fair bet that I screwed up :( 12 | 13 | #include "tonc_memmap.h" 14 | #include "tonc_memdef.h" 15 | #include "tonc_core.h" 16 | #include "tonc_irq.h" 17 | 18 | 19 | // -------------------------------------------------------------------- 20 | // CLASSES 21 | // -------------------------------------------------------------------- 22 | 23 | 24 | //! IRQ Sender information 25 | typedef struct IRQ_SENDER 26 | { 27 | u16 reg_ofs; //!< sender reg - REG_BASE 28 | u16 flag; //!< irq-bit in sender reg 29 | } ALIGN4 IRQ_SENDER; 30 | 31 | 32 | // -------------------------------------------------------------------- 33 | // GLOBALS 34 | // -------------------------------------------------------------------- 35 | 36 | 37 | // One extra entry for guaranteed zero 38 | IRQ_REC __isr_table[II_MAX+1]; 39 | 40 | // yeah, yeah, I really should use the registers and defines 41 | // I have else where. 42 | // NOTE: haven't really tested this very much; if inaccurate, 43 | // plz tell me 44 | static const IRQ_SENDER __irq_senders[] = 45 | { 46 | { 0x0004, 0x0008 }, // REG_DISPSTAT, DSTAT_VBL_IRQ 47 | { 0x0004, 0x0010 }, // REG_DISPSTAT, DSTAT_VHB_IRQ 48 | { 0x0004, 0x0020 }, // REG_DISPSTAT, DSTAT_VCT_IRQ 49 | { 0x0102, 0x0040 }, // REG_TM0CNT, TM_IRQ 50 | { 0x0106, 0x0040 }, // REG_TM1CNT, TM_IRQ 51 | { 0x010A, 0x0040 }, // REG_TM2CNT, TM_IRQ 52 | { 0x010E, 0x0040 }, // REG_TM3CNT, TM_IRQ 53 | { 0x0128, 0x4000 }, // REG_SIOCNT SIO_IRQ 54 | { 0x00BA, 0x4000 }, // REG_DMA0CNT_H, DMA_IRQ>>16 55 | { 0x00C6, 0x4000 }, // REG_DMA1CNT_H, DMA_IRQ>>16 56 | { 0x00D2, 0x4000 }, // REG_DMA2CNT_H, DMA_IRQ>>16 57 | { 0x00DE, 0x4000 }, // REG_DMA3CNT_H, DMA_IRQ>>16 58 | { 0x0132, 0x4000 }, // REG_KEYCNT, KCNT_IRQ 59 | { 0x0000, 0x0000 }, // cart: none 60 | }; 61 | 62 | 63 | // -------------------------------------------------------------------- 64 | // FUNCTIONS 65 | // -------------------------------------------------------------------- 66 | 67 | 68 | //! Initialize irq business 69 | /*! Clears ISR table and sets up a master isr. 70 | \param isr Master ISR. If NULL, \a isr_master_nest is used 71 | */ 72 | void irq_init(fnptr isr) 73 | { 74 | REG_IME= 0; 75 | 76 | // clear interrupt table (just in case) 77 | memset32(__isr_table, 0, (II_MAX+1)*sizeof(IRQ_REC)/4); 78 | 79 | REG_ISR_MAIN= (isr) ? isr : (fnptr)isr_master; 80 | 81 | REG_IME= 1; 82 | } 83 | 84 | //! Set a master ISR 85 | /*! \param isr Master ISR. If NULL, \a isr_master_multi is used 86 | * \return Previous master ISR 87 | */ 88 | fnptr irq_set_master(fnptr isr) 89 | { 90 | u16 ime= REG_IME; 91 | REG_IME= 0; 92 | 93 | fnptr old_isr= REG_ISR_MAIN; 94 | REG_ISR_MAIN= (isr) ? isr : (fnptr)isr_master; 95 | 96 | REG_IME= ime; 97 | 98 | return old_isr; 99 | } 100 | 101 | // NOTE could be optimised a little more. 102 | // and it would actually be a lot cleaner in asm :( 103 | 104 | //! General IRQ manager 105 | /*! This routine manages the ISRs of interrupts and their priorities. 106 | \param irq_id Index of irq. 107 | \param isr Interrupt service routine for this irq; can be NULL 108 | \param opts ISR options 109 | \return Previous specific ISR 110 | \note \a irq_id is \e NOT a bit-mask, it is an index! 111 | */ 112 | fnptr irq_set(enum eIrqIndex irq_id, fnptr isr, u32 opts) 113 | { 114 | u16 ime= REG_IME; 115 | REG_IME= 0; 116 | 117 | int ii, slot, prio; 118 | u16 irq_flag= BIT(irq_id); 119 | fnptr old_isr; 120 | IRQ_REC *pir= __isr_table; 121 | 122 | // Enable irq 123 | const IRQ_SENDER *sender= &__irq_senders[irq_id]; 124 | *(u16*)(REG_BASE+sender->reg_ofs) |= sender->flag; 125 | REG_IE |= irq_flag; 126 | 127 | // Search for previous occurance 128 | for(slot=0; pir[slot].flag; slot++) 129 | if(pir[slot].flag == irq_flag) 130 | break; 131 | 132 | prio= opts&(ISR_LAST|ISR_PRIO_MASK); 133 | 134 | // IRS already exists; replace? 135 | if(pir[slot].flag == irq_flag) 136 | { 137 | // Replace desired -> do so 138 | if((prio & ISR_REPLACE) || slot == prio) 139 | { 140 | old_isr= pir[slot].isr; 141 | pir[slot].isr= isr; 142 | REG_IME= ime; 143 | return old_isr; 144 | } 145 | else // No replace: Move rest of isrs up 146 | { 147 | // NOTE: optimisable 148 | while(1) 149 | { 150 | pir[slot]= pir[slot+1]; 151 | if(!pir[slot].flag) 152 | break; 153 | slot++; 154 | } 155 | } 156 | } 157 | 158 | // Priority shuffle; make room 159 | if(prioprio; ii--) 162 | pir[ii]= pir[ii-1]; 163 | slot= ii; 164 | } 165 | 166 | old_isr= pir[slot].isr; 167 | pir[slot].isr= isr; 168 | pir[slot].flag= irq_flag; 169 | 170 | REG_IME= ime; 171 | return old_isr; 172 | } 173 | 174 | 175 | 176 | //! Add a specific ISR 177 | /*! Special case of \c irq_set. If the interrupt has an ISR already 178 | it'll be replaced; if not it will add it in the back. 179 | \param irq_id Index of irq. 180 | \param isr Interrupt service routine for this irq; can be NULL 181 | \return Previous ISR 182 | \note \a irq_id is \e NOT a bit-mask, it is an index! 183 | */ 184 | fnptr irq_add(enum eIrqIndex irq_id, fnptr isr) 185 | { 186 | u16 ime= REG_IME; 187 | REG_IME= 0; 188 | 189 | int ii; 190 | u16 irq_flag= BIT(irq_id); 191 | fnptr old_isr; 192 | IRQ_REC *pir= __isr_table; 193 | 194 | // Enable irq 195 | const IRQ_SENDER *sender= &__irq_senders[irq_id]; 196 | *(u16*)(REG_BASE+sender->reg_ofs) |= sender->flag; 197 | REG_IE |= irq_flag; 198 | 199 | // Search for previous occurance, or empty slot 200 | for(ii=0; pir[ii].flag; ii++) 201 | if(pir[ii].flag == irq_flag) 202 | break; 203 | 204 | old_isr= pir[ii].isr; 205 | pir[ii].isr= isr; 206 | pir[ii].flag= irq_flag; 207 | 208 | REG_IME= ime; 209 | return old_isr; 210 | } 211 | 212 | //! Remove an ISR 213 | /*! it'll be replaced; if not it will add it in the back. 214 | \param irq_id Index of irq. 215 | \return Previous ISR 216 | \note \a irq_id is \e NOT a bit-mask, it is an index! 217 | */ 218 | fnptr irq_delete(enum eIrqIndex irq_id) 219 | { 220 | u16 ime= REG_IME; 221 | REG_IME= 0; 222 | 223 | int ii; 224 | u16 irq_flag= BIT(irq_id); 225 | fnptr old_isr; 226 | IRQ_REC *pir= __isr_table; 227 | 228 | // Disable irq 229 | const IRQ_SENDER *sender= &__irq_senders[irq_id]; 230 | *(u16*)(REG_BASE+sender->reg_ofs) &= ~sender->flag; 231 | REG_IE &= ~irq_flag; 232 | 233 | // Find the ISR 234 | for(ii=0; pir[ii].flag; ii++) 235 | if(pir[ii].flag == irq_flag) 236 | break; 237 | 238 | old_isr= pir[ii].isr; 239 | // Found it; move rest up 240 | for( ; pir[ii].flag; ii++) 241 | pir[ii]= pir[ii+1]; 242 | 243 | REG_IME= ime; 244 | return old_isr; 245 | } 246 | 247 | void irq_enable(enum eIrqIndex irq_id) 248 | { 249 | u16 ime= REG_IME; 250 | REG_IME= 0; 251 | 252 | const IRQ_SENDER *sender= &__irq_senders[irq_id]; 253 | *(u16*)(REG_BASE+sender->reg_ofs) |= sender->flag; 254 | 255 | REG_IE |= BIT(irq_id); 256 | REG_IME= ime; 257 | } 258 | 259 | void irq_disable(enum eIrqIndex irq_id) 260 | { 261 | u16 ime= REG_IME; 262 | REG_IME= 0; 263 | 264 | const IRQ_SENDER *sender= &__irq_senders[irq_id]; 265 | *(u16*)(REG_BASE+sender->reg_ofs) &= ~sender->flag; 266 | 267 | REG_IE &= ~BIT(irq_id); 268 | REG_IME= ime; 269 | } 270 | 271 | // EOF 272 | -------------------------------------------------------------------------------- /src/tonc_math.c: -------------------------------------------------------------------------------- 1 | // 2 | // Basic math functions 3 | // 4 | //! \file tonc_math.c 5 | //! \author J Vijn 6 | //! \date 20060508 - 20060508 7 | // 8 | // === NOTES === 9 | 10 | #include "tonc_memmap.h" 11 | #include "tonc_core.h" 12 | #include "tonc_math.h" 13 | 14 | 15 | // -------------------------------------------------------------------- 16 | // FUNCTIONS 17 | // -------------------------------------------------------------------- 18 | 19 | 20 | // --- Geometry ------------------------------------------------------- 21 | 22 | // --- Point functions --- 23 | 24 | //! Is a point inside a rectangle 25 | int pt_in_rect(const POINT *pt, const RECT *rc) 26 | { 27 | if(pt->x < rc->left || pt->x >= rc->right) 28 | return 0; 29 | if(pt->y < rc->top || pt->y >= rc->bottom) 30 | return 0; 31 | return 1; 32 | } 33 | 34 | // --- Vector functions --- 35 | 36 | VECTOR *vec_cross(VECTOR *vd, const VECTOR *va, const VECTOR *vb) 37 | { 38 | vd->x= fxmul(va->y, vb->z) - fxmul(va->z,vb->y); 39 | vd->y= fxmul(va->y, vb->z) - fxmul(va->z,vb->y); 40 | vd->z= fxmul(va->y, vb->z) - fxmul(va->z,vb->y); 41 | return vd; 42 | } 43 | 44 | // --- Rect functions --- 45 | 46 | RECT *rc_normalize(RECT *rc) 47 | { 48 | int tmp; 49 | if(rc->left > rc->right) 50 | SWAP3(rc->left, rc->right, tmp); 51 | if(rc->top > rc->bottom) 52 | SWAP3(rc->top, rc->bottom, tmp); 53 | return rc; 54 | } 55 | -------------------------------------------------------------------------------- /src/tonc_oam.c: -------------------------------------------------------------------------------- 1 | // 2 | // OAM functions 3 | // 4 | //! \file tonc_oam.c 5 | //! \author J Vijn 6 | //! \date 20060604 - 20060604 7 | // 8 | // === NOTES === 9 | 10 | #include "tonc_memmap.h" 11 | #include "tonc_memdef.h" 12 | #include "tonc_oam.h" 13 | 14 | 15 | // -------------------------------------------------------------------- 16 | // FUNCTIONS 17 | // -------------------------------------------------------------------- 18 | 19 | 20 | // 01 23 45 67 89 ab cd ef 21 | // -- -1 -- -0 -- -0 -- -1 22 | 23 | //! Initialize an array of \a count OBJ_ATTRs with with safe values. 24 | void oam_init(OBJ_ATTR *obj, uint count) 25 | { 26 | u32 nn= (count+3)>>2; 27 | u32 *dst= (u32*)obj; 28 | 29 | // Hide all and set OBJ_AFFINEs to I 30 | while(nn--) 31 | { 32 | *dst++= ATTR0_HIDE; 33 | *dst++= 0x0100<<16; 34 | *dst++= ATTR0_HIDE; 35 | *dst++= 0; 36 | *dst++= ATTR0_HIDE; 37 | *dst++= 0; 38 | *dst++= ATTR0_HIDE; 39 | *dst++= 0x0100<<16; 40 | } 41 | // init oam 42 | oam_copy(oam_mem, obj, count); 43 | } 44 | 45 | //! Copy attributes 0-2 in \a count OBJ_ATTRs. 46 | void obj_copy(OBJ_ATTR *dst, const OBJ_ATTR *src, uint count) 47 | { 48 | int ii; 49 | for(ii=0; iipa= src->pa; 28 | dst->pb= src->pb; 29 | dst->pc= src->pc; 30 | dst->pd= src->pd; 31 | src++; 32 | dst++; 33 | } 34 | } 35 | 36 | 37 | //! Set obj matrix to counter-clockwise rotation. 38 | /*! 39 | \param oaff Object affine struct to set. 40 | \param alpha CCW angle. full-circle is 10000h. 41 | */ 42 | void obj_aff_rotate(OBJ_AFFINE *oaff, u16 alpha) 43 | { 44 | int ss= lu_sin(alpha)>>4, cc= lu_cos(alpha)>>4; 45 | oaff->pa= cc; oaff->pb= -ss; 46 | oaff->pc= ss; oaff->pd= cc; 47 | } 48 | 49 | //! Set obj matrix to 2d scaling, then counter-clockwise rotation. 50 | /*! 51 | \param oaff Object affine struct to set. 52 | \param sx Horizontal scale (zoom). .8 fixed point. 53 | \param sy Vertical scale (zoom). .8 fixed point. 54 | \param alpha CCW angle. full-circle is 10000h. 55 | */ 56 | void obj_aff_rotscale(OBJ_AFFINE *oaff, FIXED sx, FIXED sy, u16 alpha) 57 | { 58 | int ss= lu_sin(alpha), cc= lu_cos(alpha); 59 | 60 | oaff->pa= cc*sx>>12; oaff->pb=-ss*sx>>12; 61 | oaff->pc= ss*sy>>12; oaff->pd= cc*sy>>12; 62 | } 63 | 64 | //! Pre-multiply \a dst by \a src: D = S*D 65 | void obj_aff_premul(OBJ_AFFINE *dst, const OBJ_AFFINE *src) 66 | { 67 | FIXED tmp_a, tmp_b, tmp_c, tmp_d; 68 | tmp_a= dst->pa; tmp_b= dst->pb; 69 | tmp_c= dst->pc; tmp_d= dst->pd; 70 | 71 | dst->pa= (src->pa*tmp_a + src->pb*tmp_c)>>8; 72 | dst->pb= (src->pa*tmp_b + src->pb*tmp_d)>>8; 73 | dst->pc= (src->pc*tmp_a + src->pd*tmp_c)>>8; 74 | dst->pd= (src->pc*tmp_b + src->pd*tmp_d)>>8; 75 | } 76 | 77 | //! Post-multiply \a dst by \a src: D= D*S 78 | void obj_aff_postmul(OBJ_AFFINE *dst, const OBJ_AFFINE *src) 79 | { 80 | FIXED tmp_a, tmp_b, tmp_c, tmp_d; 81 | tmp_a= dst->pa; tmp_b= dst->pb; 82 | tmp_c= dst->pc; tmp_d= dst->pd; 83 | 84 | dst->pa= (tmp_a*src->pa + tmp_b*src->pc)>>8; 85 | dst->pb= (tmp_a*src->pb + tmp_b*src->pd)>>8; 86 | dst->pc= (tmp_c*src->pa + tmp_d*src->pc)>>8; 87 | dst->pd= (tmp_c*src->pb + tmp_d*src->pd)>>8; 88 | } 89 | 90 | //! Set obj matrix to 2d scaling, then counter-clockwise rotation. 91 | /*! 92 | \param oaff Object affine struct to set. 93 | \param as Struct with scales and angle. 94 | */ 95 | void obj_aff_rotscale2(OBJ_AFFINE *oaff, const AFF_SRC *as) 96 | { 97 | int ss= lu_sin(as->alpha), cc= lu_cos(as->alpha); 98 | 99 | oaff->pa= cc*as->sx>>12; oaff->pb=-ss*as->sx>>12; 100 | oaff->pc= ss*as->sy>>12; oaff->pd= cc*as->sy>>12; 101 | } 102 | 103 | //! Rot/scale an object around an arbitrary point. 104 | /*! Sets up \a obj \e and \a oaff for rot/scale transformation 105 | around an arbitrary point using the \a asx data. 106 | \param obj Object to set. 107 | \param oaff Object affine data to set. 108 | \param asx Affine source data: screen and texture origins, 109 | scales and angle. 110 | */ 111 | void obj_rotscale_ex(OBJ_ATTR *obj, OBJ_AFFINE *oaff, const AFF_SRC_EX *asx) 112 | { 113 | int sx= asx->sx, sy= asx->sy; 114 | int sina= lu_sin(asx->alpha)>>4, cosa= lu_cos(asx->alpha)>>4; 115 | 116 | oaff->pa= sx*cosa>>8; oaff->pb= -sx*sina>>8; 117 | oaff->pc= sy*sina>>8; oaff->pd= sy*cosa>>8; 118 | 119 | // sx = 1/sx, sy = 1/sy (.12f) 120 | sx= Div(1<<20, sx); 121 | if(sx != sy) 122 | sy= Div(1<<20, sy); 123 | else 124 | sy= sx; 125 | FIXED aa, ab, ac, ad; 126 | aa= sx*cosa>>12; ab= sy*sina>>12; // .8f 127 | ac= -sx*sina>>12; ad= sy*cosa>>12; // .8f 128 | 129 | sx= oam_sizes[obj->attr0>>14][obj->attr1>>14][0]; 130 | sy= oam_sizes[obj->attr0>>14][obj->attr1>>14][1]; 131 | 132 | int dx= asx->scr_x, dy= asx->scr_y; // .0f 133 | if(obj->attr0&ATTR0_AFF_DBL_BIT) 134 | { dx -= sx; dy -=sy; } 135 | else 136 | { dx -= sx>>1; dy -= sy>>1; } 137 | 138 | sx= asx->tex_x - (sx<<7); // .8f 139 | sy= asx->tex_y - (sy<<7); // .8f 140 | dx -= (aa*sx + ab*sy)>>16; // .0 + (.8f*.8f/.16f) 141 | dy -= (ac*sx + ad*sy)>>16; // .0 + (.8f*.8f/.16f) 142 | 143 | obj_set_pos(obj, dx, dy); 144 | } 145 | 146 | // EOF 147 | -------------------------------------------------------------------------------- /src/tonc_surface.c: -------------------------------------------------------------------------------- 1 | // 2 | // Basic surface functionality.. 3 | // 4 | //! \file tonc_surface.c 5 | //! \author J Vijn 6 | //! \date 20080409 - 20080409 7 | // 8 | /* === NOTES === 9 | */ 10 | 11 | #include 12 | #include "tonc_surface.h" 13 | #include "tonc_video.h" 14 | 15 | // -------------------------------------------------------------------- 16 | // FUNCTIONS 17 | // -------------------------------------------------------------------- 18 | 19 | //! Initalize a surface for \a type formatted graphics. 20 | /*! 21 | \param srf Surface to initialize. 22 | \param type Surface type. See \sa ESurfaceType for details. 23 | \param data Pointer to the surface memory. 24 | \param width Width of surface. 25 | \param height Height of surface. 26 | \param bpp Bitdepth. If \a type is not 0, this value will be ignored. 27 | \param pal Pointer to the surface's palette. 28 | */ 29 | void srf_init(TSurface *srf, enum ESurfaceType type, const void *data, 30 | uint width, uint height, uint bpp, u16 *pal) 31 | { 32 | memset(srf, 0, sizeof(TSurface)); 33 | srf->data= (u8*)data; 34 | srf->type= type; 35 | 36 | switch(type &~ SRF_ALLOCATED) 37 | { 38 | case SRF_CHR4R: 39 | bpp= 4; 40 | srf->pitch= srf_align(width, 4)*8; 41 | break; 42 | 43 | case SRF_CHR4C: 44 | bpp= 4; 45 | srf->pitch= srf_align(height, 4)*8; 46 | break; 47 | 48 | case SRF_CHR8: 49 | bpp= 8; 50 | srf->pitch= srf_align(width, 8)*8; 51 | break; 52 | 53 | case SRF_BMP8: 54 | bpp= 8; 55 | srf->pitch= srf_align(width, bpp); 56 | break; 57 | 58 | case SRF_BMP16: 59 | bpp= 16; 60 | srf->pitch= srf_align(width, bpp); 61 | pal= NULL; 62 | break; 63 | default: 64 | srf->pitch= srf_align(width, bpp); 65 | } 66 | 67 | srf->width= width; 68 | srf->height= height; 69 | srf->bpp= bpp; 70 | 71 | if(pal != NULL) 72 | { 73 | srf->palSize= 1<palData= pal; 75 | } 76 | } 77 | 78 | //! Copy \a count colors from \a src's palette to \a dst's palette. 79 | void srf_pal_copy(const TSurface *dst, const TSurface *src, uint count) 80 | { 81 | if(dst && src && count) 82 | memcpy16(dst->palData, src->palData, count); 83 | } 84 | 85 | //! Get the byte address of coordinates (\a x, \a y) on the surface. 86 | void *srf_get_ptr(const TSurface *srf, uint x, uint y) 87 | { 88 | uint bpp= srf->bpp, pitch= srf->pitch; 89 | switch(srf->type &~ SRF_ALLOCATED) 90 | { 91 | case SRF_CHR4R: 92 | case SRF_CHR8: 93 | return &srf->data[y/8*pitch + y%8*bpp + (x/8*8)*bpp + (x%8)*bpp/8]; 94 | 95 | case SRF_CHR4C: 96 | return &srf->data[y*4 + x/8*pitch + (x%8)/2]; 97 | 98 | default: 99 | return &srf->data[y*pitch + x*bpp/8]; 100 | } 101 | } 102 | 103 | 104 | 105 | // EOF 106 | -------------------------------------------------------------------------------- /src/tonc_video.c: -------------------------------------------------------------------------------- 1 | // 2 | // Basic video functionality 3 | // 4 | //! \file tonc_video.c 5 | //! \author J Vijn 6 | //! \date 20060604 - 20070805 7 | // 8 | // === NOTES === 9 | 10 | #include "tonc_memmap.h" 11 | #include "tonc_core.h" 12 | #include "tonc_video.h" 13 | 14 | 15 | // -------------------------------------------------------------------- 16 | // FUNCTIONS 17 | // -------------------------------------------------------------------- 18 | 19 | 20 | //! Flip the display page. 21 | /*! Toggles the display page in REG_DISPCNT and sets \a vid_page 22 | to point to the back buffer. 23 | \return Current back buffer pointer. 24 | */ 25 | COLOR *vid_flip(void) 26 | { 27 | vid_page= (COLOR*)((u32)vid_page ^ VRAM_PAGE_SIZE); 28 | REG_DISPCNT ^= DCNT_PAGE; // update control register 29 | 30 | return vid_page; 31 | } 32 | 33 | // EOF 34 | -------------------------------------------------------------------------------- /src/tte/ase_drawg.c: -------------------------------------------------------------------------------- 1 | // 2 | // Affine Screen-entry glyph drawers 3 | // 4 | //! \file ase_drawg.c 5 | //! \author J Vijn 6 | //! \date 20070701 - 20080516 7 | // 8 | /* === NOTES === 9 | * Not exactly pretty implementations here, but they work. 10 | */ 11 | 12 | 13 | #include "tonc_types.h" 14 | #include "tonc_surface.h" 15 | 16 | #include "tonc_tte.h" 17 | 18 | //! Erase part of the affine tilemap canvas. 19 | void ase_erase(int left, int top, int right, int bottom) 20 | { 21 | TTC *tc= tte_get_context(); 22 | 23 | //# Check for single sequence 24 | sbmp8_rect(&tc->dst, left>>3, top>>3, right>>3, bottom>>3, 25 | tc->cattr[TTE_PAPER]); 26 | } 27 | 28 | // -------------------------------------------------------------------- 29 | // drawg routines 30 | // -------------------------------------------------------------------- 31 | 32 | 33 | //! Character-plot for affine BGs using an 8x8 font. 34 | void ase_drawg_w8h8(uint gid) 35 | { 36 | TTC *tc= tte_get_context(); 37 | u8 se= tc->cattr[TTE_SPECIAL] + gid; 38 | 39 | _sbmp8_plot(&tc->dst, tc->cursorX/8, tc->cursorY/8, se); 40 | } 41 | 42 | //! Character-plot for affine BGs using an 8x16 font. 43 | void ase_drawg_w8h16(uint gid) 44 | { 45 | TTC *tc= tte_get_context(); 46 | uint x0= tc->cursorX/8, y0= tc->cursorY/8; 47 | u8 se= tc->cattr[TTE_SPECIAL] + gid*2; 48 | 49 | _sbmp8_plot(&tc->dst, x0, y0 , se); 50 | _sbmp8_plot(&tc->dst, x0, y0+1, se+1); 51 | } 52 | 53 | //! Character-plot for affine Bgs, any size. 54 | void ase_drawg(uint gid) 55 | { 56 | TTE_BASE_VARS(tc, font); 57 | uint charW= (font->cellW+7)/8, charH= (font->cellH+7)/8; 58 | uint x0= tc->cursorX/8, y0= tc->cursorY/8; 59 | 60 | u8 se= tc->cattr[TTE_SPECIAL] + gid*charW*charH; 61 | 62 | int ix, iy; 63 | for(iy=0; iydst, ix+x0, iy+y0, se); 66 | } 67 | 68 | //! Character-plot for affine BGs, any sized,vertically oriented font. 69 | void ase_drawg_s(uint gid) 70 | { 71 | TTE_BASE_VARS(tc, font); 72 | uint charW= (font->cellW+7)/8, charH= (font->cellH+7)/8; 73 | uint x0= tc->cursorX/8, y0= tc->cursorY/8; 74 | 75 | u8 se= tc->cattr[TTE_SPECIAL] + gid*charW*charH; 76 | 77 | int ix, iy; 78 | for(ix=0; ixdst, ix+x0, iy+y0, se); 81 | } 82 | 83 | // EOF 84 | -------------------------------------------------------------------------------- /src/tte/bmp16_drawg.c: -------------------------------------------------------------------------------- 1 | // 2 | // Bitmap 16bpp glyph renderers 3 | // 4 | //! \file bmp16_drawg.c 5 | //! \author J Vijn 6 | //! \date 20080311 - 20080311 7 | // 8 | // === NOTES === 9 | 10 | #include "tonc_memdef.h" 11 | 12 | #include "tonc_tte.h" 13 | 14 | // -------------------------------------------------------------------- 15 | // FUNCTIONS 16 | // -------------------------------------------------------------------- 17 | 18 | 19 | //! Linear 16bpp bitmap glyph renderer, opaque. 20 | /* Works on a 16 bpp bitmap 21 | \param gid Character to plot. 22 | \note Font params: bitmapped, 16bpp. 23 | */ 24 | void bmp16_drawg(uint gid) 25 | { 26 | TTE_BASE_VARS(tc, font); 27 | TTE_CHAR_VARS(font, gid, u16, srcD, srcL, charW, charH); 28 | TTE_DST_VARS(tc, u16, dstD, dstL, dstP, x0, y0); 29 | uint srcP= font->cellW; 30 | dstL= &dstD[x0]; 31 | 32 | // The actual rendering 33 | uint ix, iy; 34 | for(iy=0; iycellW; 55 | dstL= &dstD[x0]; 56 | 57 | u32 trans= tc->cattr[TTE_SPECIAL]; 58 | 59 | // The actual rendering 60 | uint ix, iy; 61 | for(iy=0; iy16bpp 6 | // * recolored 7 | // * transparency 8 | // 9 | //! \file bmp16_drawg_b1cs.c 10 | //! \author J Vijn 11 | //! \date 20070605 - 20070704 12 | // 13 | // === NOTES === 14 | 15 | #include "tonc_memdef.h" 16 | 17 | #include "tonc_tte.h" 18 | 19 | // -------------------------------------------------------------------- 20 | // FUNCTIONS 21 | // -------------------------------------------------------------------- 22 | 23 | 24 | //! Linear bitmap, 16bpp transparent character plotter. 25 | /* Works on a 16 bpp bitmap (mode 3 or 5). 26 | \param gid Character to plot. 27 | \note Font req: Any width/height. 1bpp font, 8px stips. 28 | */ 29 | void bmp16_drawg_b1cts(uint gid) 30 | { 31 | TTE_BASE_VARS(tc, font); 32 | TTE_CHAR_VARS(font, gid, u8, srcD, srcL, charW, charH); 33 | TTE_DST_VARS(tc, u16, dstD, dstL, dstP, x0, y0); 34 | uint srcP= font->cellH; 35 | dstD += x0; 36 | 37 | u32 ink= tc->cattr[TTE_INK], raw; 38 | 39 | //# Fixme (src, dst, nx) 40 | uint ix, iy, iw; 41 | for(iw=0; iw0; raw>>=1, ix++) 48 | if(raw&1) 49 | dstL[ix]= ink; 50 | 51 | dstL += dstP/2; 52 | } 53 | srcL += srcP; 54 | } 55 | } 56 | 57 | //! Linear bitmap, 16bpp opaque character plotter. 58 | /* Works on a 16 bpp bitmap (mode 3 or 5). 59 | \param gid Character to plot. 60 | \note Font req: Any width/height. 1bpp font, 8px stips. 61 | */ 62 | void bmp16_drawg_b1cos(uint gid) 63 | { 64 | TTE_BASE_VARS(tc, font); 65 | TTE_CHAR_VARS(font, gid, u8, srcD, srcL, charW, charH); 66 | TTE_DST_VARS(tc, u16, dstD, dstL, dstP, x0, y0); 67 | uint srcP= font->cellH; 68 | 69 | dstD += x0; 70 | 71 | u32 ink= tc->cattr[TTE_INK]; 72 | u32 paper= tc->cattr[TTE_PAPER]; 73 | u32 raw; 74 | 75 | uint ix, iy, iw; 76 | for(iw=0; iw>=1)&1) ? ink : paper; 85 | 86 | dstL += dstP; 87 | } 88 | srcL += srcP; 89 | } 90 | } 91 | 92 | // EOF 93 | -------------------------------------------------------------------------------- /src/tte/bmp8_drawg.c: -------------------------------------------------------------------------------- 1 | // 2 | // Bitmap 8 bpp glyph renderers 3 | // 4 | //! \file bmp8_drawg.c 5 | //! \author J Vijn 6 | //! \date 20080311 - 20080311 7 | // 8 | // === NOTES === 9 | 10 | #include "tonc_memdef.h" 11 | 12 | #include "tonc_tte.h" 13 | 14 | // -------------------------------------------------------------------- 15 | // FUNCTIONS 16 | // -------------------------------------------------------------------- 17 | 18 | 19 | //! Linear 8 bpp bitmap glyph renderer, opaque. 20 | /* Works on a 8 bpp bitmap 21 | \param gid Character to plot. 22 | \note Font params: bitmapped, 8bpp. 23 | \note UNTESTED 24 | */ 25 | void bmp8_drawg(uint gid) 26 | { 27 | TTE_BASE_VARS(tc, font); 28 | TTE_CHAR_VARS(font, gid, u8, srcD, srcL, charW, charH); 29 | uint x0= tc->cursorX, y0= tc->cursorY; 30 | uint srcP= font->cellW; 31 | 32 | // The actual rendering. 33 | uint ix, iy; 34 | for(iy=0; iydst, x0+ix, y0+iy, srcL[ix]); 39 | 40 | srcL += srcP; 41 | } 42 | } 43 | 44 | //! Linear 8 bpp bitmap glyph renderer, transparent. 45 | /* Works on a 8 bpp bitmap 46 | \param gid Character to plot. 47 | \note Font params: bitmapped, 8bpp. special cattr is transparent. 48 | \note UNTESTED 49 | */ 50 | void bmp8_drawg_t(uint gid) 51 | { 52 | TTE_BASE_VARS(tc, font); 53 | TTE_CHAR_VARS(font, gid, u8, srcD, srcL, charW, charH); 54 | uint x0= tc->cursorX, y0= tc->cursorY; 55 | uint srcP= font->cellW; 56 | 57 | u32 trans= tc->cattr[TTE_SPECIAL]; 58 | 59 | // The actual rendering. 60 | uint ix, iy; 61 | for(iy=0; iydst, x0+ix, y0+iy, srcL[ix]); 66 | 67 | srcL += srcP; 68 | } 69 | } 70 | 71 | // EOF 72 | -------------------------------------------------------------------------------- /src/tte/bmp8_drawg_b1cs.c: -------------------------------------------------------------------------------- 1 | // 2 | // Bitmap glyph rendering 3 | // * vwf and fwf 4 | // * any width, height 5 | // * 1->8bpp / strips 6 | // * recolored 7 | // * transparency or opaque 8 | // 9 | //! \file bmp8_drawg_b1cs.c 10 | //! \author J Vijn 11 | //! \date 20070613 - 20070613 12 | // 13 | /* === NOTES === 14 | * 20070725: Using words here seems to have only minor effects. 15 | Could still be worth it in ARM though. 16 | */ 17 | 18 | #include "tonc_memdef.h" 19 | #include "tonc_surface.h" 20 | 21 | #include "tonc_tte.h" 22 | 23 | void bmp8_drawg_b1cts(uint gid); 24 | void bmp8_drawg_b1cos(uint gid); 25 | 26 | 27 | // -------------------------------------------------------------------- 28 | // FUNCTIONS 29 | // -------------------------------------------------------------------- 30 | 31 | void bmp8_drawg_b1cts(uint gid) 32 | { 33 | TTE_BASE_VARS(tc, font); 34 | TTE_CHAR_VARS(font, gid, u8, srcD, srcL, charW, charH); 35 | TTE_DST_VARS(tc, u16, dstD, dstL, dstP, x0, y0); 36 | uint srcP= font->cellH; 37 | uint odd= x0&1; 38 | 39 | dstD += x0/2; 40 | 41 | u32 ink= tc->cattr[TTE_INK], raw, px; 42 | 43 | uint ix, iy, iw; 44 | for(iw=0; iw0; raw>>=2, ix++) // Loop over pixels 51 | { 52 | // 2-bit -> 2-byte unpack, then used as masks. 53 | // Yes, of course I know how it looks 54 | px= ( (raw&3)<<7 | (raw&3) ) &~ 0xFE; 55 | dstL[ix]= (dstL[ix]&~(px*255)) + ink*px; 56 | } 57 | dstL += dstP/2; 58 | } 59 | srcL += srcP; 60 | } 61 | } 62 | 63 | 64 | void bmp8_drawg_b1cos(uint gid) 65 | { 66 | TTE_BASE_VARS(tc, font); 67 | TTE_CHAR_VARS(font, gid, u8, srcD, srcL, charW, charH); 68 | TTE_DST_VARS(tc, u16, dstD, dstL, dstP, x0, y0); 69 | uint srcP= font->cellH; 70 | uint odd= x0&1; 71 | 72 | dstD += x0/2; 73 | 74 | u32 ink= tc->cattr[TTE_INK]; 75 | u32 raw, px, mask; 76 | 77 | // Bugger this; I'm doing it the easy way: pre-clear 78 | sbmp8_rect(&tc->dst, x0, y0, charW, charH, tc->cattr[TTE_PAPER]); 79 | 80 | // and then write as normal. 81 | // NOTE: this is probably not as fast as it should be. 82 | 83 | uint ix, iy, iw; 84 | for(iw=0; iw0; raw>>=2, ix++) // Loop over pixels 91 | { 92 | // 2-fold 1->8 bitunpack 93 | px= ( (raw&3)<<7 | (raw&3) ) &~ 0xFE; 94 | mask= px*255; 95 | dstL[ix]= (dstL[ix]&~mask) + ink*px; 96 | } 97 | 98 | dstL += dstP/2; 99 | } 100 | srcL += srcP; 101 | } 102 | } 103 | 104 | // EOF 105 | -------------------------------------------------------------------------------- /src/tte/bmp8_drawg_b1cts_fast.s: -------------------------------------------------------------------------------- 1 | @ 2 | @ 8bpp bitmap glyph renderer. 1->8bpp recolored, 3 | @ any size, transparent 4 | @ 5 | @! \file bmp8_drawg_b1cts_fast.s 6 | @! \author J Vijn 7 | @! \date 20070814 - 20070822 8 | @ 9 | @ === NOTES === 10 | 11 | #include "tonc_asminc.h" 12 | #include "tte_types.s" 13 | 14 | @ IWRAM_CODE void bmp8_drawg_b1cts_fast(int gid); 15 | BEGIN_FUNC_ARM(bmp8_drawg_b1cts_fast, CSEC_IWRAM) 16 | stmfd sp!, {r4-r11} 17 | 18 | ldr ip,=gp_tte_context 19 | ldr ip, [ip] 20 | 21 | @ Preload dstBase (r4), dstPitch (r5), yx (r6), 22 | @ font (r7) 23 | ldmia ip, {r4, r5} 24 | add r3, ip, #TTC_cursorX 25 | ldmia r3, {r6, r7} 26 | 27 | @# Get srcD (r1), width (r8), charH (r9) 28 | ldmia r7, {r1, r3} @ Load data, widths 29 | cmp r3, #0 30 | ldrneb r8, [r3, r0] @ Var charW 31 | ldreqb r8, [r7, #TF_charW] @ Fixed charW 32 | ldrh r3, [r7, #TF_cellS] 33 | mla r1, r3, r0, r1 @ srcL 34 | ldrb r2, [r7, #TF_charH] @ charH 35 | ldrb r11, [r7, #TF_cellH] @ cellH PONDER: load later? 36 | 37 | @# Positional issues: dstD(r0), cursorX, odd(r6) 38 | mov r3, r6, lsr #16 @ y 39 | bic r6, r6, r3, lsl #16 @ x 40 | mla r0, r5, r3, r4 41 | mov r3, r6, lsr #1 42 | add r0, r0, r3, lsl #1 @ dstD= dstBase+(y*dstP+(x&~1)) 43 | and r6, r6, #1 @ odd 44 | 45 | @ Prep rest 46 | ldrh r7, [ip, #TTC_ink] 47 | 48 | @ --- Reg-list for render loops --- 49 | @ r0 dstL 50 | @ r1 srcL 51 | @ r2 iy_rev 52 | @ r3 raw / tmp 53 | @ r4 px 54 | @ r5 dstP 55 | @ r6 odd 56 | @ r7 ink 57 | @ r8 charW 58 | @ r9 charH 59 | @ r10 dstD 60 | @ r11 deltaS 61 | @ ip ix 62 | 63 | @ Prepare for strip loop 64 | cmp r8, #8 65 | b .Lyloop 66 | sub r11, r11, r2 @ deltaS= cellH - charH 67 | mov r10, r0 @ save dstD 68 | mov r9, r2 @ save charH 69 | b .Lyloop 70 | 71 | @ --- strip loop --- 72 | .Lsloop: 73 | add r0, r10, #16 @ dstL= dstD+16/2 74 | mov r10, r0 75 | add r1, r1, r11 @ srcL += deltaS 76 | 77 | @ --- iy-loop --- 78 | mov r2, r9 79 | .Lyloop: 80 | ldrb r4, [r1], #1 81 | movs r4, r4, lsl r6 82 | beq .Lyend @ No pixels: skip 83 | @ --- ix loop --- 84 | mov ip, #0 85 | .Lxloop: 86 | @ 2bit -> 2bytes and fill halfword 87 | movs r3, r4, lsl #30 @ 'raw&3' and 'raw&2' 88 | beq .Lnopx 89 | ldrh r3, [r0, ip] 90 | andmi r3, r3, #255 91 | orrmi r3, r3, r7, lsl #8 92 | tst r4, #1 93 | bicne r3, r3, #255 94 | orrne r3, r3, r7 95 | strh r3, [r0, ip] 96 | .Lnopx: 97 | add ip, ip, #2 98 | movs r4, r4, lsr #2 99 | bne .Lxloop 100 | .Lyend: 101 | @ Finish y-loop 102 | add r0, r0, r5 103 | subs r2, r2, #1 104 | bne .Lyloop 105 | 106 | @ Finish strip-loop 107 | sub r8, r8, #8 108 | bgt .Lsloop 109 | 110 | @ Final cleanup 111 | ldmfd sp!, {r4-r11} 112 | bx lr 113 | END_FUNC(bmp8_drawg_b1cts_fast) 114 | 115 | @ EOF 116 | -------------------------------------------------------------------------------- /src/tte/chr4c_drawg_b1cts.c: -------------------------------------------------------------------------------- 1 | // 2 | // Tile renderer, var width/height, 1->4bpp tiles, 3 | // recolored with transparency 4 | // 5 | //! \file chr4c_drawg_b1cts.c 6 | //! \author J Vijn 7 | //! \date 20070621 - 20080427 8 | // 9 | /* === NOTES === 10 | * 20070725: Skipping rendering if raw == 0 helps. A lot. Also, there 11 | is more than one way to bitunpack and split between tiles. Which 12 | method is faster is very platform dependent. 13 | * 20070723: Prepping dst stuff inside the drawg and passing along to 14 | renc does NOT help (prolly due to Thumb). Try combining in 15 | asm manually. 16 | */ 17 | 18 | #include "tonc_memdef.h" 19 | #include "tonc_tte.h" 20 | 21 | 22 | // -------------------------------------------------------------------- 23 | // FUNCTIONS 24 | // -------------------------------------------------------------------- 25 | 26 | //! Render 1bpp fonts to 4bpp tiles 27 | void chr4c_drawg_b1cts(uint gid) 28 | { 29 | TTE_BASE_VARS(tc, font); 30 | TTE_CHAR_VARS(font, gid, u8, srcD, srcL, charW, charH); 31 | uint x= tc->cursorX, y= tc->cursorY; 32 | uint srcP= font->cellH, dstP= tc->dst.pitch/4; 33 | 34 | u32 *dstD= (u32*)(tc->dst.data + y*4 + x/8*dstP*4), *dstL; 35 | x %= 8; 36 | u32 lsl= 4*x, lsr= 32-4*x, right= x+charW; 37 | 38 | // Inner loop vars 39 | u32 px, pxmask, raw; 40 | u32 ink= tc->cattr[TTE_INK]; 41 | const u32 mask= 0x01010101; 42 | 43 | uint iy, iw; 44 | for(iw=0; iw 8) 69 | dstL[dstP]= (dstL[dstP] &~ (pxmask>>lsr) ) | (px>>lsr); 70 | } 71 | dstL++; 72 | } 73 | } 74 | } 75 | 76 | // EOF 77 | -------------------------------------------------------------------------------- /src/tte/chr4c_drawg_b1cts_fast.s: -------------------------------------------------------------------------------- 1 | @ 2 | @ Col-major tile character renderer. 1->4bpp recolored, any size, transparent 3 | @ 4 | @! \file chr4c_drawg_b1cts_fast.s 5 | @! \author J Vijn 6 | @! \date 20080427 - 20090801 7 | @ 8 | @ === NOTES === 9 | 10 | #include "tonc_asminc.h" 11 | #include "tte_types.s" 12 | 13 | @ IWRAM_CODE void chr4c_drawg_b1cts_asm(int gid); 14 | BEGIN_FUNC_ARM(chr4c_drawg_b1cts_fast, CSEC_IWRAM) 15 | stmfd sp!, {r4-r11, lr} 16 | 17 | ldr r5,=gp_tte_context 18 | ldr r5, [r5] 19 | 20 | @ Preload dstBase (r4), dstPitch (ip), yx (r6), font (r7) 21 | ldmia r5, {r4, ip} 22 | add r3, r5, #TTC_cursorX 23 | ldmia r3, {r6, r7} 24 | 25 | @ Get srcD (r1), width (r11), charH (r2) 26 | ldmia r7, {r1, r3} @ Load data, widths 27 | cmp r3, #0 28 | ldrneb r11, [r3, r0] @ Var charW 29 | ldreqb r11, [r7, #TF_charW] @ Fixed charW 30 | ldrh r3, [r7, #TF_cellS] 31 | mla r1, r3, r0, r1 @ srcL 32 | ldrb r2, [r7, #TF_charH] @ charH 33 | ldrb r10, [r7, #TF_cellH] @ cellH PONDER: load later? 34 | 35 | @ Positional issues: dstD(r0), lsl(r8), lsr(r9), right(lr), cursorX 36 | mov r3, r6, lsr #16 @ y 37 | bic r6, r6, r3, lsl #16 @ x 38 | 39 | add r0, r4, r3, lsl #2 @ dstD= dstBase + y*4 40 | mov r3, r6, lsr #3 41 | mla r0, ip, r3, r0 42 | 43 | and r6, r6, #7 @ x%7 44 | add lr, r11, r6 @ right= width + x%8 45 | mov r8, r6, lsl #2 @ lsl = x%8*4 46 | rsb r9, r8, #32 @ lsr = 32-x%8*4 47 | 48 | ldr r6,=0x01010101 49 | ldrh r7, [r5, #TTC_ink] 50 | 51 | @ --- Reg-list for strip/render loop --- 52 | @ r0 dstL 53 | @ r1 srcL 54 | @ r2 scanline looper 55 | @ r3 raw 56 | @ r4 px / tmp 57 | @ r5 pxmask 58 | @ r6 bitmask 59 | @ r7 ink 60 | @ r8 left shift 61 | @ r9 right shift 62 | @ r10 dstD @# TODO: unnecessary; remove later 63 | @ r11 charW 64 | @ ip dstP 65 | @ lr split indicator (right edge) 66 | @ sp00 charH 67 | @ sp04 deltaS = cellH-charH (delta srcL) 68 | 69 | cmp r11, #8 70 | @ Prep for single-strip render 71 | suble sp, sp, #8 72 | ble .Lyloop 73 | @ Prep for multi-strip render 74 | sub r3, r10, r2 75 | mov r10, r0 76 | stmfd sp!, {r2, r3} @ Store charH, deltaS 77 | b .Lyloop 78 | 79 | @ --- Strip loop --- 80 | .Lsloop: 81 | ldmia sp, {r2, r3} @ Reload charH and deltaS 82 | add r10, r10, ip @ (Re)set dstD/dstL 83 | mov r0, r10 84 | add r1, r1, r3 85 | sub lr, lr, #8 86 | 87 | @ --- Render loop --- 88 | .Lyloop: 89 | @ Prep px and pxmask 90 | ldrb r3, [r1], #1 91 | orrs r3, r3, r3, lsl #12 92 | beq .Lnopx @ Skip if no pixels 93 | orr r3, r3, r3, lsl #6 94 | and r4, r3, r6, lsl #1 95 | and r3, r3, r6 96 | orr r3, r3, r4, lsl #3 97 | 98 | rsb r5, r3, r3, lsl #4 99 | mul r4, r3, r7 100 | 101 | @ Render to left tile 102 | ldr r3, [r0] 103 | bic r3, r3, r5, lsl r8 104 | orr r3, r3, r4, lsl r8 105 | str r3, [r0] 106 | 107 | @ Render to right tile 108 | cmp lr, #8 109 | ldrgt r3, [r0, ip] 110 | bicgt r3, r3, r5, lsr r9 111 | orrgt r3, r3, r4, lsr r9 112 | strgt r3, [r0, ip] 113 | .Lnopx: 114 | add r0, r0, #4 115 | subs r2, r2, #1 116 | bne .Lyloop 117 | 118 | @ Test for strip loop 119 | subs r11, r11, #8 120 | bgt .Lsloop 121 | 122 | add sp, sp, #8 123 | ldmfd sp!, {r4-r11, lr} 124 | bx lr 125 | END_FUNC(chr4c_drawg_b1cts_fast) 126 | 127 | 128 | @ EOF 129 | -------------------------------------------------------------------------------- /src/tte/chr4c_drawg_b4cts.c: -------------------------------------------------------------------------------- 1 | // 2 | // Tile renderer, var width/height, 4bpp tiles, recolored with transparency 3 | // 4 | //! \file chr4c_drawg_b4cts.c 5 | //! \author J Vijn 6 | //! \date 20080427 - 20080427 7 | // 8 | // === NOTES === 9 | 10 | #include "tonc_memdef.h" 11 | #include "tonc_tte.h" 12 | 13 | 14 | // -------------------------------------------------------------------- 15 | // FUNCTIONS 16 | // -------------------------------------------------------------------- 17 | 18 | void chr4c_drawg_b4cts(uint gid) 19 | { 20 | TTE_BASE_VARS(tc, font); 21 | TTE_CHAR_VARS(font, gid, u32, srcD, srcL, charW, charH); 22 | uint x= tc->cursorX, y= tc->cursorY; 23 | uint srcP= font->cellH, dstP= tc->dst.pitch/4; 24 | 25 | u32 *dstD= (u32*)(tc->dst.data + y*4 + x/8*dstP*4), *dstL; 26 | x %= 8; 27 | u32 lsl= 4*x, lsr= 32-4*x, right= x+charW; 28 | 29 | // Inner loop vars 30 | u32 amask= 0x11111111; 31 | u32 px, pxmask, raw; 32 | u32 ink= tc->cattr[TTE_INK]; 33 | u32 shade= tc->cattr[TTE_SHADOW]; 34 | 35 | uint iy, iw; 36 | for(iw=0; iw>1 & amask); 48 | pxmask= px | raw; 49 | if(pxmask) 50 | { 51 | px *= ink; 52 | px += raw*shade; 53 | pxmask *= 15; 54 | 55 | // Write left tile: 56 | dstL[0] = (dstL[0] &~ (pxmask< 8) 60 | dstL[dstP]= (dstL[dstP] &~ (pxmask>>lsr) ) | (px>>lsr); 61 | } 62 | dstL++; 63 | } 64 | } 65 | } 66 | 67 | // EOF 68 | -------------------------------------------------------------------------------- /src/tte/chr4c_drawg_b4cts_fast.s: -------------------------------------------------------------------------------- 1 | @ 2 | @ Col-major tile character renderer. 4->4bpp recolored, any size, transparent 3 | @ 4 | @! \file chr4c_drawg_b4cts_fast.s 5 | @! \author J Vijn 6 | @! \date 20070725 - 20090801 7 | @ 8 | @ === NOTES === 9 | 10 | #include "tonc_asminc.h" 11 | #include "tte_types.s" 12 | 13 | @ IWRAM_CODE void chr4c_drawg_b4cts_asm(int gid); 14 | BEGIN_FUNC_ARM(chr4c_drawg_b4cts_fast, CSEC_IWRAM) 15 | stmfd sp!, {r4-r11, lr} 16 | 17 | ldr r5,=gp_tte_context 18 | ldr r5, [r5] 19 | 20 | @ Preload dstBase (r4), dstPitch (ip), yx (r6), font (r7) 21 | ldmia r5, {r4, ip} 22 | add r3, r5, #TTC_cursorX 23 | ldmia r3, {r6, r7} 24 | 25 | @ Get srcD (r1), width (r11), charH (r2) 26 | ldmia r7, {r1, r3} @ Load data, widths 27 | cmp r3, #0 28 | ldrneb r11, [r3, r0] @ Var charW 29 | ldreqb r11, [r7, #TF_charW] @ Fixed charW 30 | ldrh r3, [r7, #TF_cellS] 31 | mla r1, r3, r0, r1 @ srcL 32 | ldrb r2, [r7, #TF_charH] @ charH 33 | ldrb r10, [r7, #TF_cellH] @ cellH PONDER: load later? 34 | 35 | @ Positional issues: dstD(r0), lsl(r8), lsr(r9), right(lr), cursorX 36 | mov r3, r6, lsr #16 @ y 37 | bic r6, r6, r3, lsl #16 @ x 38 | 39 | add r0, r4, r3, lsl #2 @ dstD= dstBase + y*4 40 | mov r3, r6, lsr #3 41 | mla r0, ip, r3, r0 42 | 43 | and r6, r6, #7 @ x%7 44 | add lr, r11, r6 @ right= width + x%8 45 | mov r8, r6, lsl #2 @ lsl = x%8*4 46 | rsb r9, r8, #32 @ lsr = 32-x%8*4 47 | 48 | sub r3, r10, r2 @ prep deltaS 49 | ldr r6,=0x11111111 50 | ldrh r7, [r5, #TTC_ink] 51 | ldrh r10, [r5, #TTC_shadow] 52 | 53 | @ --- Reg-list for strip/render loop --- 54 | @ r0 dstL 55 | @ r1 srcL 56 | @ r2 scanline looper 57 | @ r3 raw 58 | @ r4 px / tmp 59 | @ r5 pxmask 60 | @ r6 bitmask 61 | @ r7 ink 62 | @ r8 left shift 63 | @ r9 right shift 64 | @ r10 shadow 65 | @ r11 charW 66 | @ ip dstP 67 | @ lr Right edge 68 | @ sp00 dstD @# TODO: unnecessary; remove later 69 | @ sp04 charH 70 | @ sp08 deltaS = cellH-charH (delta srcL) 71 | 72 | cmp r11, #8 73 | @ Prep for single-strip render 74 | suble sp, sp, #12 75 | ble .Lyloop4 76 | @ Prep for multi-strip render 77 | stmfd sp!, {r0, r2, r3} @ Store dstD, charH, deltaS 78 | b .Lyloop4 79 | 80 | @ --- Strip loop --- 81 | .Lsloop4: 82 | ldmia sp, {r0,r2,r3} @ Reload dstD, charH and deltaS 83 | add r0, r0, ip @ (Re)set dstD/dstL 84 | str r0, [sp] 85 | add r1, r1, r3, lsl #2 86 | sub lr, lr, #8 87 | 88 | @ --- Render loop --- 89 | .Lyloop4: 90 | @# Prep px and pxmask 91 | ldr r3, [r1], #4 92 | and r4, r6, r3 @ Ink mask 93 | and r3, r6, r3, lsr #1 @ Shadow mask 94 | orrs r5, r3, r4 @ Full mask 95 | beq .Lnopx4 96 | mul r4, r7, r4 @ Apply ink (#fix for slowness?) 97 | mla r4, r3, r10, r4 @ Apply shadow 98 | rsb r5, r5, r5, lsl #4 @ Mask *= 0xF 99 | 100 | @ Render to left tile 101 | ldr r3, [r0] 102 | bic r3, r3, r5, lsl r8 103 | orr r3, r3, r4, lsl r8 104 | str r3, [r0] 105 | 106 | @ Render to right tile 107 | cmp lr, #8 108 | ldrgt r3, [r0, ip] 109 | bicgt r3, r3, r5, lsr r9 110 | orrgt r3, r3, r4, lsr r9 111 | strgt r3, [r0, ip] 112 | .Lnopx4: 113 | add r0, r0, #4 114 | 115 | subs r2, r2, #1 116 | bne .Lyloop4 117 | 118 | @ Test for strip loop 119 | subs r11, r11, #8 120 | bgt .Lsloop4 121 | 122 | add sp, sp, #12 123 | ldmfd sp!, {r4-r11, lr} 124 | bx lr 125 | END_FUNC(chr4c_drawg_b4cts_fast) 126 | 127 | @ EOF 128 | -------------------------------------------------------------------------------- /src/tte/chr4r_drawg_b1cts.c: -------------------------------------------------------------------------------- 1 | // 2 | // Tile renderer, var width/height, 1->4bpp tiles, 3 | // recolored with transparency 4 | // 5 | //! \file chr4r_drawg_b1cts.c 6 | //! \author J Vijn 7 | //! \date 20070621 - 20070725 8 | // 9 | /* === NOTES === 10 | * 20070725: Skipping rendering if raw == 0 helps. A lot. Also, there 11 | is more than one way to bitunpack and split between tiles. Which 12 | method is faster is very platform dependent. 13 | * 20070723: Prepping dst stuff inside the drawg and passing along to 14 | renc does NOT help (prolly due to Thumb). Try combining in 15 | asm manually. 16 | */ 17 | 18 | #include "tonc_memdef.h" 19 | #include "tonc_tte.h" 20 | 21 | 22 | // -------------------------------------------------------------------- 23 | // FUNCTIONS 24 | // -------------------------------------------------------------------- 25 | 26 | //! Render 1bpp fonts to 4bpp tiles 27 | void chr4r_drawg_b1cts(uint gid) 28 | { 29 | TTE_BASE_VARS(tc, font); 30 | TTE_CHAR_VARS(font, gid, u8, srcD, srcL, charW, charH); 31 | uint x= tc->cursorX, y= tc->cursorY; 32 | uint srcP= font->cellH, dstP= tc->dst.pitch/4; 33 | 34 | u32 *dstD= (u32*)(tc->dst.data + y/8*dstP + (y%8)*4 + x/8*32), *dstL; 35 | dstP= dstP/4 - 8; 36 | x %= 8; 37 | u32 lsl= 4*x, lsr= 32-4*x, right= x+charW; 38 | 39 | // Inner loop vars 40 | u32 px, pxmask, raw; 41 | u32 ink= tc->cattr[TTE_INK]; 42 | const u32 mask= 0x01010101; 43 | 44 | uint iy, iw; 45 | for(iw=0; iw 8) 70 | dstL[8]= (dstL[8] &~ (pxmask>>lsr) ) | (px>>lsr); 71 | } 72 | dstL++; 73 | 74 | if( ((u32)dstL)%32 == 0 ) 75 | dstL += dstP; 76 | } 77 | } 78 | } 79 | 80 | // EOF 81 | -------------------------------------------------------------------------------- /src/tte/chr4r_drawg_b1cts_fast.s: -------------------------------------------------------------------------------- 1 | @ 2 | @ Tile character renderer. 1->4bpp recolored, any size, transparent 3 | @ 4 | @! \file chr4r_drawg_b1cts_fast.s 5 | @! \author J Vijn 6 | @! \date 20070724 - 20070822 7 | @ 8 | @ === NOTES === 9 | 10 | #include "tte_types.s" 11 | 12 | @ IWRAM_CODE void chr4r_drawg_b1cts_asm(int gid); 13 | .section .iwram, "ax", %progbits 14 | .arm 15 | .align 16 | .global chr4r_drawg_b1cts_fast 17 | chr4r_drawg_b1cts_fast: 18 | stmfd sp!, {r4-r11, lr} 19 | 20 | ldr ip,=gp_tte_context 21 | ldr ip, [ip] 22 | 23 | @ Preload dstBase (r4), dstPitch (r5), yx (r6), 24 | @ font (r7) 25 | ldmia ip, {r4, r5} 26 | add r3, ip, #TTC_cursorX 27 | ldmia r3, {r6, r7} 28 | 29 | @ Get srcD (r1), width (r11), charH (r2) 30 | ldmia r7, {r1, r3} @ Load data, widths 31 | cmp r3, #0 32 | ldrneb r11, [r3, r0] @ Var charW 33 | ldreqb r11, [r7, #TF_charW] @ Fixed charW 34 | ldrh r3, [r7, #TF_cellS] 35 | mla r1, r3, r0, r1 @ srcL 36 | ldrb r2, [r7, #TF_charH] @ charH 37 | ldrb r10, [r7, #TF_cellH] @ cellH PONDER: load later? 38 | 39 | @ Positional issues: dstD(r0), lsl(r8), lsr(r9), right(lr), cursorX 40 | mov r3, r6, lsr #16 @ y 41 | bic r6, r6, r3, lsl #16 @ x 42 | mov r0, r3, lsr #3 43 | mla r4, r5, r0, r4 @ dstD= dstBase+y/8*dstP 44 | and r0, r3, #7 @ PONDER: use ror trick? 45 | add r0, r4, r0, lsl #2 @ dstD += y%8*4. 46 | #if 0 // Not worth it in the long run 47 | mov r3, r6, lsr #3 @ dstL += x/8*8 48 | add r0, r0, r3, lsl #5 49 | ands lr, r6, #7 @ x%8 50 | mov r8, lr, lsl #2 @ lsl = x%8*4 51 | addne lr, lr, r11 @ split= (x%8) ? x%7+width : 0; 52 | rsb r9, r8, #32 @ lsr = 32-x%8*4 53 | #else 54 | mov r6, r6, ror #3 @ x/8 (kinda) 55 | add r0, r0, r6, lsl #5 @ dstL += x/8*8 56 | add lr, r11, r6, lsr #(32-3) @ right= width + x%8 57 | mov r8, r6, lsr #(32-3-2) @ lsl = x%8*4 58 | rsb r9, r8, #32 @ lsr = 32-x%8*4 59 | #endif 60 | ldr r6,=0x01010101 61 | ldrh r7, [ip, #TTC_ink] 62 | 63 | sub ip, r5, #32 @ Fix dstP 64 | 65 | @ --- Reg-list for strip/render loop --- 66 | @ r0 dstL 67 | @ r1 srcL 68 | @ r2 scanline looper 69 | @ r3 raw 70 | @ r4 px / tmp 71 | @ r5 pxmask 72 | @ r6 bitmask 73 | @ r7 ink 74 | @ r8 left shift 75 | @ r9 right shift 76 | @ r10 dstD 77 | @ r11 charW 78 | @ ip dstP 79 | @ lr split indicator (right edge) 80 | @ sp00 charH 81 | @ sp04 deltaS = cellH-charH (delta srcL) 82 | 83 | cmp r11, #8 84 | @ Prep for single-strip render 85 | suble sp, sp, #8 86 | ble .Lyloop 87 | @ Prep for multi-strip render 88 | sub r3, r10, r2 89 | mov r10, r0 90 | stmfd sp!, {r2, r3} @ Store charH, deltaS 91 | b .Lyloop 92 | 93 | @ --- Strip loop --- 94 | .Lsloop: 95 | ldmia sp, {r2, r3} @ Reload charH and deltaS 96 | add r10, r10, #32 @ (Re)set dstD/dstL 97 | mov r0, r10 98 | add r1, r1, r3 99 | sub lr, lr, #8 100 | 101 | @ --- Render loop --- 102 | .Lyloop: 103 | @ Prep px and pxmask 104 | ldrb r3, [r1], #1 105 | orrs r3, r3, r3, lsl #12 106 | beq .Lnopx @ Skip if no pixels 107 | orr r3, r3, r3, lsl #6 108 | and r4, r3, r6, lsl #1 109 | and r3, r3, r6 110 | orr r3, r3, r4, lsl #3 111 | 112 | rsb r5, r3, r3, lsl #4 113 | mul r4, r3, r7 114 | 115 | @ Render to left tile 116 | ldr r3, [r0] 117 | bic r3, r3, r5, lsl r8 118 | orr r3, r3, r4, lsl r8 119 | str r3, [r0] 120 | 121 | @ Render to right tile 122 | cmp lr, #8 123 | ldrgt r3, [r0, #32] 124 | bicgt r3, r3, r5, lsr r9 125 | orrgt r3, r3, r4, lsr r9 126 | strgt r3, [r0, #32] 127 | .Lnopx: 128 | add r0, r0, #4 129 | @ Skip for new tile-row 130 | tst r0, #31 131 | addeq r0, r0, ip 132 | 133 | subs r2, r2, #1 134 | bne .Lyloop 135 | 136 | @ Test for strip loop 137 | subs r11, r11, #8 138 | bgt .Lsloop 139 | 140 | add sp, sp, #8 141 | ldmfd sp!, {r4-r11, lr} 142 | bx lr 143 | .size chr4r_drawg_b1cts_fast, .-chr4r_drawg_b1cts_fast 144 | 145 | @ EOF 146 | -------------------------------------------------------------------------------- /src/tte/obj_drawg.c: -------------------------------------------------------------------------------- 1 | // 2 | // Object plotter 3 | // 4 | //! \file obj_drawg.c 5 | //! \author J Vijn 6 | //! \date 20070715 - 20070822 7 | // 8 | /* === NOTES === 9 | * 20070715: The object system works a little differently than the 10 | others. Objects are used as a descending stack with dstPitch as the 11 | backwards obj index. Also, INK, SHADOW and SPECIAL are base 12 | attributes of the objects. obj_erase unwinds the whole obj-stack. 13 | */ 14 | 15 | #include "tonc_types.h" 16 | #include "tonc_memdef.h" 17 | #include "tonc_core.h" 18 | #include "tonc_oam.h" 19 | 20 | #include "tonc_tte.h" 21 | 22 | 23 | //! Unwind the object text-buffer 24 | void obj_erase(int left, int top, int right, int bottom) 25 | { 26 | TTC *tc= tte_get_context(); 27 | int ii=0, nn= tc->dst.pitch; 28 | OBJ_ATTR *obj= (OBJ_ATTR*)tc->dst.data; 29 | 30 | for(ii=0; iidst.pitch= 0; 34 | } 35 | 36 | 37 | // -------------------------------------------------------------------- 38 | // drawg routines 39 | // -------------------------------------------------------------------- 40 | 41 | 42 | //! Character-plot for objects. 43 | void obj_drawg(uint gid) 44 | { 45 | // PONDER: no obj for ' ' ? 46 | 47 | TTC *tc= tte_get_context(); 48 | TFont *font= tc->font; 49 | uint x0= tc->cursorX, y0= tc->cursorY; 50 | 51 | uint id= tc->dst.pitch; 52 | OBJ_ATTR *obj= &((OBJ_ATTR*)tc->dst.data)[-id]; 53 | 54 | tc->dst.pitch= (id+1 < tc->dst.width ? id+1 : 0); 55 | 56 | obj->attr0= tc->cattr[0] | BFN_PREP(y0, ATTR0_Y); 57 | obj->attr1= tc->cattr[1] | BFN_PREP(x0, ATTR1_X); 58 | obj->attr2= tc->cattr[2] + gid*font->cellW*font->cellH/64; 59 | } 60 | 61 | // EOF 62 | -------------------------------------------------------------------------------- /src/tte/se_drawg.c: -------------------------------------------------------------------------------- 1 | // 2 | // Screen-entry plotter 3 | // 4 | //! \file se_drawg.c 5 | //! \author J Vijn 6 | //! \date 20070628 - 20070628 7 | // 8 | // === NOTES === 9 | 10 | 11 | #include "tonc_types.h" 12 | #include "tonc_tte.h" 13 | #include "tonc_surface.h" 14 | 15 | 16 | typedef u16 pixel_t; 17 | #define PXSIZE sizeof(pixel_t) 18 | #define PXPTR(psrf, x, y) \ 19 | (pixel_t*)((psrf)->data + (y)*(psrf)->pitch + (x)*sizeof(pixel_t) ) 20 | 21 | 22 | //! Erase part of the regular tilemap canvas. 23 | void se_erase(int left, int top, int right, int bottom) 24 | { 25 | TTC *tc= tte_get_context(); 26 | 27 | //# Check for single sequence 28 | sbmp16_rect(&tc->dst, left>>3, top>>3, right>>3, bottom>>3, 29 | tc->cattr[TTE_PAPER]); 30 | } 31 | 32 | 33 | // -------------------------------------------------------------------- 34 | // drawg routines 35 | // -------------------------------------------------------------------- 36 | 37 | 38 | //! Character-plot for reg BGs using an 8x8 font. 39 | void se_drawg_w8h8(uint gid) 40 | { 41 | TTC *tc= tte_get_context(); 42 | 43 | uint x0= tc->cursorX, y0= tc->cursorY; 44 | u16 *dstD= PXPTR(&tc->dst, x0/8, y0/8); 45 | 46 | dstD[0]= tc->cattr[TTE_SPECIAL] + gid; 47 | } 48 | 49 | //! Character-plot for reg BGs using an 8x16 font. 50 | void se_drawg_w8h16(uint gid) 51 | { 52 | TTC *tc= tte_get_context(); 53 | 54 | uint x0= tc->cursorX, y0= tc->cursorY; 55 | uint dstP= tc->dst.pitch/PXSIZE; 56 | u16 *dstD= PXPTR(&tc->dst, x0/8, y0/8); 57 | 58 | u32 se= tc->cattr[TTE_SPECIAL] + gid*2; 59 | 60 | dstD[0]= se; 61 | dstD[dstP]= se+1; 62 | } 63 | 64 | //! Character-plot for reg BGs, any sized font. 65 | void se_drawg(uint gid) 66 | { 67 | int ix, iy; 68 | 69 | TTE_BASE_VARS(tc, font); 70 | u32 charW= (font->cellW+7)/8, charH= (font->cellH+7)/8; 71 | 72 | uint x0= tc->cursorX, y0= tc->cursorY; 73 | uint dstP= tc->dst.pitch/PXSIZE; 74 | u16 *dstD= PXPTR(&tc->dst, x0/8, y0/8); 75 | 76 | u32 se= tc->cattr[TTE_SPECIAL] + gid*charW*charH; 77 | 78 | for(iy=0; iycellW+7)/8, charH= (font->cellH+7)/8; 94 | 95 | uint x0= tc->cursorX, y0= tc->cursorY; 96 | uint dstP= tc->dst.pitch/PXSIZE; 97 | u16 *dstD= PXPTR(&tc->dst, x0/8, y0/8); 98 | 99 | u32 se= tc->cattr[TTE_SPECIAL] + gid*charW*charH; 100 | 101 | for(ix=0; ix 14 | 15 | #include "tonc_memdef.h" 16 | #include "tonc_core.h" 17 | #include "tonc_bios.h" 18 | #include "tonc_surface.h" 19 | 20 | #include "tonc_tte.h" 21 | 22 | 23 | // -------------------------------------------------------------------- 24 | // FUNCTIONS 25 | // -------------------------------------------------------------------- 26 | 27 | //! Initialize text system for affine screen-entry fonts. 28 | /*! 29 | \param bgnr Number of background to be used for text. 30 | \param bgcnt Background control flags. 31 | \param ase0 Base screen entry. This allows a greater range in 32 | capabilities, like offset tile-starts. 33 | \param clrs colors to use for the text. The palette entries 34 | used depends on \a ase0 and \a bupofs. 35 | \param bupofs Flags for font bit-unpacking. Basically indicates 36 | pixel values (and hence palette use). 37 | \param font Font to initialize with. 38 | \param proc Character plotting procedure. 39 | */ 40 | void tte_init_ase(int bgnr, u16 bgcnt, u8 ase0, u32 clrs, u32 bupofs, 41 | const TFont *font, fnDrawg proc) 42 | { 43 | if(font==NULL) font= &fwf_default; 44 | if(proc==NULL) proc= ase_drawg_default; 45 | 46 | tte_init_base(font, proc, ase_erase); 47 | 48 | TTC *tc= tte_get_context(); 49 | uint size= 16<dst, SRF_BMP8, se_mem[BFN_GET(bgcnt, BG_SBB)], 52 | size, size, 8, pal_bg_mem); 53 | 54 | tc->marginRight= size*8; 55 | tc->marginBottom= size*8; 56 | 57 | tc->flags0= bgnr; 58 | tc->ctrl= bgcnt; 59 | REG_BGCNT[bgnr]= bgcnt; 60 | 61 | // --- Prep color-lut and palette --- 62 | u32 ink, shadow=0, paper; 63 | 64 | ink= (bupofs+1)&255; 65 | if( (bupofs&~BUP_ALL_OFS) > 255) 66 | shadow= (bupofs>>8)&255; 67 | 68 | // Set paper entry (PONDER: color too somehow?) 69 | paper= (bupofs&BUP_ALL_OFS) ? bupofs : 0; 70 | 71 | tc->cattr[TTE_INK]= ink; 72 | tc->cattr[TTE_SHADOW]= shadow; 73 | tc->cattr[TTE_PAPER]= paper; 74 | tc->cattr[TTE_SPECIAL]= ase0; 75 | 76 | pal_bg_mem[ink]= clrs&0xFFFF; 77 | pal_bg_mem[shadow]= clrs>>16; 78 | 79 | // --- Bup font --- 80 | void *dstD= &tile_mem[BFN_GET(bgcnt, BG_CBB)][2*ase0]; 81 | u32 dstS= font->charCount*font->cellSize; 82 | 83 | BUP bup= { dstS, font->bpp, 8, bupofs }; 84 | BitUnPack(font->data, dstD, &bup); 85 | } 86 | 87 | // EOF 88 | -------------------------------------------------------------------------------- /src/tte/tte_init_bmp.c: -------------------------------------------------------------------------------- 1 | 2 | // 3 | // Initializer for bitmap text renderers 4 | // 5 | //! \file tte_init_bmp.c 6 | //! \author J Vijn 7 | //! \date 20070517 - 20080229 8 | // 9 | // === NOTES === 10 | 11 | #include 12 | 13 | #include "tonc_memdef.h" 14 | #include "tonc_core.h" 15 | #include "tonc_video.h" 16 | #include "tonc_tte.h" 17 | 18 | #include "tonc_surface.h" 19 | 20 | 21 | // -------------------------------------------------------------------- 22 | // FUNCTIONS 23 | // -------------------------------------------------------------------- 24 | 25 | //! Initialize text system for bitmap fonts. 26 | /*! 27 | \param vmode Video mode (3,4 or 5). 28 | \param font Font to initialize with. 29 | \param proc Glyph renderer. 30 | */ 31 | void tte_init_bmp(int vmode, const TFont *font, fnDrawg proc) 32 | { 33 | if(font==NULL) font= &vwf_default; 34 | tte_init_base(font, proc, NULL); 35 | 36 | TTC *tc= tte_get_context(); 37 | 38 | //# PONDER: page flip ? 39 | switch(vmode) 40 | { 41 | case 4: 42 | tc->dst = m4_surface; 43 | 44 | tc->cattr[TTE_INK]= 0xF1; 45 | tc->cattr[TTE_SHADOW]= 0xF2; 46 | //tc->cattr[TTE_PAPER]= 0; 47 | 48 | tc->marginRight= M4_WIDTH; 49 | tc->marginBottom= M4_HEIGHT; 50 | 51 | if(proc == NULL) 52 | proc= bmp8_drawg_default; 53 | tc->eraseProc= bmp8_erase; 54 | 55 | pal_bg_mem[0xF1]= CLR_YELLOW; 56 | pal_bg_mem[0xF2]= CLR_ORANGE; 57 | pal_bg_mem[0]= CLR_BLACK; 58 | break; 59 | 60 | case 5: 61 | tc->dst = m5_surface; 62 | 63 | tc->cattr[TTE_INK]= CLR_YELLOW; 64 | tc->cattr[TTE_SHADOW]= CLR_ORANGE; 65 | tc->cattr[TTE_PAPER]= CLR_BLACK; 66 | 67 | tc->marginRight= M5_WIDTH; 68 | tc->marginBottom= M5_HEIGHT; 69 | 70 | if(proc == NULL) 71 | proc= bmp16_drawg_default; 72 | tc->eraseProc= bmp16_erase; 73 | break; 74 | 75 | // Default mode is 3. This covers for not having set 76 | // The video mode yet. 77 | // case 3: 78 | default: 79 | tc->dst = m3_surface; 80 | 81 | tc->cattr[TTE_INK]= CLR_YELLOW; 82 | tc->cattr[TTE_SHADOW]= CLR_ORANGE; 83 | tc->cattr[TTE_PAPER]= CLR_BLACK; 84 | 85 | tc->marginRight= M3_WIDTH; 86 | tc->marginBottom= M3_HEIGHT; 87 | 88 | if(proc == NULL) 89 | proc= bmp16_drawg_default; 90 | tc->eraseProc= bmp16_erase; 91 | break; 92 | } 93 | 94 | tc->drawgProc= proc; 95 | } 96 | 97 | 98 | //! Erase part of the 8bpp text canvas. 99 | void bmp8_erase(int left, int top, int right, int bottom) 100 | { 101 | TTC *tc= tte_get_context(); 102 | 103 | //# Check for single sequence 104 | sbmp8_rect(&tc->dst, left, top, right, bottom, tc->cattr[TTE_PAPER]); 105 | } 106 | 107 | 108 | //! Erase part of the 16bpp text canvas. 109 | void bmp16_erase(int left, int top, int right, int bottom) 110 | { 111 | TTC *tc= tte_get_context(); 112 | 113 | //# Check for single sequence 114 | sbmp16_rect(&tc->dst, left, top, right, bottom, tc->cattr[TTE_PAPER]); 115 | } 116 | 117 | 118 | // EOF 119 | -------------------------------------------------------------------------------- /src/tte/tte_init_chr4c.c: -------------------------------------------------------------------------------- 1 | 2 | // 3 | // Initializer for 4bpp tiled, column-major surfaces 4 | // 5 | //! \file tte_init_chr4c.c 6 | //! \author J Vijn 7 | //! \date 20070517 - 20080427 8 | // 9 | /* === NOTES === 10 | * 20080315,jv: separated clrids into se0 and cattrs fields. 11 | se0: screen-entry offset for map 12 | cattrs: packed BYTES (not nybbles) for color attributes. 13 | */ 14 | 15 | #include 16 | #include 17 | #include "tonc_tte.h" 18 | 19 | 20 | // -------------------------------------------------------------------- 21 | // GLOBALS 22 | // -------------------------------------------------------------------- 23 | 24 | // -------------------------------------------------------------------- 25 | // FUNCTIONS 26 | // -------------------------------------------------------------------- 27 | 28 | 29 | //! Initialize text system for 4bpp tiled, column-major surfaces. 30 | /*! 31 | \param bgnr Background number. 32 | \param bgcnt Background control flags. 33 | \param se0 Base offset for screen-entries. 34 | \param cattrs Color attributes; one byte per attr. 35 | \param clrs ink(/shadow) colors. 36 | \param font Font to initialize with. 37 | \param proc Glyph renderer 38 | */ 39 | void tte_init_chr4c(int bgnr, u16 bgcnt, u16 se0, u32 cattrs, u32 clrs, 40 | const TFont *font, fnDrawg proc) 41 | { 42 | if(font==NULL) font= &vwf_default; 43 | if(proc==NULL) proc= chr4c_drawg_default; 44 | 45 | tte_init_base(font, proc, chr4c_erase); 46 | 47 | TTC *tc= tte_get_context(); 48 | TSurface *srf= &tc->dst; 49 | 50 | srf_init(srf, SRF_CHR4C, 51 | &tile_mem[BFN_GET(bgcnt, BG_CBB)][se0 & SE_ID_MASK], 52 | SCREEN_WIDTH, SCREEN_HEIGHT, 4, pal_bg_mem); 53 | schr4c_prep_map(srf, se_mem[BFN_GET(bgcnt, BG_SBB)], se0); 54 | 55 | tc->flags0= bgnr; 56 | tc->ctrl= bgcnt; 57 | REG_BGCNT[bgnr]= bgcnt; 58 | 59 | // --- Init color attributes --- 60 | u32 ink, shadow, paper; //spec; 61 | ink= cattrs & 15; 62 | shadow= (cattrs>> 8)& 15; 63 | paper= (cattrs>>16)& 15; 64 | //spec= (cattrs>>24)&255; 65 | 66 | tc->cattr[TTE_INK]= ink; 67 | tc->cattr[TTE_SHADOW]= shadow; 68 | tc->cattr[TTE_PAPER]= paper; 69 | //tc->cattr[TTE_SPECIAL]= 0; 70 | 71 | srf->palData= pal_bg_bank[se0>>12]; 72 | srf->palData[ink]= clrs&0xFFFF; 73 | srf->palData[shadow]= clrs>>16; 74 | } 75 | 76 | 77 | //! Erase part of the 4bpp text canvas. 78 | void chr4c_erase(int left, int top, int right, int bottom) 79 | { 80 | TTC *tc= tte_get_context(); 81 | 82 | //# Check for single sequence 83 | schr4c_rect(&tc->dst, left, top, right, bottom, tc->cattr[TTE_PAPER]); 84 | } 85 | 86 | // EOF 87 | -------------------------------------------------------------------------------- /src/tte/tte_init_chr4r.c: -------------------------------------------------------------------------------- 1 | 2 | // 3 | // Initializer for 4bpp tiled surfaces, row-major. 4 | // 5 | //! \file tte_init_chr4r.c 6 | //! \author J Vijn 7 | //! \date 20070517 - 20080515 8 | // 9 | /* === NOTES === 10 | * 20080315,jv: separated clrids into se0 and cattrs fields. 11 | se0: screen-entry offset for map 12 | cattrs: packed BYTES (not nybbles) for color attributes. 13 | */ 14 | 15 | #include 16 | #include 17 | #include "tonc_tte.h" 18 | 19 | 20 | // -------------------------------------------------------------------- 21 | // GLOBALS 22 | // -------------------------------------------------------------------- 23 | 24 | // -------------------------------------------------------------------- 25 | // FUNCTIONS 26 | // -------------------------------------------------------------------- 27 | 28 | 29 | //! Initialize text system for 4bpp tiled, column-major surfaces. 30 | /*! 31 | \param bgnr Background number. 32 | \param bgcnt Background control flags. 33 | \param se0 Base offset for screen-entries. 34 | \param cattrs Color attributes; one byte per attr. 35 | \param clrs ink(/shadow) colors. 36 | \param font Font to initialize with. 37 | \param proc Glyph renderer 38 | */ 39 | void tte_init_chr4r(int bgnr, u16 bgcnt, u16 se0, u32 cattrs, u32 clrs, 40 | const TFont *font, fnDrawg proc) 41 | { 42 | if(font==NULL) font= &vwf_default; 43 | if(proc==NULL) proc= chr4r_drawg_default; 44 | 45 | tte_init_base(font, proc, chr4r_erase); 46 | REG_BGCNT[bgnr]= bgcnt; 47 | 48 | TTC *tc= tte_get_context(); 49 | TSurface *srf= &tc->dst; 50 | 51 | srf_init(srf, SRF_CHR4R, 52 | &tile_mem[BFN_GET(bgcnt, BG_CBB)][se0 & SE_ID_MASK], 53 | SCREEN_WIDTH, SCREEN_HEIGHT, 4, pal_bg_mem); 54 | schr4r_prep_map(srf, se_mem[BFN_GET(bgcnt, BG_SBB)], se0); 55 | 56 | tc->flags0= bgnr; 57 | tc->ctrl= bgcnt; 58 | REG_BGCNT[bgnr]= bgcnt; 59 | 60 | // --- Init color attribute --- 61 | u32 ink, shadow, paper; //spec; 62 | ink= cattrs & 15; 63 | shadow= (cattrs>> 8)& 15; 64 | paper= (cattrs>>16)& 15; 65 | //spec= (cattrs>>24)&255; 66 | 67 | tc->cattr[TTE_INK]= ink; 68 | tc->cattr[TTE_SHADOW]= shadow; 69 | tc->cattr[TTE_PAPER]= paper; 70 | //tc->cattr[TTE_SPECIAL]= 0; 71 | 72 | srf->palData= pal_bg_bank[se0>>12]; 73 | srf->palData[ink]= clrs&0xFFFF; 74 | srf->palData[shadow]= clrs>>16; 75 | } 76 | 77 | 78 | //! Erase part of the 4bpp text canvas. 79 | void chr4r_erase(int left, int top, int right, int bottom) 80 | { 81 | TTC *tc= tte_get_context(); 82 | 83 | //# Check for single sequence 84 | schr4r_rect(&tc->dst, left, top, right, bottom, tc->cattr[TTE_PAPER]); 85 | } 86 | 87 | // EOF 88 | -------------------------------------------------------------------------------- /src/tte/tte_init_obj.c: -------------------------------------------------------------------------------- 1 | // 2 | // Object glyph plotter initializer 3 | // 4 | //! \file tte_init_obj.c 5 | //! \author J Vijn 6 | //! \date 20070715 - 20080229 7 | // 8 | /* === NOTES === 9 | * 20070715: The object system works a little differently than the 10 | others. Objects are used as a descending stack with dstPitch as the 11 | backwards obj index. Also, INK, SHADOW and SPECIAL are base 12 | attributes of the objects. obj_erase unwinds the whole obj-stack. 13 | */ 14 | 15 | #include 16 | 17 | #include "tonc_memdef.h" 18 | #include "tonc_core.h" 19 | #include "tonc_bios.h" 20 | #include "tonc_tte.h" 21 | 22 | 23 | // -------------------------------------------------------------------- 24 | // FUNCTIONS 25 | // -------------------------------------------------------------------- 26 | 27 | //! Initialize text system for screen-entry fonts. 28 | /*! 29 | \param obj Destination object. 30 | \param attr0 Base obj.attr0. 31 | \param attr1 Base obj.attr1. 32 | \param attr2 Base obj.attr2. 33 | \param clrs colors to use for the text. The palette entries 34 | used depends on \a attr2 and \a bupofs. 35 | \param bupofs Flags for font bit-unpacking. Basically indicates 36 | pixel values (and hence palette use). 37 | \param font Font to initialize with. 38 | \param proc Character plotting procedure. 39 | \note The TTE-obj system uses the surface differently than then 40 | rest. Be careful when modifying the surface data. 41 | \todo Multi-bpp. 42 | */ 43 | void tte_init_obj(OBJ_ATTR *obj, u32 attr0, u32 attr1, u32 attr2, 44 | u32 clrs, u32 bupofs, const TFont *font, fnDrawg proc) 45 | { 46 | if(font==NULL) font= &fwf_default; 47 | if(proc==NULL) proc= obj_drawg_default; 48 | 49 | tte_init_base(font, proc, obj_erase); 50 | 51 | TTC *tc= tte_get_context(); 52 | TSurface *srf= &tc->dst; 53 | 54 | srf->data= (u8*)(obj ? obj : &oam_mem[127]); 55 | srf->pitch= 0; // NOTE: works as a backwards index, not pitch. 56 | srf->width= 128; 57 | srf->height= 0; 58 | srf->bpp= 4; 59 | srf->type= SRF_NONE; 60 | srf->palSize= 16; 61 | //srf->palData= pal_obj_mem; 62 | 63 | // --- Prep color-lut and palette --- 64 | uint tid= BFN_GET(attr2, ATTR2_ID); 65 | uint pb = BFN_GET(attr2, ATTR2_PALBANK); 66 | srf->palData= pal_obj_bank[pb]; 67 | 68 | srf->palData[(bupofs+1)&15]= clrs&0xFFFF; 69 | if( (bupofs&~BUP_ALL_OFS) > 15) 70 | srf->palData[(bupofs>>4)&15]= clrs>>16; 71 | 72 | tc->cattr[0]= attr0 &~ ATTR0_Y_MASK; 73 | tc->cattr[1]= attr1 &~ ATTR1_X_MASK; 74 | tc->cattr[2]= attr2; 75 | //tc->cattr[3]= 0; 76 | 77 | // --- Unpack font --- 78 | u32 dstS= font->charCount*font->cellSize; 79 | 80 | BUP bup= { dstS, font->bpp, 4, bupofs }; 81 | BitUnPack(font->data, &tile_mem[4][tid], &bup); 82 | } 83 | 84 | // EOF 85 | -------------------------------------------------------------------------------- /src/tte/tte_init_se.c: -------------------------------------------------------------------------------- 1 | // 2 | // Screen-entry glyph renderer initializer 3 | // 4 | //! \file tte_init_se.c 5 | //! \author J Vijn 6 | //! \date 20070628 - 20080229 7 | // 8 | // === NOTES === 9 | 10 | #include 11 | 12 | #include "tonc_memdef.h" 13 | #include "tonc_core.h" 14 | #include "tonc_bios.h" 15 | #include "tonc_tte.h" 16 | 17 | 18 | // -------------------------------------------------------------------- 19 | // FUNCTIONS 20 | // -------------------------------------------------------------------- 21 | 22 | 23 | //! Initialize text system for screen-entry fonts. 24 | /*! 25 | \param bgnr Number of background to be used for text. 26 | \param bgcnt Background control flags. 27 | \param se0 Base screen entry. This allows a greater range in 28 | capabilities, like offset tile-starts and palettes. 29 | \param clrs colors to use for the text. The palette entries 30 | used depends on \a se0 and \a bupofs. 31 | \param bupofs Flags for font bit-unpacking. Basically indicates 32 | pixel values (and hence palette use). 33 | \param font Font to initialize with. 34 | \param proc Glyph renderer. 35 | */ 36 | void tte_init_se(int bgnr, u16 bgcnt, SCR_ENTRY se0, u32 clrs, u32 bupofs, 37 | const TFont *font, fnDrawg proc) 38 | { 39 | if(font==NULL) font= &fwf_default; 40 | if(proc==NULL) proc= se_drawg_default; 41 | 42 | tte_init_base(font, proc, se_erase); 43 | 44 | TTC *tc= tte_get_context(); 45 | TSurface *srf= &tc->dst; 46 | 47 | srf_init(srf, SRF_BMP16, se_mem[BFN_GET(bgcnt, BG_SBB)], 48 | 32, 32, 16, pal_bg_mem); 49 | srf_set_pal(srf, pal_bg_mem, 256); 50 | 51 | tc->flags0= bgnr; 52 | tc->ctrl= bgcnt; 53 | REG_BGCNT[bgnr]= bgcnt; 54 | 55 | // --- Prep color attributes and palette --- 56 | uint dstB= (bgcnt & BG_8BPP) ? 8 : 4; 57 | uint ink, shadow=0, paper; 58 | uint se= BFN_GET(se0, SE_ID); 59 | 60 | if(dstB == 4) 61 | { 62 | u32 pb= BFN_GET(se0, SE_PALBANK)*16; 63 | 64 | ink= pb + ((bupofs+1)&15); 65 | if( (bupofs&~BUP_ALL_OFS) > 15) 66 | shadow= pb + ((bupofs>>4)&15); 67 | } 68 | else 69 | { 70 | se *= 2; // Correct for tile stride 71 | 72 | ink= (bupofs+1)&255; 73 | if( (bupofs&~BUP_ALL_OFS) > 255) 74 | shadow= (bupofs>>8)&255; 75 | } 76 | // Set paper entry (PONDER: color too somehow?) 77 | paper= (bupofs&BUP_ALL_OFS) ? bupofs : 0; 78 | 79 | tc->cattr[TTE_INK]= ink; 80 | tc->cattr[TTE_SHADOW]= shadow; 81 | tc->cattr[TTE_PAPER]= paper; 82 | tc->cattr[TTE_SPECIAL]= se0; 83 | 84 | srf->palData[ink]= clrs&0xFFFF; 85 | if(shadow) 86 | srf->palData[shadow]= clrs>>16; 87 | 88 | // --- Bitunpack font --- 89 | void *dstD= &tile_mem[BFN_GET(bgcnt, BG_CBB)][se]; 90 | u32 dstS= font->charCount*font->cellSize; 91 | 92 | BUP bup= { dstS, font->bpp, dstB, bupofs }; 93 | BitUnPack(font->data, dstD, &bup); 94 | } 95 | 96 | // EOF 97 | -------------------------------------------------------------------------------- /src/tte/tte_iohook.c: -------------------------------------------------------------------------------- 1 | // 2 | // io hooks for using printf 3 | // 4 | //! \file tte_iohook.c 5 | //! \author J Vijn 6 | //! \date 20070517 - 20070517 7 | // 8 | // === NOTES === 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include "tonc_tte.h" 16 | #include "tonc_nocash.h" 17 | 18 | 19 | static int sConInitialized= 0; 20 | 21 | uint utf8_decode_char(const char *ptr, char **endptr); 22 | 23 | // -------------------------------------------------------------------- 24 | // CONSTANTS 25 | // MACROS 26 | // CLASSES 27 | // GLOBALS 28 | // PROTOTYPES 29 | // FUNCTIONS 30 | 31 | const devoptab_t tte_dotab_stdout= 32 | { 33 | "ttecon", 34 | 0, 35 | NULL, 36 | NULL, 37 | tte_con_write, 38 | NULL, 39 | NULL, 40 | NULL 41 | }; 42 | 43 | const devoptab_t tte_dotab_nocash= 44 | { 45 | "ttenocash", 46 | 0, 47 | NULL, 48 | NULL, 49 | tte_con_nocash, 50 | NULL, 51 | NULL, 52 | NULL 53 | }; 54 | 55 | 56 | //! Init stdio capabilities. 57 | void tte_init_con() 58 | { 59 | devoptab_list[STD_OUT] = &tte_dotab_stdout; 60 | devoptab_list[STD_ERR] = &tte_dotab_nocash; 61 | setvbuf(stdout, NULL , _IONBF, 0); 62 | setvbuf(stderr, NULL , _IONBF, 0); 63 | 64 | sConInitialized = 1; 65 | } 66 | 67 | 68 | //! Parse for VT100-sequences 69 | /*! Taken librally from libgba.
70 | See 71 | here for a full overview. 72 | \param text Sequence string, starting at the '['. 73 | \todo: check for buffer overflow. 74 | */ 75 | int tte_cmd_vt100(const char *text) 76 | { 77 | int ch; 78 | const char *str= text; 79 | 80 | TTC *tc= tte_get_context(); 81 | int x, y; 82 | int x2, y2, dx, dy; 83 | 84 | while( (ch=*str) != '\0') 85 | { 86 | str++; 87 | switch(ch) 88 | { 89 | case 'A': // Cursor up, with clamp. 90 | siscanf(text,"[%dA", &dy); 91 | y= tc->cursorY - dy*tc->font->charH; 92 | tc->cursorY= (y >= tc->marginTop ? y : tc->marginTop); 93 | return str-text; 94 | 95 | case 'B': // Cursor down, with clamp. 96 | siscanf(text,"[%dB", &dy); 97 | y = tc->cursorY + dy*tc->font->charH; 98 | y2= tc->marginBottom-tc->font->charH; 99 | tc->cursorY= (y <= y2 ? y : y2); 100 | return str-text; 101 | 102 | case 'C': // Cursor right, with clamp. 103 | siscanf(text,"[%dC", &dx); 104 | x = tc->cursorX + dx*tc->font->cellW; 105 | x2= tc->marginRight- tc->font->cellW; 106 | tc->cursorX= (x <= x2 ? x : x2); 107 | return str-text; 108 | 109 | case 'D': // Cursor left, with clamp. 110 | siscanf(text,"[%dD", &dx); 111 | x = tc->cursorX - dx*tc->font->cellW; 112 | tc->cursorX= (x >= tc->marginLeft ? x : tc->marginLeft); 113 | return str-text; 114 | 115 | case 'H': // Set position. 116 | case 'f': 117 | siscanf(text,"[%d;%d", &x, &y); 118 | tc->cursorX= x; 119 | tc->cursorY= y; 120 | return str-text; 121 | 122 | case 'J': // Clear screen 123 | if(text[1] == '2') 124 | tte_erase_screen(); 125 | return str-text; 126 | 127 | case 'K': // Clear rest of line 128 | { 129 | switch(text[1]) 130 | { 131 | case 1: // Line up to here 132 | tte_erase_rect(0, tc->cursorY, 133 | tc->cursorX, tc->cursorY+tc->font->charH); 134 | break; 135 | case 2: // Entire line 136 | tte_erase_line(); 137 | break; 138 | default: 139 | tte_erase_rect(tc->cursorX, tc->cursorY, 140 | tc->marginRight, tc->cursorY+tc->font->charH); 141 | } 142 | return str-text; 143 | } 144 | 145 | case 's': // Save curson position 146 | tc->savedX = tc->cursorX; 147 | tc->savedY = tc->cursorY; 148 | return str-text; 149 | 150 | case 'u': // Restore cursor position 151 | tc->cursorX = tc->savedX; 152 | tc->cursorX = tc->savedY; 153 | return str-text; 154 | } 155 | } 156 | 157 | // Couldn't find anything: use as normal string 158 | return 0; 159 | } 160 | 161 | 162 | ssize_t tte_con_nocash(struct _reent *r, void *fd, const char *text, size_t len) 163 | { 164 | if(text==NULL || len<=0) 165 | return -1; 166 | 167 | int ii, count; 168 | for(ii=0; iilen ? len-ii : 80; 171 | strncpy(nocash_buffer, &text[ii], count); 172 | nocash_buffer[count]= '\0'; 173 | nocash_message(); 174 | } 175 | return len; 176 | 177 | } 178 | 179 | //! Internal routine for stdio functionality. 180 | /*! \note While this function 'works', I am not 100% sure I'm 181 | handling everything correctly. 182 | */ 183 | ssize_t tte_con_write(struct _reent *r, void *fd, const char *text, size_t len) 184 | { 185 | if(!sConInitialized || !text || len<=0) 186 | return -1; 187 | 188 | // The buffer is not zeroed, so PLEASE use len properly. 189 | 190 | uint ch, gid; 191 | char *str= (char*)text; 192 | const char *end= text+len; 193 | 194 | TTC *tc= tte_get_context(); 195 | TFont *font; 196 | 197 | while( (ch= *str) != 0 && str < end) 198 | { 199 | str++; 200 | switch(ch) 201 | { 202 | // --- Newline/carriage return --- 203 | case '\r': 204 | if(str[0] == '\n') // deal with CRLF pair 205 | str++; 206 | // FALLTHRU 207 | case '\n': 208 | tc->cursorY += tc->font->charH; 209 | tc->cursorX = tc->marginLeft; 210 | break; 211 | 212 | // --- Tab --- 213 | case '\t': 214 | tc->cursorX= (tc->cursorX/TTE_TAB_WIDTH+1)*TTE_TAB_WIDTH; 215 | break; 216 | 217 | // --- VT100 sequence ( ESC[foo; ) --- 218 | case 0x1B: 219 | if(str[0] == '[') 220 | str += tte_cmd_vt100(str); 221 | break; 222 | 223 | // --- Normal char --- 224 | default: 225 | // Command sequence 226 | if(ch=='#' && str[0]=='{') 227 | { 228 | str= tte_cmd_default(str+1); 229 | break; 230 | } 231 | // Escaped command: skip '\\' and print '#' 232 | else if(ch=='\\' && str[0]=='#') 233 | ch= *str++; 234 | // Check for UTF8 code 235 | else if(ch>=0x80) 236 | ch= utf8_decode_char(str-1, &str); 237 | 238 | // Get glyph index and call renderer 239 | font= tc->font; 240 | gid= ch - font->charOffset; 241 | if(tc->charLut) 242 | gid= tc->charLut[gid]; 243 | 244 | // Character wrap 245 | int charW= font->widths ? font->widths[gid] : font->charW; 246 | if(tc->cursorX+charW > tc->marginRight) 247 | { 248 | tc->cursorY += font->charH; 249 | tc->cursorX = tc->marginLeft; 250 | } 251 | 252 | // Draw and update position 253 | tc->drawgProc(gid); 254 | tc->cursorX += charW; 255 | } 256 | } 257 | 258 | // Return characters used 259 | //# PONDER: This seems to 'work', but is it right? 260 | return str - text; 261 | } 262 | 263 | 264 | // EOF 265 | -------------------------------------------------------------------------------- /src/tte/tte_types.s: -------------------------------------------------------------------------------- 1 | @ 2 | @ Text types formatted for assembly 3 | @ 4 | @! \file tte_types.s 5 | @! \author J Vijn 6 | @! \date 20070517 - 20070813 7 | @ 8 | @ === NOTES === 9 | 10 | /* 11 | typedef int (*fn_drawg)(int); 12 | 13 | typedef struct TFont 14 | { 15 | const u32 *data; //!< Character data. 16 | const u8 *widths; //!< Width table for variable width font. 17 | const u8 *heights; //!< Height table for variable height font. 18 | u16 charOffset; //!< Character offset. 19 | u16 charCount; //!< Number of characters in font. 20 | u8 charW; //!< Character width (fwf). 21 | u8 charH; //!< Character height. 22 | u8 cellW; //!< Glyph cell width. 23 | u8 cellH; //!< Glyph cell height. 24 | u16 cellSize; //!< Cell-size (bytes). 25 | u8 bpp; //!< Font bitdepth; 26 | u8 extra; //!< Padding. Free to use. 27 | } TFont; 28 | 29 | 30 | //! Text context struct 31 | typedef struct TTC 32 | { 33 | // Members for renderers 34 | TSurface dst //!< Destination surface 35 | u16 cursorX; //!< Cursor X-coord. 36 | u16 cursorY; //!< Cursor Y-coord. 37 | TFont *font; //!< Font info. 38 | u8 *charLut; //!< Character mapping lut. (if any) 39 | u16 colors[4]; //!< ink, shadow, paper and special colors. 40 | // Higher control members 41 | u16 flags0; 42 | u16 ctrl; //!< BG control flags. (PONDER: remove?) 43 | u16 marginLeft; 44 | u16 marginTop; 45 | u16 marginRight; 46 | u16 marginBottom; 47 | u16 savedX; 48 | u16 savedY; 49 | // Callbacks and table pointers 50 | fnCmd cmdProc; //!< Text command procedure 51 | fnDrawg drawgProc; //!< Character plot procedure. 52 | fnErase eraseProc; //!< Text eraser procedure 53 | const TFont **fontTable; //!< Pointer to font table for \{c} 54 | const char **stringTable; //!< Pointer to string table for \{s} 55 | } TTC; 56 | 57 | extern TVwf *gp_tte_sys; 58 | */ 59 | 60 | // --- Color lut indices --- 61 | #define TTE_INK 0 62 | #define TTE_SHADOW 1 63 | #define TTE_PAPER 2 64 | #define TTE_SPECIAL 3 65 | 66 | // --- TFont --- 67 | #define TF_data 0 68 | #define TF_widths 4 69 | #define TF_heights 8 70 | #define TF_charOffset 12 71 | #define TF_charCount 14 72 | #define TF_charW 16 73 | #define TF_charH 17 74 | #define TF_cellW 18 75 | #define TF_cellH 19 76 | #define TF_cellS 20 77 | #define TF_bpp 22 78 | #define TF_extra 23 79 | 80 | // --- TTC --- 81 | #define TTC_dstBase 0 82 | #define TTC_dstPitch 4 83 | #define TTC_dstWidth 8 84 | #define TTC_dstHeight 10 85 | #define TTC_dstBpp 12 86 | #define TTC_dstPalSize 14 87 | #define TTC_dstPal 16 88 | 89 | #define TTC_cursorX 20 90 | #define TTC_cursorY 22 91 | #define TTC_font 24 92 | #define TTC_charLut 28 93 | 94 | #define TTC_colors 32 95 | #define TTC_ink 32 96 | #define TTC_shadow 34 97 | #define TTC_paper 36 98 | #define TTC_special 38 99 | 100 | #define TTC_flags0 40 101 | #define TTC_ctrl 42 102 | 103 | #define TTC_marginLeft 44 104 | #define TTC_marginTop 46 105 | #define TTC_marginRight 48 106 | #define TTC_marginBottom 50 107 | #define TTC_savedX 52 108 | #define TTC_savedY 54 109 | 110 | #define TTC_cmdProc 56 111 | #define TTC_drawgProc 60 112 | #define TTC_eraseProc 64 113 | #define TTC_fontTable 68 114 | #define TTC_stringTable 72 115 | #define TTC_end 76 116 | 117 | .extern gp_tte_sys 118 | 119 | @ EOF 120 | -------------------------------------------------------------------------------- /todo.txt: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // 4 | 5 | // --- Todo for old tonc --- 6 | Fix memset16, which has a bug for large, uneven copies. 7 | Near the check after memset32, "lsr r1, r1" should be "lsr r1, #16" 8 | and I'm an utter twat for not realising it. Shifting a number by 9 | itself, what was I thinking?!? 10 | 11 | // --- Todo (20070803) --- 12 | 13 | + add dma_cpy functions. In name I mean. 14 | + put oft-used globals in common.c (nm, too few to bother) 15 | * key_reset, or something like it for avoiding key bounce 16 | * oe_hide for multiple objects. Seriously. 17 | * PAD macro for arrays. Can't have alignment issues, can we? 18 | * add sound stuff 19 | * Dooby div ? (+ bin-search) 20 | * tonc_atan2 ? 21 | / faders 22 | * windowers 23 | * ASSERT ? 24 | + DMA_BUILD and TM_BUILD 25 | + something for oft-used key-switches: if(up) x++; else if(down) x--; 26 | * txt_init_se should have options iso bupofs 27 | 28 | - turn ints off in irq_init? Yes !!! 29 | - lut / div lut / atan lut ? 30 | + affine functions 31 | - mode7 functions (in asm plz) 32 | - basic mosaic / fade / window 33 | 34 | / Replace old text system for new, and update demos for it. 35 | - Refactor the tonc_video.h 36 | + Refactor/Remove tonc_bitmap.c ? Mostly superceded by bmp8.c/bmp16.c anyway 37 | Hmm, maybe keep as backup? 38 | + Add bmp8_line() 39 | - Add more chr4 stuff? 40 | + Change mx_foo to use bmp8/16. 41 | - PONDER: redistribute math.h ? 42 | - PONDER: move color/palette stuff to color.h ? 43 | / Use libgba #defines for some of the reg-bits 44 | - make a vid_reset (and possibly sound reset) 45 | 46 | Legacy items: 47 | 48 | void bm8_hline(u8 *dst, int width, u8 clrid); 49 | void bm8_vline(u8 *dst, int height, u8 clrid, int pitch); 50 | //void bm8_line(u8 *dst, int dx, int y, u8 clrid, int pitch); 51 | void bm8_rect(u8 *dst, int width, int height, u8 clrid, int pitch); 52 | void bm8_frame(u8 *dst, int width, int height, u8 clrid, int pitch); 53 | 54 | // 16bit (mode 3/5, se) 55 | void bm16_hline(u16 *dst, int width, u16 clr); 56 | void bm16_vline(u16 *dst, int height, u16 clr, int pitch); 57 | void bm16_line(u16 *dst, int dx, int y, COLOR clr, int pitch); 58 | void bm16_rect(u16 *dst, int width, int height, u16 clr, int pitch); 59 | void bm16_frame(u16 *dst, int width, int height, u16 clr, int pitch); 60 | 61 | Possibly some se_foo() things too 62 | 63 | RESET_foo -> RESET_REG_foo 64 | 65 | 66 | // 20070921 67 | 68 | Working on libgba compatibility. Found a few things: 69 | 70 | REG_JOYCNT is :0140, not 0150 71 | SDS_ATR0 -> SDS_ATMR0 72 | added DMA_GAMEPAK 73 | REG_SIOCNT and REG_JSTAT are vu16 74 | REG_WAVE -> REG_WAVE_RAM 75 | REG_FIFOA/B -> REG_FIFO_A/_B 76 | REG_TMxCNT_L/H #defines 77 | 78 | bool enum 79 | 80 | SoftReset flags. (Has parameters after all :\) 81 | 82 | 83 | A number of memmap defines should be altered 84 | 85 | 86 | // 20070804, sa 87 | 88 | Added bf_get, bf_merge and BF_MERGE. 89 | 90 | 91 | // 20060905, fr 92 | More name changes 93 | 94 | OAM_ENTRY -> OBJ_ATTR 95 | OAM_AFF_ENTRY -> OBJ_AFFINE 96 | 97 | oe -> obj 98 | OE_A -> OA 99 | oa -> oaff 100 | SB_ENTRY -> SCR_ENTRY 101 | Members in AFF_DST_EX. 102 | 103 | IO's foo_mem to REG_foo, etc 104 | BGPOINT -> BG_POINT 105 | 106 | 107 | // --- (20050717) --- 108 | ++ several masks in toolbox2.c are incorrect. 109 | 110 | // --- (20050731) --- 111 | ++ move _pbank up in SE_BUILD 112 | ++ fixed memset16 for odd high counts 113 | 114 | // --- Done (20050731) --- 115 | ++ rename OE_A0_AFF to uhm OE_A0_MODE 116 | ++ Change text routines to use globals, not rely on structures 117 | so much, as it bugs the user (at least _this_ user). 118 | ++ REMU_VAL, REMU_DIV (toncmath.h) 119 | ++ added sinlut 120 | ++ octant routine. S. Tested and working. 121 | 122 | ++ VBlankIntrDelay 123 | ++ Change swi_ex names to something more in line with the rest 124 | CpuFastFill, Mod, DivSafe. Y'know, for consistency. 125 | ++ remove BIT0 to BIT31, gawd that thing's ugly 126 | ++ mod swi_fast_fill's wd-loader to "push {r0}". Silly me. 127 | ++ SE_BUILD 128 | ++ OE_Ax_BUILD -------------------------------------------------------------------------------- /toncfont.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devkitPro/libtonc/ccc03fa321e56f51aed5e2ee1d6e3df3d1cbc803/toncfont.bmp --------------------------------------------------------------------------------