initial commit

This commit is contained in:
smea 2012-12-21 18:07:13 +01:00
commit b5192082f2
188 changed files with 18429 additions and 0 deletions

39
Makefile Normal file
View File

@ -0,0 +1,39 @@
#---------------------------------------------------------------------------------
.SUFFIXES:
#---------------------------------------------------------------------------------
ifeq ($(strip $(DEVKITARM)),)
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
endif
include $(DEVKITARM)/ds_rules
NITRODATA := nitrofiles
export TARGET := $(shell basename $(CURDIR))
export TOPDIR := $(CURDIR)
.PHONY: arm7/$(TARGET).elf arm9/$(TARGET).elf
#---------------------------------------------------------------------------------
# main targets
#---------------------------------------------------------------------------------
all: $(TARGET).nds
#---------------------------------------------------------------------------------
$(TARGET).nds : arm7/$(TARGET).elf arm9/$(TARGET).elf
ndstool -c $(TARGET).nds -b logo.bmp "Portal DS;prototype;smea" -7 arm7/$(TARGET).elf -9 arm9/$(TARGET).elf -d $(NITRODATA)
#---------------------------------------------------------------------------------
arm7/$(TARGET).elf:
$(MAKE) -C arm7
#---------------------------------------------------------------------------------
arm9/$(TARGET).elf:
$(MAKE) -C arm9
#---------------------------------------------------------------------------------
clean:
$(MAKE) -C arm9 clean
$(MAKE) -C arm7 clean
rm -f $(TARGET).nds $(TARGET).arm7 $(TARGET).arm9

BIN
arm-none-eabi-addr2line.exe Normal file

Binary file not shown.

126
arm7/Makefile Normal file
View File

@ -0,0 +1,126 @@
#---------------------------------------------------------------------------------
.SUFFIXES:
#---------------------------------------------------------------------------------
ifeq ($(strip $(DEVKITARM)),)
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
endif
include $(DEVKITARM)/ds_rules
#---------------------------------------------------------------------------------
# BUILD is the directory where object files & intermediate files will be placed
# SOURCES is a list of directories containing source code
# INCLUDES is a list of directories containing extra header files
# DATA is a list of directories containing binary files
# all directories are relative to this makefile
#---------------------------------------------------------------------------------
BUILD := build
SOURCES := source
INCLUDES := include build
DATA :=
#---------------------------------------------------------------------------------
# options for code generation
#---------------------------------------------------------------------------------
ARCH := -marm
CFLAGS := -g -Wall -Os\
-mcpu=arm7tdmi -mtune=arm7tdmi -fomit-frame-pointer\
-ffast-math \
$(ARCH)
CFLAGS += $(INCLUDE) -DARM7
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -fno-rtti
ASFLAGS := -g $(ARCH)
LDFLAGS = -specs=ds_arm7.specs -g $(ARCH) -Wl,-Map,$(notdir $*).map
LIBS := -ldswifi7 -lmm7 -lnds7
#---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing
# include and lib
#---------------------------------------------------------------------------------
LIBDIRS := $(LIBNDS)
#---------------------------------------------------------------------------------
# no real need to edit anything past this point unless you need to add additional
# rules for different file extensions
#---------------------------------------------------------------------------------
ifneq ($(BUILD),$(notdir $(CURDIR)))
#---------------------------------------------------------------------------------
export ARM7ELF := $(CURDIR)/$(TARGET).elf
export DEPSDIR := $(CURDIR)/$(BUILD)
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir))
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
export OFILES := $(addsuffix .o,$(BINFILES)) \
$(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
-I$(CURDIR)/$(BUILD)
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
#---------------------------------------------------------------------------------
# use CXX for linking C++ projects, CC for standard C
#---------------------------------------------------------------------------------
ifeq ($(strip $(CPPFILES)),)
#---------------------------------------------------------------------------------
export LD := $(CC)
#---------------------------------------------------------------------------------
else
#---------------------------------------------------------------------------------
export LD := $(CXX)
#---------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------
.PHONY: $(BUILD) clean
#---------------------------------------------------------------------------------
$(BUILD):
@[ -d $@ ] || mkdir -p $@
@make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
#---------------------------------------------------------------------------------
clean:
@echo clean ...
@rm -fr $(BUILD) *.elf
#---------------------------------------------------------------------------------
else
DEPENDS := $(OFILES:.o=.d)
#---------------------------------------------------------------------------------
# main targets
#---------------------------------------------------------------------------------
$(ARM7ELF) : $(OFILES)
@echo linking $(notdir $@)
@$(LD) $(LDFLAGS) $(OFILES) $(LIBPATHS) $(LIBS) -o $@
#---------------------------------------------------------------------------------
# you need a rule like this for each extension you use as binary data
#---------------------------------------------------------------------------------
%.bin.o : %.bin
#---------------------------------------------------------------------------------
@echo $(notdir $<)
@$(bin2o)
-include $(DEPENDS)
#---------------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------------

35
arm7/include/AAR.h Normal file
View File

@ -0,0 +1,35 @@
#ifndef AAR_H //axis aligned rectangle !
#define AAR_H
#define NUMAARS (150)
#define NUMAARSEGMENTS (4)
#define NODESIZE (2048)
typedef struct
{
vect3D position, size, normal;
bool used;
}AAR_struct;
// 4*3 + 4*3 + 4*3 + 1 = 37
// 2*2 + 1 + 3*1 + 1 + 1 = 10
typedef struct
{
u16* data;
u8 length;
}node_struct;
typedef struct
{
node_struct* nodes;
u16 width, height;
vect3D m, M;
}grid_struct;
void initAARs(void);
void drawAARs(void);
void AARsOBBContacts(OBB_struct* o);
AAR_struct* createAAR(u16 id, vect3D position, vect3D size, vect3D normal);
#endif

155
arm7/include/LUTs.h Normal file
View File

@ -0,0 +1,155 @@
#ifndef LUTS_H
#define LUTS_H
#define SQRTRANGE (512)
#define SQRTPRECISION (4096)
static const int32 sqrtLUT1[SQRTRANGE]=
{0, 4096, 5792, 7094, 8192, 9158, 10033, 10836, 11585, 12288, 12952, 13584, 14188, 14768, 15325, 15863, 16384, 16888, 17377, 17854, 18317, 18770, 19211, 19643, 20066, 20480, 20885, 21283, 21673, 22057, 22434, 22805, 23170, 23529, 23883, 24232, 24576, 24914, 25249, 25579, 25905, 26227, 26545, 26859, 27169, 27476, 27780, 28080, 28377, 28672, 28963, 29251, 29536, 29819, 30099, 30376, 30651, 30924, 31194, 31461, 31727, 31990, 32251, 32510, 32768,
33023, 33276, 33527, 33776, 34023, 34269, 34513, 34755, 34996, 35235, 35472, 35708, 35942, 36174, 36406, 36635, 36864, 37090, 37316, 37540, 37763, 37984, 38204, 38423, 38641, 38858, 39073, 39287, 39500, 39712, 39922, 40132, 40340, 40548, 40754, 40960, 41164, 41367, 41569, 41771, 41971, 42170, 42369, 42566, 42763, 42959, 43154, 43347, 43541, 43733, 43924, 44115, 44305, 44493, 44682, 44869, 45056, 45241, 45426, 45611, 45794, 45977, 46159, 46340,
46521, 46701, 46880, 47059, 47237, 47414, 47591, 47767, 47942, 48117, 48291, 48464, 48637, 48809, 48981, 49152, 49322, 49492, 49661, 49829, 49998, 50165, 50332, 50498, 50664, 50830, 50994, 51159, 51322, 51485, 51648, 51810, 51972, 52133, 52294, 52454, 52614, 52773, 52931, 53090, 53248, 53405, 53562, 53718, 53874, 54029, 54184, 54339, 54493, 54647, 54800, 54953, 55106, 55258, 55409, 55560, 55711, 55861, 56011, 56161, 56310, 56459, 56607, 56755,
56903, 57050, 57197, 57344, 57490, 57635, 57781, 57926, 58070, 58215, 58359, 58502, 58645, 58788, 58931, 59073, 59215, 59356, 59497, 59638, 59779, 59919, 60059, 60198, 60337, 60476, 60615, 60753, 60891, 61029, 61166, 61303, 61440, 61576, 61712, 61848, 61983, 62118, 62253, 62388, 62522, 62656, 62790, 62923, 63057, 63190, 63322, 63454, 63587, 63718, 63850, 63981, 64112, 64243, 64373, 64503, 64633, 64763, 64892, 65021, 65150, 65279, 65407, 65536,
65663, 65791, 65918, 66046, 66172, 66299, 66425, 66552, 66678, 66803, 66929, 67054, 67179, 67304, 67428, 67552, 67677, 67800, 67924, 68047, 68171, 68293, 68416, 68539, 68661, 68783, 68905, 69027, 69148, 69269, 69390, 69511, 69632, 69752, 69872, 69992, 70112, 70231, 70351, 70470, 70589, 70707, 70826, 70944, 71062, 71180, 71298, 71416, 71533, 71650, 71767, 71884, 72001, 72117, 72233, 72349, 72465, 72581, 72696, 72812, 72927, 73042, 73156, 73271,
73385, 73500, 73614, 73728, 73841, 73955, 74068, 74181, 74294, 74407, 74520, 74632, 74744, 74857, 74969, 75080, 75192, 75304, 75415, 75526, 75637, 75748, 75858, 75969, 76079, 76190, 76300, 76409, 76519, 76629, 76738, 76847, 76956, 77065, 77174, 77283, 77391, 77499, 77608, 77716, 77824, 77931, 78039, 78146, 78253, 78361, 78468, 78574, 78681, 78788, 78894, 79000, 79106, 79212, 79318, 79424, 79529, 79635, 79740, 79845, 79950, 80055, 80160, 80264,
80369, 80473, 80577, 80681, 80785, 80889, 80993, 81096, 81200, 81303, 81406, 81509, 81612, 81714, 81817, 81920, 82022, 82124, 82226, 82328, 82430, 82532, 82633, 82735, 82836, 82937, 83038, 83139, 83240, 83341, 83441, 83542, 83642, 83742, 83843, 83943, 84042, 84142, 84242, 84341, 84441, 84540, 84639, 84738, 84837, 84936, 85035, 85133, 85232, 85330, 85428, 85526, 85625, 85722, 85820, 85918, 86016, 86113, 86210, 86308, 86405, 86502, 86599, 86695,
86792, 86889, 86985, 87082, 87178, 87274, 87370, 87466, 87562, 87658, 87753, 87849, 87944, 88040, 88135, 88230, 88325, 88420, 88515, 88610, 88704, 88799, 88893, 88987, 89082, 89176, 89270, 89364, 89457, 89551, 89645, 89738, 89832, 89925, 90018, 90112, 90205, 90297, 90390, 90483, 90576, 90668, 90761, 90853, 90945, 91038, 91130, 91222, 91314, 91405, 91497, 91589, 91680, 91772, 91863, 91954, 92046, 92137, 92228, 92319, 92409, 92500, 92591, };
static const s16 sqrtLUT2[SQRTPRECISION/2]=
{4096, 4097, 4097, 4098, 4099, 4100, 4101, 4102, 4103, 4104, 4105, 4106, 4107, 4108, 4109, 4110, 4111, 4112, 4113, 4114, 4115, 4116, 4117, 4118, 4119, 4120, 4121, 4122, 4123, 4124, 4125, 4126, 4127,
4128, 4129, 4130, 4131, 4132, 4133, 4134, 4135, 4136, 4137, 4138, 4139, 4140, 4141, 4142, 4143, 4144, 4145, 4146, 4147, 4148, 4149, 4150, 4151, 4152, 4153, 4154, 4155, 4156, 4157, 4158, 4159,
4160, 4161, 4162, 4163, 4164, 4165, 4166, 4167, 4168, 4169, 4170, 4171, 4172, 4173, 4174, 4175, 4176, 4177, 4178, 4179, 4180, 4181, 4182, 4183, 4184, 4185, 4186, 4186, 4187, 4188, 4189, 4190,
4191, 4192, 4193, 4194, 4195, 4196, 4197, 4198, 4199, 4200, 4201, 4202, 4203, 4204, 4205, 4206, 4207, 4208, 4209, 4210, 4211, 4212, 4213, 4214, 4215, 4216, 4217, 4218, 4219, 4220, 4221, 4222,
4223, 4224, 4224, 4225, 4226, 4227, 4228, 4229, 4230, 4231, 4232, 4233, 4234, 4235, 4236, 4237, 4238, 4239, 4240, 4241, 4242, 4243, 4244, 4245, 4246, 4247, 4248, 4249, 4250, 4251, 4252, 4252,
4253, 4254, 4255, 4256, 4257, 4258, 4259, 4260, 4261, 4262, 4263, 4264, 4265, 4266, 4267, 4268, 4269, 4270, 4271, 4272, 4273, 4274, 4275, 4276, 4277, 4277, 4278, 4279, 4280, 4281, 4282, 4283,
4284, 4285, 4286, 4287, 4288, 4289, 4290, 4291, 4292, 4293, 4294, 4295, 4296, 4297, 4298, 4298, 4299, 4300, 4301, 4302, 4303, 4304, 4305, 4306, 4307, 4308, 4309, 4310, 4311, 4312, 4313, 4314,
4315, 4316, 4317, 4317, 4318, 4319, 4320, 4321, 4322, 4323, 4324, 4325, 4326, 4327, 4328, 4329, 4330, 4331, 4332, 4333, 4334, 4335, 4335, 4336, 4337, 4338, 4339, 4340, 4341, 4342, 4343, 4344,
4345, 4346, 4347, 4348, 4349, 4350, 4351, 4352, 4352, 4353, 4354, 4355, 4356, 4357, 4358, 4359, 4360, 4361, 4362, 4363, 4364, 4365, 4366, 4367, 4367, 4368, 4369, 4370, 4371, 4372, 4373, 4374,
4375, 4376, 4377, 4378, 4379, 4380, 4381, 4382, 4382, 4383, 4384, 4385, 4386, 4387, 4388, 4389, 4390, 4391, 4392, 4393, 4394, 4395, 4396, 4396, 4397, 4398, 4399, 4400, 4401, 4402, 4403, 4404,
4405, 4406, 4407, 4408, 4409, 4409, 4410, 4411, 4412, 4413, 4414, 4415, 4416, 4417, 4418, 4419, 4420, 4421, 4422, 4422, 4423, 4424, 4425, 4426, 4427, 4428, 4429, 4430, 4431, 4432, 4433, 4434,
4434, 4435, 4436, 4437, 4438, 4439, 4440, 4441, 4442, 4443, 4444, 4445, 4446, 4446, 4447, 4448, 4449, 4450, 4451, 4452, 4453, 4454, 4455, 4456, 4457, 4458, 4458, 4459, 4460, 4461, 4462, 4463,
4464, 4465, 4466, 4467, 4468, 4469, 4469, 4470, 4471, 4472, 4473, 4474, 4475, 4476, 4477, 4478, 4479, 4480, 4480, 4481, 4482, 4483, 4484, 4485, 4486, 4487, 4488, 4489, 4490, 4490, 4491, 4492,
4493, 4494, 4495, 4496, 4497, 4498, 4499, 4500, 4500, 4501, 4502, 4503, 4504, 4505, 4506, 4507, 4508, 4509, 4510, 4510, 4511, 4512, 4513, 4514, 4515, 4516, 4517, 4518, 4519, 4520, 4520, 4521,
4522, 4523, 4524, 4525, 4526, 4527, 4528, 4529, 4530, 4530, 4531, 4532, 4533, 4534, 4535, 4536, 4537, 4538, 4539, 4539, 4540, 4541, 4542, 4543, 4544, 4545, 4546, 4547, 4548, 4548, 4549, 4550,
4551, 4552, 4553, 4554, 4555, 4556, 4557, 4557, 4558, 4559, 4560, 4561, 4562, 4563, 4564, 4565, 4566, 4566, 4567, 4568, 4569, 4570, 4571, 4572, 4573, 4574, 4574, 4575, 4576, 4577, 4578, 4579,
4580, 4581, 4582, 4583, 4583, 4584, 4585, 4586, 4587, 4588, 4589, 4590, 4591, 4591, 4592, 4593, 4594, 4595, 4596, 4597, 4598, 4599, 4599, 4600, 4601, 4602, 4603, 4604, 4605, 4606, 4607, 4608,
4608, 4609, 4610, 4611, 4612, 4613, 4614, 4615, 4615, 4616, 4617, 4618, 4619, 4620, 4621, 4622, 4623, 4623, 4624, 4625, 4626, 4627, 4628, 4629, 4630, 4631, 4631, 4632, 4633, 4634, 4635, 4636,
4637, 4638, 4639, 4639, 4640, 4641, 4642, 4643, 4644, 4645, 4646, 4646, 4647, 4648, 4649, 4650, 4651, 4652, 4653, 4653, 4654, 4655, 4656, 4657, 4658, 4659, 4660, 4661, 4661, 4662, 4663, 4664,
4665, 4666, 4667, 4668, 4668, 4669, 4670, 4671, 4672, 4673, 4674, 4675, 4675, 4676, 4677, 4678, 4679, 4680, 4681, 4682, 4682, 4683, 4684, 4685, 4686, 4687, 4688, 4689, 4689, 4690, 4691, 4692,
4693, 4694, 4695, 4696, 4696, 4697, 4698, 4699, 4700, 4701, 4702, 4703, 4703, 4704, 4705, 4706, 4707, 4708, 4709, 4709, 4710, 4711, 4712, 4713, 4714, 4715, 4716, 4716, 4717, 4718, 4719, 4720,
4721, 4722, 4723, 4723, 4724, 4725, 4726, 4727, 4728, 4729, 4729, 4730, 4731, 4732, 4733, 4734, 4735, 4736, 4736, 4737, 4738, 4739, 4740, 4741, 4742, 4742, 4743, 4744, 4745, 4746, 4747, 4748,
4748, 4749, 4750, 4751, 4752, 4753, 4754, 4754, 4755, 4756, 4757, 4758, 4759, 4760, 4761, 4761, 4762, 4763, 4764, 4765, 4766, 4767, 4767, 4768, 4769, 4770, 4771, 4772, 4773, 4773, 4774, 4775,
4776, 4777, 4778, 4779, 4779, 4780, 4781, 4782, 4783, 4784, 4785, 4785, 4786, 4787, 4788, 4789, 4790, 4791, 4791, 4792, 4793, 4794, 4795, 4796, 4797, 4797, 4798, 4799, 4800, 4801, 4802, 4802,
4803, 4804, 4805, 4806, 4807, 4808, 4808, 4809, 4810, 4811, 4812, 4813, 4814, 4814, 4815, 4816, 4817, 4818, 4819, 4820, 4820, 4821, 4822, 4823, 4824, 4825, 4825, 4826, 4827, 4828, 4829, 4830,
4831, 4831, 4832, 4833, 4834, 4835, 4836, 4836, 4837, 4838, 4839, 4840, 4841, 4842, 4842, 4843, 4844, 4845, 4846, 4847, 4847, 4848, 4849, 4850, 4851, 4852, 4853, 4853, 4854, 4855, 4856, 4857,
4858, 4858, 4859, 4860, 4861, 4862, 4863, 4864, 4864, 4865, 4866, 4867, 4868, 4869, 4869, 4870, 4871, 4872, 4873, 4874, 4874, 4875, 4876, 4877, 4878, 4879, 4879, 4880, 4881, 4882, 4883, 4884,
4885, 4885, 4886, 4887, 4888, 4889, 4890, 4890, 4891, 4892, 4893, 4894, 4895, 4895, 4896, 4897, 4898, 4899, 4900, 4900, 4901, 4902, 4903, 4904, 4905, 4905, 4906, 4907, 4908, 4909, 4910, 4910,
4911, 4912, 4913, 4914, 4915, 4915, 4916, 4917, 4918, 4919, 4920, 4920, 4921, 4922, 4923, 4924, 4925, 4925, 4926, 4927, 4928, 4929, 4930, 4930, 4931, 4932, 4933, 4934, 4935, 4935, 4936, 4937,
4938, 4939, 4940, 4940, 4941, 4942, 4943, 4944, 4945, 4945, 4946, 4947, 4948, 4949, 4949, 4950, 4951, 4952, 4953, 4954, 4954, 4955, 4956, 4957, 4958, 4959, 4959, 4960, 4961, 4962, 4963, 4964,
4964, 4965, 4966, 4967, 4968, 4968, 4969, 4970, 4971, 4972, 4973, 4973, 4974, 4975, 4976, 4977, 4978, 4978, 4979, 4980, 4981, 4982, 4982, 4983, 4984, 4985, 4986, 4987, 4987, 4988, 4989, 4990,
4991, 4992, 4992, 4993, 4994, 4995, 4996, 4996, 4997, 4998, 4999, 5000, 5001, 5001, 5002, 5003, 5004, 5005, 5005, 5006, 5007, 5008, 5009, 5010, 5010, 5011, 5012, 5013, 5014, 5014, 5015, 5016,
5017, 5018, 5019, 5019, 5020, 5021, 5022, 5023, 5023, 5024, 5025, 5026, 5027, 5027, 5028, 5029, 5030, 5031, 5032, 5032, 5033, 5034, 5035, 5036, 5036, 5037, 5038, 5039, 5040, 5040, 5041, 5042,
5043, 5044, 5045, 5045, 5046, 5047, 5048, 5049, 5049, 5050, 5051, 5052, 5053, 5053, 5054, 5055, 5056, 5057, 5058, 5058, 5059, 5060, 5061, 5062, 5062, 5063, 5064, 5065, 5066, 5066, 5067, 5068,
5069, 5070, 5070, 5071, 5072, 5073, 5074, 5075, 5075, 5076, 5077, 5078, 5079, 5079, 5080, 5081, 5082, 5083, 5083, 5084, 5085, 5086, 5087, 5087, 5088, 5089, 5090, 5091, 5091, 5092, 5093, 5094,
5095, 5095, 5096, 5097, 5098, 5099, 5099, 5100, 5101, 5102, 5103, 5103, 5104, 5105, 5106, 5107, 5107, 5108, 5109, 5110, 5111, 5111, 5112, 5113, 5114, 5115, 5115, 5116, 5117, 5118, 5119, 5120,
5120, 5121, 5122, 5123, 5123, 5124, 5125, 5126, 5127, 5127, 5128, 5129, 5130, 5131, 5131, 5132, 5133, 5134, 5135, 5135, 5136, 5137, 5138, 5139, 5139, 5140, 5141, 5142, 5143, 5143, 5144, 5145,
5146, 5147, 5147, 5148, 5149, 5150, 5151, 5151, 5152, 5153, 5154, 5155, 5155, 5156, 5157, 5158, 5159, 5159, 5160, 5161, 5162, 5163, 5163, 5164, 5165, 5166, 5166, 5167, 5168, 5169, 5170, 5170,
5171, 5172, 5173, 5174, 5174, 5175, 5176, 5177, 5178, 5178, 5179, 5180, 5181, 5182, 5182, 5183, 5184, 5185, 5185, 5186, 5187, 5188, 5189, 5189, 5190, 5191, 5192, 5193, 5193, 5194, 5195, 5196,
5197, 5197, 5198, 5199, 5200, 5200, 5201, 5202, 5203, 5204, 5204, 5205, 5206, 5207, 5208, 5208, 5209, 5210, 5211, 5211, 5212, 5213, 5214, 5215, 5215, 5216, 5217, 5218, 5219, 5219, 5220, 5221,
5222, 5222, 5223, 5224, 5225, 5226, 5226, 5227, 5228, 5229, 5230, 5230, 5231, 5232, 5233, 5233, 5234, 5235, 5236, 5237, 5237, 5238, 5239, 5240, 5240, 5241, 5242, 5243, 5244, 5244, 5245, 5246,
5247, 5248, 5248, 5249, 5250, 5251, 5251, 5252, 5253, 5254, 5255, 5255, 5256, 5257, 5258, 5258, 5259, 5260, 5261, 5262, 5262, 5263, 5264, 5265, 5265, 5266, 5267, 5268, 5269, 5269, 5270, 5271,
5272, 5272, 5273, 5274, 5275, 5276, 5276, 5277, 5278, 5279, 5279, 5280, 5281, 5282, 5283, 5283, 5284, 5285, 5286, 5286, 5287, 5288, 5289, 5289, 5290, 5291, 5292, 5293, 5293, 5294, 5295, 5296,
5296, 5297, 5298, 5299, 5300, 5300, 5301, 5302, 5303, 5303, 5304, 5305, 5306, 5306, 5307, 5308, 5309, 5310, 5310, 5311, 5312, 5313, 5313, 5314, 5315, 5316, 5317, 5317, 5318, 5319, 5320, 5320,
5321, 5322, 5323, 5323, 5324, 5325, 5326, 5327, 5327, 5328, 5329, 5330, 5330, 5331, 5332, 5333, 5333, 5334, 5335, 5336, 5337, 5337, 5338, 5339, 5340, 5340, 5341, 5342, 5343, 5343, 5344, 5345,
5346, 5346, 5347, 5348, 5349, 5350, 5350, 5351, 5352, 5353, 5353, 5354, 5355, 5356, 5356, 5357, 5358, 5359, 5359, 5360, 5361, 5362, 5363, 5363, 5364, 5365, 5366, 5366, 5367, 5368, 5369, 5369,
5370, 5371, 5372, 5372, 5373, 5374, 5375, 5376, 5376, 5377, 5378, 5379, 5379, 5380, 5381, 5382, 5382, 5383, 5384, 5385, 5385, 5386, 5387, 5388, 5388, 5389, 5390, 5391, 5391, 5392, 5393, 5394,
5395, 5395, 5396, 5397, 5398, 5398, 5399, 5400, 5401, 5401, 5402, 5403, 5404, 5404, 5405, 5406, 5407, 5407, 5408, 5409, 5410, 5410, 5411, 5412, 5413, 5413, 5414, 5415, 5416, 5416, 5417, 5418,
5419, 5420, 5420, 5421, 5422, 5423, 5423, 5424, 5425, 5426, 5426, 5427, 5428, 5429, 5429, 5430, 5431, 5432, 5432, 5433, 5434, 5435, 5435, 5436, 5437, 5438, 5438, 5439, 5440, 5441, 5441, 5442,
5443, 5444, 5444, 5445, 5446, 5447, 5447, 5448, 5449, 5450, 5450, 5451, 5452, 5453, 5453, 5454, 5455, 5456, 5456, 5457, 5458, 5459, 5459, 5460, 5461, 5462, 5462, 5463, 5464, 5465, 5465, 5466,
5467, 5468, 5468, 5469, 5470, 5471, 5471, 5472, 5473, 5474, 5474, 5475, 5476, 5477, 5477, 5478, 5479, 5480, 5480, 5481, 5482, 5483, 5483, 5484, 5485, 5486, 5486, 5487, 5488, 5489, 5489, 5490,
5491, 5492, 5492, 5493, 5494, 5495, 5495, 5496, 5497, 5498, 5498, 5499, 5500, 5501, 5501, 5502, 5503, 5504, 5504, 5505, 5506, 5506, 5507, 5508, 5509, 5509, 5510, 5511, 5512, 5512, 5513, 5514,
5515, 5515, 5516, 5517, 5518, 5518, 5519, 5520, 5521, 5521, 5522, 5523, 5524, 5524, 5525, 5526, 5527, 5527, 5528, 5529, 5529, 5530, 5531, 5532, 5532, 5533, 5534, 5535, 5535, 5536, 5537, 5538,
5538, 5539, 5540, 5541, 5541, 5542, 5543, 5544, 5544, 5545, 5546, 5546, 5547, 5548, 5549, 5549, 5550, 5551, 5552, 5552, 5553, 5554, 5555, 5555, 5556, 5557, 5558, 5558, 5559, 5560, 5561, 5561,
5562, 5563, 5563, 5564, 5565, 5566, 5566, 5567, 5568, 5569, 5569, 5570, 5571, 5572, 5572, 5573, 5574, 5574, 5575, 5576, 5577, 5577, 5578, 5579, 5580, 5580, 5581, 5582, 5583, 5583, 5584, 5585,
5585, 5586, 5587, 5588, 5588, 5589, 5590, 5591, 5591, 5592, 5593, 5594, 5594, 5595, 5596, 5596, 5597, 5598, 5599, 5599, 5600, 5601, 5602, 5602, 5603, 5604, 5605, 5605, 5606, 5607, 5607, 5608,
5609, 5610, 5610, 5611, 5612, 5613, 5613, 5614, 5615, 5615, 5616, 5617, 5618, 5618, 5619, 5620, 5621, 5621, 5622, 5623, 5623, 5624, 5625, 5626, 5626, 5627, 5628, 5629, 5629, 5630, 5631, 5632,
5632, 5633, 5634, 5634, 5635, 5636, 5637, 5637, 5638, 5639, 5639, 5640, 5641, 5642, 5642, 5643, 5644, 5645, 5645, 5646, 5647, 5647, 5648, 5649, 5650, 5650, 5651, 5652, 5653, 5653, 5654, 5655,
5655, 5656, 5657, 5658, 5658, 5659, 5660, 5661, 5661, 5662, 5663, 5663, 5664, 5665, 5666, 5666, 5667, 5668, 5668, 5669, 5670, 5671, 5671, 5672, 5673, 5674, 5674, 5675, 5676, 5676, 5677, 5678,
5679, 5679, 5680, 5681, 5681, 5682, 5683, 5684, 5684, 5685, 5686, 5687, 5687, 5688, 5689, 5689, 5690, 5691, 5692, 5692, 5693, 5694, 5694, 5695, 5696, 5697, 5697, 5698, 5699, 5699, 5700, 5701,
5702, 5702, 5703, 5704, 5704, 5705, 5706, 5707, 5707, 5708, 5709, 5710, 5710, 5711, 5712, 5712, 5713, 5714, 5715, 5715, 5716, 5717, 5717, 5718, 5719, 5720, 5720, 5721, 5722, 5722, 5723, 5724,
5725, 5725, 5726, 5727, 5727, 5728, 5729, 5730, 5730, 5731, 5732, 5732, 5733, 5734, 5735, 5735, 5736, 5737, 5737, 5738, 5739, 5740, 5740, 5741, 5742, 5742, 5743, 5744, 5745, 5745, 5746, 5747,
5747, 5748, 5749, 5750, 5750, 5751, 5752, 5752, 5753, 5754, 5755, 5755, 5756, 5757, 5757, 5758, 5759, 5760, 5760, 5761, 5762, 5762, 5763, 5764, 5764, 5765, 5766, 5767, 5767, 5768, 5769, 5769,
5770, 5771, 5772, 5772, 5773, 5774, 5774, 5775, 5776, 5777, 5777, 5778, 5779, 5779, 5780, 5781, 5782, 5782, 5783, 5784, 5784, 5785, 5786, 5786, 5787, 5788, 5789, 5789, 5790, 5791, 5791, };
static const s16 sqrtLUT3[SQRTPRECISION]=
{0, 64, 90, 110, 128, 143, 156, 169, 181, 192, 202, 212, 221, 230, 239, 247, 256, 263, 271, 278, 286, 293, 300, 306, 313, 320, 326, 332, 338, 344, 350, 356, 362, 367, 373, 378, 384, 389, 394, 399, 404, 409, 414, 419, 424, 429, 434, 438, 443, 448, 452, 457, 461, 465, 470, 474, 478, 483, 487, 491, 495, 499, 503, 507, 512,
515, 519, 523, 527, 531, 535, 539, 543, 546, 550, 554, 557, 561, 565, 568, 572, 576, 579, 583, 586, 590, 593, 596, 600, 603, 607, 610, 613, 617, 620, 623, 627, 630, 633, 636, 640, 643, 646, 649, 652, 655, 658, 662, 665, 668, 671, 674, 677, 680, 683, 686, 689, 692, 695, 698, 701, 704, 706, 709, 712, 715, 718, 721, 724,
726, 729, 732, 735, 738, 740, 743, 746, 749, 751, 754, 757, 759, 762, 765, 768, 770, 773, 775, 778, 781, 783, 786, 789, 791, 794, 796, 799, 801, 804, 807, 809, 812, 814, 817, 819, 822, 824, 827, 829, 832, 834, 836, 839, 841, 844, 846, 849, 851, 853, 856, 858, 861, 863, 865, 868, 870, 872, 875, 877, 879, 882, 884, 886,
889, 891, 893, 896, 898, 900, 902, 905, 907, 909, 911, 914, 916, 918, 920, 923, 925, 927, 929, 931, 934, 936, 938, 940, 942, 944, 947, 949, 951, 953, 955, 957, 960, 962, 964, 966, 968, 970, 972, 974, 976, 979, 981, 983, 985, 987, 989, 991, 993, 995, 997, 999, 1001, 1003, 1005, 1007, 1009, 1011, 1013, 1015, 1017, 1019, 1021, 1024,
1025, 1027, 1029, 1031, 1033, 1035, 1037, 1039, 1041, 1043, 1045, 1047, 1049, 1051, 1053, 1055, 1057, 1059, 1061, 1063, 1065, 1067, 1069, 1070, 1072, 1074, 1076, 1078, 1080, 1082, 1084, 1086, 1088, 1089, 1091, 1093, 1095, 1097, 1099, 1101, 1102, 1104, 1106, 1108, 1110, 1112, 1114, 1115, 1117, 1119, 1121, 1123, 1125, 1126, 1128, 1130, 1132, 1134, 1135, 1137, 1139, 1141, 1143, 1144,
1146, 1148, 1150, 1152, 1153, 1155, 1157, 1159, 1160, 1162, 1164, 1166, 1167, 1169, 1171, 1173, 1174, 1176, 1178, 1180, 1181, 1183, 1185, 1187, 1188, 1190, 1192, 1193, 1195, 1197, 1199, 1200, 1202, 1204, 1205, 1207, 1209, 1210, 1212, 1214, 1216, 1217, 1219, 1221, 1222, 1224, 1226, 1227, 1229, 1231, 1232, 1234, 1236, 1237, 1239, 1241, 1242, 1244, 1245, 1247, 1249, 1250, 1252, 1254,
1255, 1257, 1259, 1260, 1262, 1263, 1265, 1267, 1268, 1270, 1271, 1273, 1275, 1276, 1278, 1280, 1281, 1283, 1284, 1286, 1287, 1289, 1291, 1292, 1294, 1295, 1297, 1299, 1300, 1302, 1303, 1305, 1306, 1308, 1310, 1311, 1313, 1314, 1316, 1317, 1319, 1320, 1322, 1324, 1325, 1327, 1328, 1330, 1331, 1333, 1334, 1336, 1337, 1339, 1340, 1342, 1344, 1345, 1347, 1348, 1350, 1351, 1353, 1354,
1356, 1357, 1359, 1360, 1362, 1363, 1365, 1366, 1368, 1369, 1371, 1372, 1374, 1375, 1377, 1378, 1380, 1381, 1383, 1384, 1386, 1387, 1388, 1390, 1391, 1393, 1394, 1396, 1397, 1399, 1400, 1402, 1403, 1405, 1406, 1408, 1409, 1410, 1412, 1413, 1415, 1416, 1418, 1419, 1421, 1422, 1423, 1425, 1426, 1428, 1429, 1431, 1432, 1433, 1435, 1436, 1438, 1439, 1441, 1442, 1443, 1445, 1446, 1448,
1449, 1450, 1452, 1453, 1455, 1456, 1458, 1459, 1460, 1462, 1463, 1465, 1466, 1467, 1469, 1470, 1472, 1473, 1474, 1476, 1477, 1478, 1480, 1481, 1483, 1484, 1485, 1487, 1488, 1489, 1491, 1492, 1494, 1495, 1496, 1498, 1499, 1500, 1502, 1503, 1505, 1506, 1507, 1509, 1510, 1511, 1513, 1514, 1515, 1517, 1518, 1519, 1521, 1522, 1523, 1525, 1526, 1527, 1529, 1530, 1531, 1533, 1534, 1536,
1537, 1538, 1539, 1541, 1542, 1543, 1545, 1546, 1547, 1549, 1550, 1551, 1553, 1554, 1555, 1557, 1558, 1559, 1561, 1562, 1563, 1565, 1566, 1567, 1568, 1570, 1571, 1572, 1574, 1575, 1576, 1578, 1579, 1580, 1581, 1583, 1584, 1585, 1587, 1588, 1589, 1591, 1592, 1593, 1594, 1596, 1597, 1598, 1600, 1601, 1602, 1603, 1605, 1606, 1607, 1608, 1610, 1611, 1612, 1614, 1615, 1616, 1617, 1619,
1620, 1621, 1622, 1624, 1625, 1626, 1627, 1629, 1630, 1631, 1632, 1634, 1635, 1636, 1637, 1639, 1640, 1641, 1642, 1644, 1645, 1646, 1647, 1649, 1650, 1651, 1652, 1654, 1655, 1656, 1657, 1659, 1660, 1661, 1662, 1664, 1665, 1666, 1667, 1668, 1670, 1671, 1672, 1673, 1675, 1676, 1677, 1678, 1679, 1681, 1682, 1683, 1684, 1686, 1687, 1688, 1689, 1690, 1692, 1693, 1694, 1695, 1696, 1698,
1699, 1700, 1701, 1702, 1704, 1705, 1706, 1707, 1708, 1710, 1711, 1712, 1713, 1714, 1716, 1717, 1718, 1719, 1720, 1722, 1723, 1724, 1725, 1726, 1728, 1729, 1730, 1731, 1732, 1733, 1735, 1736, 1737, 1738, 1739, 1740, 1742, 1743, 1744, 1745, 1746, 1748, 1749, 1750, 1751, 1752, 1753, 1755, 1756, 1757, 1758, 1759, 1760, 1762, 1763, 1764, 1765, 1766, 1767, 1768, 1770, 1771, 1772, 1773,
1774, 1775, 1777, 1778, 1779, 1780, 1781, 1782, 1783, 1785, 1786, 1787, 1788, 1789, 1790, 1792, 1793, 1794, 1795, 1796, 1797, 1798, 1799, 1801, 1802, 1803, 1804, 1805, 1806, 1807, 1809, 1810, 1811, 1812, 1813, 1814, 1815, 1816, 1818, 1819, 1820, 1821, 1822, 1823, 1824, 1825, 1827, 1828, 1829, 1830, 1831, 1832, 1833, 1834, 1836, 1837, 1838, 1839, 1840, 1841, 1842, 1843, 1844, 1846,
1847, 1848, 1849, 1850, 1851, 1852, 1853, 1854, 1856, 1857, 1858, 1859, 1860, 1861, 1862, 1863, 1864, 1865, 1867, 1868, 1869, 1870, 1871, 1872, 1873, 1874, 1875, 1876, 1877, 1879, 1880, 1881, 1882, 1883, 1884, 1885, 1886, 1887, 1888, 1889, 1890, 1892, 1893, 1894, 1895, 1896, 1897, 1898, 1899, 1900, 1901, 1902, 1903, 1905, 1906, 1907, 1908, 1909, 1910, 1911, 1912, 1913, 1914, 1915,
1916, 1917, 1918, 1920, 1921, 1922, 1923, 1924, 1925, 1926, 1927, 1928, 1929, 1930, 1931, 1932, 1933, 1934, 1935, 1936, 1938, 1939, 1940, 1941, 1942, 1943, 1944, 1945, 1946, 1947, 1948, 1949, 1950, 1951, 1952, 1953, 1954, 1955, 1956, 1958, 1959, 1960, 1961, 1962, 1963, 1964, 1965, 1966, 1967, 1968, 1969, 1970, 1971, 1972, 1973, 1974, 1975, 1976, 1977, 1978, 1979, 1980, 1981, 1982,
1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025, 2026, 2027, 2028, 2029, 2030, 2031, 2032, 2033, 2034, 2035, 2036, 2037, 2038, 2039, 2040, 2041, 2042, 2043, 2044, 2045, 2046, 2048,
2048, 2049, 2050, 2051, 2052, 2053, 2054, 2055, 2056, 2057, 2058, 2059, 2060, 2061, 2062, 2063, 2064, 2065, 2066, 2067, 2068, 2069, 2070, 2071, 2072, 2073, 2074, 2075, 2076, 2077, 2078, 2079, 2080, 2081, 2082, 2083, 2084, 2085, 2086, 2087, 2088, 2089, 2090, 2091, 2092, 2093, 2094, 2095, 2096, 2097, 2098, 2099, 2100, 2101, 2102, 2103, 2104, 2105, 2106, 2107, 2108, 2109, 2110, 2111,
2112, 2112, 2113, 2114, 2115, 2116, 2117, 2118, 2119, 2120, 2121, 2122, 2123, 2124, 2125, 2126, 2127, 2128, 2129, 2130, 2131, 2132, 2133, 2134, 2135, 2136, 2137, 2138, 2138, 2139, 2140, 2141, 2142, 2143, 2144, 2145, 2146, 2147, 2148, 2149, 2150, 2151, 2152, 2153, 2154, 2155, 2156, 2157, 2158, 2158, 2159, 2160, 2161, 2162, 2163, 2164, 2165, 2166, 2167, 2168, 2169, 2170, 2171, 2172,
2173, 2174, 2175, 2176, 2176, 2177, 2178, 2179, 2180, 2181, 2182, 2183, 2184, 2185, 2186, 2187, 2188, 2189, 2190, 2191, 2191, 2192, 2193, 2194, 2195, 2196, 2197, 2198, 2199, 2200, 2201, 2202, 2203, 2204, 2204, 2205, 2206, 2207, 2208, 2209, 2210, 2211, 2212, 2213, 2214, 2215, 2216, 2217, 2217, 2218, 2219, 2220, 2221, 2222, 2223, 2224, 2225, 2226, 2227, 2228, 2229, 2229, 2230, 2231,
2232, 2233, 2234, 2235, 2236, 2237, 2238, 2239, 2240, 2240, 2241, 2242, 2243, 2244, 2245, 2246, 2247, 2248, 2249, 2250, 2250, 2251, 2252, 2253, 2254, 2255, 2256, 2257, 2258, 2259, 2260, 2260, 2261, 2262, 2263, 2264, 2265, 2266, 2267, 2268, 2269, 2269, 2270, 2271, 2272, 2273, 2274, 2275, 2276, 2277, 2278, 2278, 2279, 2280, 2281, 2282, 2283, 2284, 2285, 2286, 2287, 2287, 2288, 2289,
2290, 2291, 2292, 2293, 2294, 2295, 2295, 2296, 2297, 2298, 2299, 2300, 2301, 2302, 2303, 2304, 2304, 2305, 2306, 2307, 2308, 2309, 2310, 2311, 2311, 2312, 2313, 2314, 2315, 2316, 2317, 2318, 2319, 2319, 2320, 2321, 2322, 2323, 2324, 2325, 2326, 2326, 2327, 2328, 2329, 2330, 2331, 2332, 2333, 2334, 2334, 2335, 2336, 2337, 2338, 2339, 2340, 2341, 2341, 2342, 2343, 2344, 2345, 2346,
2347, 2348, 2348, 2349, 2350, 2351, 2352, 2353, 2354, 2354, 2355, 2356, 2357, 2358, 2359, 2360, 2361, 2361, 2362, 2363, 2364, 2365, 2366, 2367, 2368, 2368, 2369, 2370, 2371, 2372, 2373, 2374, 2374, 2375, 2376, 2377, 2378, 2379, 2380, 2380, 2381, 2382, 2383, 2384, 2385, 2386, 2386, 2387, 2388, 2389, 2390, 2391, 2392, 2392, 2393, 2394, 2395, 2396, 2397, 2398, 2398, 2399, 2400, 2401,
2402, 2403, 2404, 2404, 2405, 2406, 2407, 2408, 2409, 2410, 2410, 2411, 2412, 2413, 2414, 2415, 2415, 2416, 2417, 2418, 2419, 2420, 2421, 2421, 2422, 2423, 2424, 2425, 2426, 2426, 2427, 2428, 2429, 2430, 2431, 2432, 2432, 2433, 2434, 2435, 2436, 2437, 2437, 2438, 2439, 2440, 2441, 2442, 2442, 2443, 2444, 2445, 2446, 2447, 2447, 2448, 2449, 2450, 2451, 2452, 2452, 2453, 2454, 2455,
2456, 2457, 2457, 2458, 2459, 2460, 2461, 2462, 2462, 2463, 2464, 2465, 2466, 2467, 2467, 2468, 2469, 2470, 2471, 2472, 2472, 2473, 2474, 2475, 2476, 2477, 2477, 2478, 2479, 2480, 2481, 2482, 2482, 2483, 2484, 2485, 2486, 2486, 2487, 2488, 2489, 2490, 2491, 2491, 2492, 2493, 2494, 2495, 2496, 2496, 2497, 2498, 2499, 2500, 2500, 2501, 2502, 2503, 2504, 2505, 2505, 2506, 2507, 2508,
2509, 2509, 2510, 2511, 2512, 2513, 2513, 2514, 2515, 2516, 2517, 2518, 2518, 2519, 2520, 2521, 2522, 2522, 2523, 2524, 2525, 2526, 2526, 2527, 2528, 2529, 2530, 2531, 2531, 2532, 2533, 2534, 2535, 2535, 2536, 2537, 2538, 2539, 2539, 2540, 2541, 2542, 2543, 2543, 2544, 2545, 2546, 2547, 2547, 2548, 2549, 2550, 2551, 2551, 2552, 2553, 2554, 2555, 2555, 2556, 2557, 2558, 2559, 2560,
2560, 2561, 2562, 2563, 2563, 2564, 2565, 2566, 2567, 2567, 2568, 2569, 2570, 2571, 2571, 2572, 2573, 2574, 2575, 2575, 2576, 2577, 2578, 2579, 2579, 2580, 2581, 2582, 2583, 2583, 2584, 2585, 2586, 2587, 2587, 2588, 2589, 2590, 2591, 2591, 2592, 2593, 2594, 2594, 2595, 2596, 2597, 2598, 2598, 2599, 2600, 2601, 2602, 2602, 2603, 2604, 2605, 2605, 2606, 2607, 2608, 2609, 2609, 2610,
2611, 2612, 2613, 2613, 2614, 2615, 2616, 2616, 2617, 2618, 2619, 2620, 2620, 2621, 2622, 2623, 2624, 2624, 2625, 2626, 2627, 2627, 2628, 2629, 2630, 2631, 2631, 2632, 2633, 2634, 2634, 2635, 2636, 2637, 2638, 2638, 2639, 2640, 2641, 2641, 2642, 2643, 2644, 2644, 2645, 2646, 2647, 2648, 2648, 2649, 2650, 2651, 2651, 2652, 2653, 2654, 2655, 2655, 2656, 2657, 2658, 2658, 2659, 2660,
2661, 2661, 2662, 2663, 2664, 2665, 2665, 2666, 2667, 2668, 2668, 2669, 2670, 2671, 2671, 2672, 2673, 2674, 2675, 2675, 2676, 2677, 2678, 2678, 2679, 2680, 2681, 2681, 2682, 2683, 2684, 2684, 2685, 2686, 2687, 2688, 2688, 2689, 2690, 2691, 2691, 2692, 2693, 2694, 2694, 2695, 2696, 2697, 2697, 2698, 2699, 2700, 2700, 2701, 2702, 2703, 2703, 2704, 2705, 2706, 2706, 2707, 2708, 2709,
2710, 2710, 2711, 2712, 2713, 2713, 2714, 2715, 2716, 2716, 2717, 2718, 2719, 2719, 2720, 2721, 2722, 2722, 2723, 2724, 2725, 2725, 2726, 2727, 2728, 2728, 2729, 2730, 2731, 2731, 2732, 2733, 2734, 2734, 2735, 2736, 2737, 2737, 2738, 2739, 2740, 2740, 2741, 2742, 2743, 2743, 2744, 2745, 2746, 2746, 2747, 2748, 2749, 2749, 2750, 2751, 2752, 2752, 2753, 2754, 2754, 2755, 2756, 2757,
2757, 2758, 2759, 2760, 2760, 2761, 2762, 2763, 2763, 2764, 2765, 2766, 2766, 2767, 2768, 2769, 2769, 2770, 2771, 2772, 2772, 2773, 2774, 2774, 2775, 2776, 2777, 2777, 2778, 2779, 2780, 2780, 2781, 2782, 2783, 2783, 2784, 2785, 2786, 2786, 2787, 2788, 2788, 2789, 2790, 2791, 2791, 2792, 2793, 2794, 2794, 2795, 2796, 2797, 2797, 2798, 2799, 2799, 2800, 2801, 2802, 2802, 2803, 2804,
2805, 2805, 2806, 2807, 2807, 2808, 2809, 2810, 2810, 2811, 2812, 2813, 2813, 2814, 2815, 2816, 2816, 2817, 2818, 2818, 2819, 2820, 2821, 2821, 2822, 2823, 2823, 2824, 2825, 2826, 2826, 2827, 2828, 2829, 2829, 2830, 2831, 2831, 2832, 2833, 2834, 2834, 2835, 2836, 2837, 2837, 2838, 2839, 2839, 2840, 2841, 2842, 2842, 2843, 2844, 2844, 2845, 2846, 2847, 2847, 2848, 2849, 2849, 2850,
2851, 2852, 2852, 2853, 2854, 2855, 2855, 2856, 2857, 2857, 2858, 2859, 2860, 2860, 2861, 2862, 2862, 2863, 2864, 2865, 2865, 2866, 2867, 2867, 2868, 2869, 2870, 2870, 2871, 2872, 2872, 2873, 2874, 2875, 2875, 2876, 2877, 2877, 2878, 2879, 2880, 2880, 2881, 2882, 2882, 2883, 2884, 2884, 2885, 2886, 2887, 2887, 2888, 2889, 2889, 2890, 2891, 2892, 2892, 2893, 2894, 2894, 2895, 2896,
2897, 2897, 2898, 2899, 2899, 2900, 2901, 2901, 2902, 2903, 2904, 2904, 2905, 2906, 2906, 2907, 2908, 2909, 2909, 2910, 2911, 2911, 2912, 2913, 2913, 2914, 2915, 2916, 2916, 2917, 2918, 2918, 2919, 2920, 2920, 2921, 2922, 2923, 2923, 2924, 2925, 2925, 2926, 2927, 2927, 2928, 2929, 2930, 2930, 2931, 2932, 2932, 2933, 2934, 2934, 2935, 2936, 2937, 2937, 2938, 2939, 2939, 2940, 2941,
2941, 2942, 2943, 2944, 2944, 2945, 2946, 2946, 2947, 2948, 2948, 2949, 2950, 2950, 2951, 2952, 2953, 2953, 2954, 2955, 2955, 2956, 2957, 2957, 2958, 2959, 2959, 2960, 2961, 2962, 2962, 2963, 2964, 2964, 2965, 2966, 2966, 2967, 2968, 2968, 2969, 2970, 2971, 2971, 2972, 2973, 2973, 2974, 2975, 2975, 2976, 2977, 2977, 2978, 2979, 2979, 2980, 2981, 2982, 2982, 2983, 2984, 2984, 2985,
2986, 2986, 2987, 2988, 2988, 2989, 2990, 2990, 2991, 2992, 2992, 2993, 2994, 2995, 2995, 2996, 2997, 2997, 2998, 2999, 2999, 3000, 3001, 3001, 3002, 3003, 3003, 3004, 3005, 3005, 3006, 3007, 3008, 3008, 3009, 3010, 3010, 3011, 3012, 3012, 3013, 3014, 3014, 3015, 3016, 3016, 3017, 3018, 3018, 3019, 3020, 3020, 3021, 3022, 3022, 3023, 3024, 3024, 3025, 3026, 3027, 3027, 3028, 3029,
3029, 3030, 3031, 3031, 3032, 3033, 3033, 3034, 3035, 3035, 3036, 3037, 3037, 3038, 3039, 3039, 3040, 3041, 3041, 3042, 3043, 3043, 3044, 3045, 3045, 3046, 3047, 3047, 3048, 3049, 3049, 3050, 3051, 3051, 3052, 3053, 3053, 3054, 3055, 3055, 3056, 3057, 3057, 3058, 3059, 3059, 3060, 3061, 3061, 3062, 3063, 3063, 3064, 3065, 3065, 3066, 3067, 3067, 3068, 3069, 3069, 3070, 3071, 3072,
3072, 3073, 3073, 3074, 3075, 3075, 3076, 3077, 3077, 3078, 3079, 3079, 3080, 3081, 3081, 3082, 3083, 3083, 3084, 3085, 3085, 3086, 3087, 3087, 3088, 3089, 3089, 3090, 3091, 3091, 3092, 3093, 3093, 3094, 3095, 3095, 3096, 3097, 3097, 3098, 3099, 3099, 3100, 3101, 3101, 3102, 3103, 3103, 3104, 3105, 3105, 3106, 3107, 3107, 3108, 3109, 3109, 3110, 3111, 3111, 3112, 3113, 3113, 3114,
3115, 3115, 3116, 3117, 3117, 3118, 3118, 3119, 3120, 3120, 3121, 3122, 3122, 3123, 3124, 3124, 3125, 3126, 3126, 3127, 3128, 3128, 3129, 3130, 3130, 3131, 3132, 3132, 3133, 3134, 3134, 3135, 3136, 3136, 3137, 3137, 3138, 3139, 3139, 3140, 3141, 3141, 3142, 3143, 3143, 3144, 3145, 3145, 3146, 3147, 3147, 3148, 3149, 3149, 3150, 3150, 3151, 3152, 3152, 3153, 3154, 3154, 3155, 3156,
3156, 3157, 3158, 3158, 3159, 3160, 3160, 3161, 3162, 3162, 3163, 3163, 3164, 3165, 3165, 3166, 3167, 3167, 3168, 3169, 3169, 3170, 3171, 3171, 3172, 3173, 3173, 3174, 3174, 3175, 3176, 3176, 3177, 3178, 3178, 3179, 3180, 3180, 3181, 3182, 3182, 3183, 3183, 3184, 3185, 3185, 3186, 3187, 3187, 3188, 3189, 3189, 3190, 3191, 3191, 3192, 3192, 3193, 3194, 3194, 3195, 3196, 3196, 3197,
3198, 3198, 3199, 3200, 3200, 3201, 3201, 3202, 3203, 3203, 3204, 3205, 3205, 3206, 3207, 3207, 3208, 3208, 3209, 3210, 3210, 3211, 3212, 3212, 3213, 3214, 3214, 3215, 3215, 3216, 3217, 3217, 3218, 3219, 3219, 3220, 3221, 3221, 3222, 3222, 3223, 3224, 3224, 3225, 3226, 3226, 3227, 3228, 3228, 3229, 3229, 3230, 3231, 3231, 3232, 3233, 3233, 3234, 3235, 3235, 3236, 3236, 3237, 3238,
3238, 3239, 3240, 3240, 3241, 3241, 3242, 3243, 3243, 3244, 3245, 3245, 3246, 3247, 3247, 3248, 3248, 3249, 3250, 3250, 3251, 3252, 3252, 3253, 3253, 3254, 3255, 3255, 3256, 3257, 3257, 3258, 3258, 3259, 3260, 3260, 3261, 3262, 3262, 3263, 3264, 3264, 3265, 3265, 3266, 3267, 3267, 3268, 3269, 3269, 3270, 3270, 3271, 3272, 3272, 3273, 3274, 3274, 3275, 3275, 3276, 3277, 3277, 3278,
3279, 3279, 3280, 3280, 3281, 3282, 3282, 3283, 3284, 3284, 3285, 3285, 3286, 3287, 3287, 3288, 3289, 3289, 3290, 3290, 3291, 3292, 3292, 3293, 3293, 3294, 3295, 3295, 3296, 3297, 3297, 3298, 3298, 3299, 3300, 3300, 3301, 3302, 3302, 3303, 3303, 3304, 3305, 3305, 3306, 3307, 3307, 3308, 3308, 3309, 3310, 3310, 3311, 3311, 3312, 3313, 3313, 3314, 3315, 3315, 3316, 3316, 3317, 3318,
3318, 3319, 3319, 3320, 3321, 3321, 3322, 3323, 3323, 3324, 3324, 3325, 3326, 3326, 3327, 3328, 3328, 3329, 3329, 3330, 3331, 3331, 3332, 3332, 3333, 3334, 3334, 3335, 3335, 3336, 3337, 3337, 3338, 3339, 3339, 3340, 3340, 3341, 3342, 3342, 3343, 3343, 3344, 3345, 3345, 3346, 3347, 3347, 3348, 3348, 3349, 3350, 3350, 3351, 3351, 3352, 3353, 3353, 3354, 3354, 3355, 3356, 3356, 3357,
3358, 3358, 3359, 3359, 3360, 3361, 3361, 3362, 3362, 3363, 3364, 3364, 3365, 3365, 3366, 3367, 3367, 3368, 3368, 3369, 3370, 3370, 3371, 3372, 3372, 3373, 3373, 3374, 3375, 3375, 3376, 3376, 3377, 3378, 3378, 3379, 3379, 3380, 3381, 3381, 3382, 3382, 3383, 3384, 3384, 3385, 3385, 3386, 3387, 3387, 3388, 3388, 3389, 3390, 3390, 3391, 3392, 3392, 3393, 3393, 3394, 3395, 3395, 3396,
3396, 3397, 3398, 3398, 3399, 3399, 3400, 3401, 3401, 3402, 3402, 3403, 3404, 3404, 3405, 3405, 3406, 3407, 3407, 3408, 3408, 3409, 3410, 3410, 3411, 3411, 3412, 3413, 3413, 3414, 3414, 3415, 3416, 3416, 3417, 3417, 3418, 3419, 3419, 3420, 3420, 3421, 3422, 3422, 3423, 3423, 3424, 3425, 3425, 3426, 3426, 3427, 3428, 3428, 3429, 3429, 3430, 3431, 3431, 3432, 3432, 3433, 3434, 3434,
3435, 3435, 3436, 3436, 3437, 3438, 3438, 3439, 3439, 3440, 3441, 3441, 3442, 3442, 3443, 3444, 3444, 3445, 3445, 3446, 3447, 3447, 3448, 3448, 3449, 3450, 3450, 3451, 3451, 3452, 3453, 3453, 3454, 3454, 3455, 3456, 3456, 3457, 3457, 3458, 3458, 3459, 3460, 3460, 3461, 3461, 3462, 3463, 3463, 3464, 3464, 3465, 3466, 3466, 3467, 3467, 3468, 3469, 3469, 3470, 3470, 3471, 3471, 3472,
3473, 3473, 3474, 3474, 3475, 3476, 3476, 3477, 3477, 3478, 3479, 3479, 3480, 3480, 3481, 3481, 3482, 3483, 3483, 3484, 3484, 3485, 3486, 3486, 3487, 3487, 3488, 3489, 3489, 3490, 3490, 3491, 3491, 3492, 3493, 3493, 3494, 3494, 3495, 3496, 3496, 3497, 3497, 3498, 3498, 3499, 3500, 3500, 3501, 3501, 3502, 3503, 3503, 3504, 3504, 3505, 3506, 3506, 3507, 3507, 3508, 3508, 3509, 3510,
3510, 3511, 3511, 3512, 3513, 3513, 3514, 3514, 3515, 3515, 3516, 3517, 3517, 3518, 3518, 3519, 3520, 3520, 3521, 3521, 3522, 3522, 3523, 3524, 3524, 3525, 3525, 3526, 3526, 3527, 3528, 3528, 3529, 3529, 3530, 3531, 3531, 3532, 3532, 3533, 3533, 3534, 3535, 3535, 3536, 3536, 3537, 3537, 3538, 3539, 3539, 3540, 3540, 3541, 3542, 3542, 3543, 3543, 3544, 3544, 3545, 3546, 3546, 3547,
3547, 3548, 3548, 3549, 3550, 3550, 3551, 3551, 3552, 3553, 3553, 3554, 3554, 3555, 3555, 3556, 3557, 3557, 3558, 3558, 3559, 3559, 3560, 3561, 3561, 3562, 3562, 3563, 3563, 3564, 3565, 3565, 3566, 3566, 3567, 3567, 3568, 3569, 3569, 3570, 3570, 3571, 3571, 3572, 3573, 3573, 3574, 3574, 3575, 3575, 3576, 3577, 3577, 3578, 3578, 3579, 3579, 3580, 3581, 3581, 3582, 3582, 3583, 3584,
3584, 3585, 3585, 3586, 3586, 3587, 3587, 3588, 3589, 3589, 3590, 3590, 3591, 3591, 3592, 3593, 3593, 3594, 3594, 3595, 3595, 3596, 3597, 3597, 3598, 3598, 3599, 3599, 3600, 3601, 3601, 3602, 3602, 3603, 3603, 3604, 3605, 3605, 3606, 3606, 3607, 3607, 3608, 3609, 3609, 3610, 3610, 3611, 3611, 3612, 3613, 3613, 3614, 3614, 3615, 3615, 3616, 3616, 3617, 3618, 3618, 3619, 3619, 3620,
3620, 3621, 3622, 3622, 3623, 3623, 3624, 3624, 3625, 3626, 3626, 3627, 3627, 3628, 3628, 3629, 3629, 3630, 3631, 3631, 3632, 3632, 3633, 3633, 3634, 3635, 3635, 3636, 3636, 3637, 3637, 3638, 3639, 3639, 3640, 3640, 3641, 3641, 3642, 3642, 3643, 3644, 3644, 3645, 3645, 3646, 3646, 3647, 3648, 3648, 3649, 3649, 3650, 3650, 3651, 3651, 3652, 3653, 3653, 3654, 3654, 3655, 3655, 3656,
3656, 3657, 3658, 3658, 3659, 3659, 3660, 3660, 3661, 3662, 3662, 3663, 3663, 3664, 3664, 3665, 3665, 3666, 3667, 3667, 3668, 3668, 3669, 3669, 3670, 3670, 3671, 3672, 3672, 3673, 3673, 3674, 3674, 3675, 3675, 3676, 3677, 3677, 3678, 3678, 3679, 3679, 3680, 3680, 3681, 3682, 3682, 3683, 3683, 3684, 3684, 3685, 3685, 3686, 3687, 3687, 3688, 3688, 3689, 3689, 3690, 3690, 3691, 3692,
3692, 3693, 3693, 3694, 3694, 3695, 3695, 3696, 3697, 3697, 3698, 3698, 3699, 3699, 3700, 3700, 3701, 3702, 3702, 3703, 3703, 3704, 3704, 3705, 3705, 3706, 3707, 3707, 3708, 3708, 3709, 3709, 3710, 3710, 3711, 3712, 3712, 3713, 3713, 3714, 3714, 3715, 3715, 3716, 3716, 3717, 3718, 3718, 3719, 3719, 3720, 3720, 3721, 3721, 3722, 3723, 3723, 3724, 3724, 3725, 3725, 3726, 3726, 3727,
3727, 3728, 3729, 3729, 3730, 3730, 3731, 3731, 3732, 3732, 3733, 3734, 3734, 3735, 3735, 3736, 3736, 3737, 3737, 3738, 3738, 3739, 3740, 3740, 3741, 3741, 3742, 3742, 3743, 3743, 3744, 3744, 3745, 3746, 3746, 3747, 3747, 3748, 3748, 3749, 3749, 3750, 3750, 3751, 3752, 3752, 3753, 3753, 3754, 3754, 3755, 3755, 3756, 3756, 3757, 3758, 3758, 3759, 3759, 3760, 3760, 3761, 3761, 3762,
3762, 3763, 3764, 3764, 3765, 3765, 3766, 3766, 3767, 3767, 3768, 3768, 3769, 3770, 3770, 3771, 3771, 3772, 3772, 3773, 3773, 3774, 3774, 3775, 3776, 3776, 3777, 3777, 3778, 3778, 3779, 3779, 3780, 3780, 3781, 3781, 3782, 3783, 3783, 3784, 3784, 3785, 3785, 3786, 3786, 3787, 3787, 3788, 3788, 3789, 3790, 3790, 3791, 3791, 3792, 3792, 3793, 3793, 3794, 3794, 3795, 3796, 3796, 3797,
3797, 3798, 3798, 3799, 3799, 3800, 3800, 3801, 3801, 3802, 3803, 3803, 3804, 3804, 3805, 3805, 3806, 3806, 3807, 3807, 3808, 3808, 3809, 3810, 3810, 3811, 3811, 3812, 3812, 3813, 3813, 3814, 3814, 3815, 3815, 3816, 3816, 3817, 3818, 3818, 3819, 3819, 3820, 3820, 3821, 3821, 3822, 3822, 3823, 3823, 3824, 3825, 3825, 3826, 3826, 3827, 3827, 3828, 3828, 3829, 3829, 3830, 3830, 3831,
3831, 3832, 3833, 3833, 3834, 3834, 3835, 3835, 3836, 3836, 3837, 3837, 3838, 3838, 3839, 3840, 3840, 3841, 3841, 3842, 3842, 3843, 3843, 3844, 3844, 3845, 3845, 3846, 3846, 3847, 3847, 3848, 3849, 3849, 3850, 3850, 3851, 3851, 3852, 3852, 3853, 3853, 3854, 3854, 3855, 3855, 3856, 3857, 3857, 3858, 3858, 3859, 3859, 3860, 3860, 3861, 3861, 3862, 3862, 3863, 3863, 3864, 3864, 3865,
3866, 3866, 3867, 3867, 3868, 3868, 3869, 3869, 3870, 3870, 3871, 3871, 3872, 3872, 3873, 3873, 3874, 3875, 3875, 3876, 3876, 3877, 3877, 3878, 3878, 3879, 3879, 3880, 3880, 3881, 3881, 3882, 3882, 3883, 3884, 3884, 3885, 3885, 3886, 3886, 3887, 3887, 3888, 3888, 3889, 3889, 3890, 3890, 3891, 3891, 3892, 3892, 3893, 3894, 3894, 3895, 3895, 3896, 3896, 3897, 3897, 3898, 3898, 3899,
3899, 3900, 3900, 3901, 3901, 3902, 3902, 3903, 3904, 3904, 3905, 3905, 3906, 3906, 3907, 3907, 3908, 3908, 3909, 3909, 3910, 3910, 3911, 3911, 3912, 3912, 3913, 3913, 3914, 3915, 3915, 3916, 3916, 3917, 3917, 3918, 3918, 3919, 3919, 3920, 3920, 3921, 3921, 3922, 3922, 3923, 3923, 3924, 3924, 3925, 3925, 3926, 3927, 3927, 3928, 3928, 3929, 3929, 3930, 3930, 3931, 3931, 3932, 3932,
3933, 3933, 3934, 3934, 3935, 3935, 3936, 3936, 3937, 3937, 3938, 3938, 3939, 3940, 3940, 3941, 3941, 3942, 3942, 3943, 3943, 3944, 3944, 3945, 3945, 3946, 3946, 3947, 3947, 3948, 3948, 3949, 3949, 3950, 3950, 3951, 3951, 3952, 3953, 3953, 3954, 3954, 3955, 3955, 3956, 3956, 3957, 3957, 3958, 3958, 3959, 3959, 3960, 3960, 3961, 3961, 3962, 3962, 3963, 3963, 3964, 3964, 3965, 3965,
3966, 3966, 3967, 3968, 3968, 3969, 3969, 3970, 3970, 3971, 3971, 3972, 3972, 3973, 3973, 3974, 3974, 3975, 3975, 3976, 3976, 3977, 3977, 3978, 3978, 3979, 3979, 3980, 3980, 3981, 3981, 3982, 3982, 3983, 3983, 3984, 3984, 3985, 3986, 3986, 3987, 3987, 3988, 3988, 3989, 3989, 3990, 3990, 3991, 3991, 3992, 3992, 3993, 3993, 3994, 3994, 3995, 3995, 3996, 3996, 3997, 3997, 3998, 3998,
3999, 3999, 4000, 4000, 4001, 4001, 4002, 4002, 4003, 4003, 4004, 4004, 4005, 4006, 4006, 4007, 4007, 4008, 4008, 4009, 4009, 4010, 4010, 4011, 4011, 4012, 4012, 4013, 4013, 4014, 4014, 4015, 4015, 4016, 4016, 4017, 4017, 4018, 4018, 4019, 4019, 4020, 4020, 4021, 4021, 4022, 4022, 4023, 4023, 4024, 4024, 4025, 4025, 4026, 4026, 4027, 4027, 4028, 4028, 4029, 4029, 4030, 4030, 4031,
4032, 4032, 4033, 4033, 4034, 4034, 4035, 4035, 4036, 4036, 4037, 4037, 4038, 4038, 4039, 4039, 4040, 4040, 4041, 4041, 4042, 4042, 4043, 4043, 4044, 4044, 4045, 4045, 4046, 4046, 4047, 4047, 4048, 4048, 4049, 4049, 4050, 4050, 4051, 4051, 4052, 4052, 4053, 4053, 4054, 4054, 4055, 4055, 4056, 4056, 4057, 4057, 4058, 4058, 4059, 4059, 4060, 4060, 4061, 4061, 4062, 4062, 4063, 4063,
4064, 4064, 4065, 4065, 4066, 4066, 4067, 4067, 4068, 4068, 4069, 4069, 4070, 4070, 4071, 4071, 4072, 4072, 4073, 4073, 4074, 4074, 4075, 4075, 4076, 4076, 4077, 4077, 4078, 4078, 4079, 4079, 4080, 4080, 4081, 4081, 4082, 4082, 4083, 4083, 4084, 4084, 4085, 4085, 4086, 4086, 4087, 4087, 4088, 4088, 4089, 4089, 4090, 4090, 4091, 4091, 4092, 4092, 4093, 4093, 4094, 4094, 4095, };
static inline int32 sqrtv(int32 x)
{
const u16 a=f32toint(x);
const u16 b=x&4095;
return (a<SQRTRANGE)?((a)?mulf32(sqrtLUT1[a],sqrtLUT2[b/(2*a)]):(sqrtLUT3[b])):(0);
}
#endif

77
arm7/include/OBB.h Normal file
View File

@ -0,0 +1,77 @@
#ifndef OBB_H
#define OBB_H
#define NUMOBJECTS (4)
#define NUMOBBSEGMENTS (12)
#define NUMOBBFACES (6)
#define MAXCONTACTPOINTS (15) // pool system ?
#define PENETRATIONTHRESHOLD (1<<6)
#define MAXPENETRATIONBOX (1<<6)
static const u8 OBBSegments[NUMOBBSEGMENTS][2]={{0,1},{1,2},{3,2},{0,3},
{5,4},{5,6},{6,7},{4,7},
{3,4},{0,5},{1,6},{2,7}};
static const u8 OBBSegmentsPD[NUMOBBSEGMENTS][2]={{0,0},{1,2},{3,0},{0,2},
{5,2},{5,0},{6,2},{4,0},
{3,1},{0,1},{1,1},{2,1}};
static const u8 OBBFaces[NUMOBBFACES][4]={{0,1,2,3},{4,5,6,7},{0,5,4,3},{0,1,6,5},{1,2,7,6},{2,3,4,7}};
static const s8 OBBFacesPDDN[NUMOBBFACES][4]={{0,0,2,-2},{5,0,2,2},{0,1,2,-1},{0,0,1,-3},{1,1,2,1},{3,0,1,3}};
typedef enum
{
BOXCOLLISION,
PLANECOLLISION,
TESTPOINT,
AARCOLLISION
}contactPoint_type;
typedef struct
{
vect3D point;
vect3D normal;
u16 penetration;
void* target;
contactPoint_type type;
}contactPoint_struct;
typedef struct
{
int32 mass;
int32 transformationMatrix[9]; //3x3
int32 invInertiaMatrix[9]; //3x3
int32 invWInertiaMatrix[9]; //3x3
u16 maxPenetration;
contactPoint_struct contactPoints[MAXCONTACTPOINTS];
u8 numContactPoints;
vect3D size;
vect3D position;
vect3D velocity, angularVelocity, forces, moment;
vect3D angularMomentum;
vect3D AABBo, AABBs;
bool portal[2];
bool oldPortal[2];
bool used;
}OBB_struct;
// 4 + 9*4*3 + 4 +
extern OBB_struct objects[NUMOBJECTS];
void initOBB(OBB_struct* o, vect3D size, vect3D pos);
void initTransformationMatrix(int32* m);
void getOBBVertices(OBB_struct* o, vect3D* v);
void drawOBB(OBB_struct* o);
void applyOBBImpulses(OBB_struct* o);
void applyOBBForce(OBB_struct* o, vect3D p, vect3D f);
void updateOBB(OBB_struct* o);
void initOBBs(void);
void updateOBBs(void);
void drawOBBs(void);
OBB_struct* createOBB(u8 id, vect3D size, vect3D position);
void collideOBBs(OBB_struct* o1, OBB_struct* o2);
bool clipSegmentOBB(int32* ss, vect3D *uu, vect3D* p1, vect3D* p2, vect3D vv, vect3D* uu1, vect3D* uu2, vect3D vv1, vect3D* n1, vect3D* n2, bool* b1, bool* b2, int32* k1, int32* k2);
#endif

24
arm7/include/PI7.h Normal file
View File

@ -0,0 +1,24 @@
#ifndef PI7_H
#define PI7_H
typedef struct
{
vect3D position;
}player_struct;
typedef struct portal_struct
{
vect3D position, normal, plane[2];
int32 cos, sin;
struct portal_struct* targetPortal;
}portal_struct;
#include "PIC.h"
extern player_struct player;
extern portal_struct portal[2];
void initPI7(void);
void listenPI7(void);
#endif

103
arm7/include/PIC.h Normal file
View File

@ -0,0 +1,103 @@
#ifndef PIC_H
#define PIC_H
#define PISIGNALDATA (6)
#define PISIGNALMASK ((1<<PISIGNALDATA)-1)
typedef enum
{
PI_START=1, //ARG : 0
PI_PAUSE=2, //ARG : 0
PI_STOP=3, //ARG : 0
PI_RESET=4, //ARG : 0
PI_ADDBOX=5, //ARG : 5 (id;[sizex|sizey][sizez|mass][posx][posy][posz])
PI_APPLYFORCE=6, //ARG : 5 (id;[posx|posy][posz][vx][vy][vz])
PI_ADDAAR=7, //ARG : 5 (id;[sizex|sizey][sizez|normal][posx][posy][posz])
PI_MAKEGRID=8, //ARG : 0
PI_SETVELOCITY=9, //ARG : 3 (id;[vx][vy][vz])
PI_UPDATEPLAYER=10, //ARG : 3 ([vx][vy][vz])
PI_UPDATEPORTAL=11, //ARG : 4 (id;[px][py][pz][n])
}message_type;
#ifdef ARM7
static inline void computePortalPlane(portal_struct* p)
{
if(!p)return;
if(p->normal.x)
{
if(p->normal.x>0)
{
p->plane[0]=vect(0,p->sin,-p->cos);
}else{
p->plane[0]=vect(0,p->sin,p->cos);
}
}else if(p->normal.y)
{
if(p->normal.y>0)
{
p->plane[0]=vect(p->cos,0,p->sin);
}else{
p->plane[0]=vect(p->cos,0,p->sin);
}
}else{
if(p->normal.z>0)
{
p->plane[0]=vect(p->cos,p->sin,0);
}else{
p->plane[0]=vect(-p->cos,p->sin,0);
}
}
p->plane[1]=vectProduct(p->normal,p->plane[0]);
}
#else
static inline void computePortalPlane(portal_struct* p)
{
if(!p)return;
if(p->normal.x)
{
if(p->normal.x>0)
{
p->plane[0]=vect(0,sinLerp(p->angle),-cosLerp(p->angle));
}else{
p->plane[0]=vect(0,sinLerp(p->angle),cosLerp(p->angle));
}
}else if(p->normal.y)
{
if(p->normal.y>0)
{
p->plane[0]=vect(cosLerp(p->angle),0,sinLerp(p->angle));
}else{
p->plane[0]=vect(cosLerp(p->angle),0,sinLerp(p->angle));
}
}else{
if(p->normal.z>0)
{
p->plane[0]=vect(cosLerp(p->angle),sinLerp(p->angle),0);
}else{
p->plane[0]=vect(-cosLerp(p->angle),sinLerp(p->angle),0);
}
}
p->plane[1]=vectProduct(p->normal,p->plane[0]);
}
#endif
static inline vect3D warpVector(portal_struct* p, vect3D v)
{
if(!p)return vect(0,0,0);
portal_struct* p2=p->targetPortal;
if(!p2)return vect(0,0,0);
// computePortalPlane(p2);
int32 x=dotProduct(v,p->plane[0]);
int32 y=dotProduct(v,p->plane[1]);
int32 z=dotProduct(v,p->normal);
return addVect(vectMult(p2->normal,-z),addVect(vectMult(p2->plane[0],-x),vectMult(p2->plane[1],y)));
}
#endif

38
arm7/include/debug.h Normal file
View File

@ -0,0 +1,38 @@
#ifndef __DEBUG9__
#define __DEBUG9__
#define VERSIONMAGIC 45464873
int glob_time;
#define PROF_START() \
do { \
TIMER2_DATA = 0; TIMER3_DATA = 0; \
TIMER3_CR = TIMER_ENABLE | TIMER_CASCADE | TIMER_IRQ_REQ; \
TIMER2_CR = TIMER_ENABLE; \
} while(0)
#define PROF_GET(_time) _time = ( TIMER3_DATA << 16 ) | TIMER2_DATA;
#define PROF_END(_time) \
do { \
_time = ( TIMER3_DATA << 16 ) | TIMER2_DATA; \
TIMER2_CR = 0; TIMER3_CR = 0; \
} while(0)
#define PROF2_START()
#define PROF2_END(_time) _time=92431
#define NOGBA(_fmt, _args...) do { char nogba_buffer[256]; sprintf(nogba_buffer, _fmt, ##_args); N3DNoCashMsg(nogba_buffer); } while(0)
extern int N3DNoCashMsg(const char *pText);
int TESTANGLE2;
void DS_Debug(char* string, ...);
void DS_DebugPause(void);
size_t DS_UsedMem(void);
size_t DS_FreeMem(void);
#endif

225
arm7/include/math.h Normal file
View File

@ -0,0 +1,225 @@
#ifndef MATH_H
#define MATH_H
#define inttof32(n) ((n) << (12)) /*!< \brief convert int to f32 */
#define f32toint(n) ((n) >> (12)) /*!< \brief convert f32 to int */
#define floattof32(n) ((int)((n) * (1 << (12)))) /*!< \brief convert float to f32 */
#define f32tofloat(n) (((float)(n)) / (float)(1<<(12))) /*!< \brief convert f32 to float */
#define min(a,b) (((a)>(b))?(b):(a))
#define max(a,b) (((a)>(b))?(a):(b))
typedef struct
{
int32 x, y, z;
}vect3D;
// float sqrtf(float a){return a;}
static inline vect3D vect(int32 x, int32 y, int32 z){vect3D v;v.x=x;v.y=y;v.z=z;return v;}
static inline int32 mulf32(int32 a, int32 b)
{
long long result = (long long)a * (long long)b;
return (int32)(result >> (12));
}
#include "LUTs.h"
// static inline int32 divf32(int32 a, int32 b)
// {
// long long result = (((long long)a)<<12) / (long long)b;
// return (int32)(result);
// }
static inline int32 divv16(int32 a, int32 b)
{
int32 d=(((int32)a)<<12)/b;
return (int32)d;
}
static inline int32 mulv16(int32 a, int32 b)
{
int32 d=((int32)a)*((int32)b);
return (int32)(d>>12);
}
static inline vect3D addVect(vect3D p1, vect3D p2)
{
return vect(p1.x+p2.x,p1.y+p2.y,p1.z+p2.z);
}
static inline vect3D vectMult(vect3D v, int32 k)
{
return vect(mulf32(v.x,k), mulf32(v.y,k), mulf32(v.z,k));
}
static inline vect3D vectMultv16(vect3D v, int32 k)
{
return vect(mulv16(v.x,k), mulv16(v.y,k), mulv16(v.z,k));
}
static inline vect3D vectMultInt(vect3D v, int k)
{
return vect((v.x*k), (v.y*k), (v.z*k));
}
static inline vect3D vectDivInt(vect3D v, int k)
{
return vect((v.x/k), (v.y/k), (v.z/k));
}
static inline vect3D vectDifference(vect3D p1, vect3D p2)
{
return vect(p1.x-p2.x,p1.y-p2.y,p1.z-p2.z);
}
static inline int32 dotProduct(vect3D v1, vect3D v2)
{
return (mulf32(v1.x,v2.x)+mulf32(v1.y,v2.y)+mulf32(v1.z,v2.z));
}
static inline vect3D normalize(vect3D v)
{
int32 d=sqrtv(mulf32(v.x,v.x)+mulf32(v.y,v.y)+mulf32(v.z,v.z));
return vect(divv16(v.x,d),divv16(v.y,d),divv16(v.z,d));
}
static inline int32 magnitude(vect3D v)
{
int32 d=sqrtv(mulf32(v.x,v.x)+mulf32(v.y,v.y)+mulf32(v.z,v.z));
return d;
}
static inline int32 distance(vect3D v1, vect3D v2)
{
return magnitude(vectDifference(v2,v1));
}
static inline vect3D divideVect(vect3D v, int32 d)
{
return vect(divv16(v.x,d),divv16(v.y,d),divv16(v.z,d));
}
static inline vect3D vectProduct(vect3D v1, vect3D v2)
{
return vect(mulf32(v1.y,v2.z)-mulf32(v1.z,v2.y),mulf32(v1.z,v2.x)-mulf32(v1.x,v2.z),mulf32(v1.x,v2.y)-mulf32(v1.y,v2.x));
}
// static inline int cosLerp(int32 x){return floattof32(cos((x*PI)/16384));}
// static inline int sinLerp(int32 x){return floattof32(sin((x*PI)/16384));}
static inline int cosLerp(int32 x){return 1;}
static inline int sinLerp(int32 x){return 1;}
static inline void multMatrix33(int32* m1, int32* m2, int32* m) //3x3
{
int i, j;
// for(i=0;i<4;i++)for(j=0;j<4;j++)m[i+j*4]=m1[i+0*4]*m2[0+j*4]+m1[i+1*4]*m2[1+j*4]+m1[i+2*4]*m2[2+j*4]+m1[i+3*4]*m2[3+j*4];
for(i=0;i<3;i++)for(j=0;j<3;j++)m[j+i*3]=mulf32(m1[0+i*3],m2[j+0*3])+mulf32(m1[1+i*3],m2[j+1*3])+mulf32(m1[2+i*3],m2[j+2*3]);
}
static inline void multMatrix332(int32* m1, int32* m2, int32* m) //3x3
{
int i, j;
for(i=0;i<3;i++)for(j=0;j<3;j++)m[i+j*3]=mulf32(m1[i+0*3],m2[0+j*3])+mulf32(m1[i+2*3],m2[2+j*3])+mulf32(m1[i+2*3],m2[2+j*3]);
}
static inline void addMatrix33(int32* m1, int32* m2, int32* m) //3x3
{
int i, j;
for(i=0;i<3;i++)for(j=0;j<3;j++)m[j+i*3]=m1[j+i*3]+m2[j+i*3];
}
static inline void transposeMatrix33(int32* m1, int32* m2) //3x3
{
int i, j;
for(i=0;i<3;i++)for(j=0;j<3;j++)m2[j+i*3]=m1[i+j*3];
}
static inline vect3D evalVectMatrix33(int32* m, vect3D v) //3x3
{
return vect((mulf32(v.x,m[0])+mulf32(v.y,m[1])+mulf32(v.z,m[2])),
(mulf32(v.x,m[3])+mulf32(v.y,m[4])+mulf32(v.z,m[5])),
(mulf32(v.x,m[6])+mulf32(v.y,m[7])+mulf32(v.z,m[8])));
}
static inline int32 clamp(int32 v, int32 m, int32 M)
{
if(m<M)return max(m,min(v,M));
else return min(m,max(v,M));
}
static inline void rotateMatrixX(int32* tm, int32 x, bool r)
{
int i;
int32 rm[9], m[9];
for(i=0;i<9;i++)rm[i]=0;
rm[0]=inttof32(1);
rm[4]=cosLerp(x);
rm[5]=sinLerp(x);
rm[7]=-sinLerp(x);
rm[8]=cosLerp(x);
if(r)multMatrix33(rm,tm,m);
else multMatrix33(tm,rm,m);
memcpy(tm,m,9*sizeof(int32));
}
static inline void rotateMatrixY(int32* tm, int32 x, bool r)
{
int i;
int32 rm[9], m[16];
for(i=0;i<9;i++)rm[i]=0;
rm[0]=cosLerp(x);
rm[2]=sinLerp(x);
rm[4]=inttof32(1);
rm[6]=-sinLerp(x);
rm[8]=cosLerp(x);
if(r)multMatrix33(rm,tm,m);
else multMatrix33(tm,rm,m);
memcpy(tm,m,9*sizeof(int32));
}
static inline void rotateMatrixZ(int32* tm, int32 x, bool r)
{
int i;
int32 rm[9], m[16];
for(i=0;i<9;i++)rm[i]=0;
rm[0]=cosLerp(x);
rm[1]=sinLerp(x);
rm[3]=-sinLerp(x);
rm[4]=cosLerp(x);
rm[8]=inttof32(1);
if(r)multMatrix33(rm,tm,m);
else multMatrix33(tm,rm,m);
memcpy(tm,m,9*sizeof(int32));
}
static inline void projectVectorPlane(vect3D* v, vect3D n)
{
if(!v)return;
int32 r=dotProduct(*v,n);
*v=vectDifference(*v,vectMult(n,r));
}
static inline void fixMatrix(int32* m) //3x3
{
if(!m)return;
vect3D x=vect(m[0],m[3],m[6]);
vect3D y=vect(m[1],m[4],m[7]);
vect3D z=vect(m[2],m[5],m[8]);
projectVectorPlane(&x,y);
projectVectorPlane(&z,y);
projectVectorPlane(&z,x);
x=normalize(x);
y=normalize(y);
z=normalize(z);
m[0]=x.x;m[3]=x.y;m[6]=x.z;
m[1]=y.x;m[4]=y.y;m[7]=y.z;
m[2]=z.x;m[5]=z.y;m[8]=z.z;
}
#endif

23
arm7/include/plane.h Normal file
View File

@ -0,0 +1,23 @@
#ifndef PLANE_H
#define PLANE_H
typedef struct
{
int32 A, B, C, D;
vect3D point;
}plane_struct;
static inline int32 evaluatePlanePoint(plane_struct* p, vect3D v)
{
if(!p)return 0;
return mulf32(p->A,v.x)+mulf32(p->B,v.y)+mulf32(p->C,v.z)+p->D;
}
plane_struct testPlane;
void initPlane(plane_struct* pl, int32 A, int32 B, int32 C, int32 D);
vect3D intersectSegmentPlane(plane_struct* pl, vect3D o, vect3D v, int32 d);
void planeOBBContacts(plane_struct* p, OBB_struct* o);
#endif

23
arm7/include/stdafx.h Normal file
View File

@ -0,0 +1,23 @@
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#define RESX 800
#define RESY 600
#define PI 3.14159265
#include <stdio.h>
#include <stdlib.h>
#include <nds.h>
#include "math.h"
#include "OBB.h"
#include "plane.h"
#include "AAR.h"
#include "PI7.h"
#include "debug.h"
// TODO: reference additional headers your program requires here

382
arm7/source/AAR.c Normal file
View File

@ -0,0 +1,382 @@
#include "stdafx.h"
#define PORTALSIZEX (inttof32(1)/12) //TEMP (PIC.h)
#define PORTALSIZEY (inttof32(1)/6) //TEMP (PIC.h)
#define ALLOCATORSIZE (8*1024)
u8 allocatorPool[ALLOCATORSIZE];
u16 allocatorCounter;
AAR_struct aaRectangles[NUMAARS];
grid_struct AARgrid;
static const u8 AARSegments[NUMAARSEGMENTS][2]={{0,1},{1,2},{3,2},{0,3}};
static const u8 AARSegmentsPD[NUMAARSEGMENTS][2]={{0,0},{1,1},{3,0},{0,1}};
extern portal_struct portal[2];
void initAllocator(void)
{
allocatorCounter=0;
}
void* allocateData(u16 size)
{
if(allocatorCounter+size>ALLOCATORSIZE){return NULL;}
allocatorCounter+=size;
return &allocatorPool[allocatorCounter-size];
}
void initAARs(void)
{
int i;
for(i=0;i<NUMAARS;i++)
{
aaRectangles[i].used=false;
}
AARgrid.nodes=NULL;
AARgrid.width=AARgrid.height=0;
initAllocator();
}
void freeGrid(grid_struct* g)
{
if(!g || !g->nodes)return;
g->nodes=NULL;
initAllocator();
}
void generateGrid(grid_struct* g)
{
if(!g)g=&AARgrid;
freeGrid(g);
int i;
bool b=false;
vect3D m, M;
m=vect((1<<29),(1<<29),(1<<29));
M=vect(-(1<<29),-(1<<29),-(1<<29));
for(i=0;i<NUMAARS;i++)
{
if(aaRectangles[i].used)
{
if(aaRectangles[i].position.x<m.x)m.x=aaRectangles[i].position.x;
if(aaRectangles[i].position.z<m.z)m.z=aaRectangles[i].position.z;
if(aaRectangles[i].position.x+aaRectangles[i].size.x>M.x)M.x=aaRectangles[i].position.x+aaRectangles[i].size.x;
if(aaRectangles[i].position.z+aaRectangles[i].size.z>M.z)M.z=aaRectangles[i].position.z+aaRectangles[i].size.z;
b=true;
}
}
if(!b)return;
g->width=(M.x-m.x)/NODESIZE+1;
g->height=(M.z-m.z)/NODESIZE+1;
g->m=m;
g->M=M;
g->nodes=allocateData(sizeof(node_struct)*g->width*g->height);
fifoSendValue32(FIFO_USER_08,allocatorCounter);
static u16 temp[NUMAARS];
int j, k;
for(i=0;i<g->width;i++)
{
for(j=0;j<g->height;j++)
{
node_struct* n=&g->nodes[i+j*g->width];
n->length=0;
for(k=0;k<NUMAARS;k++)
{
if(aaRectangles[k].used)
{
const int32 mX=g->m.x+i*NODESIZE, MX=g->m.x+(i+1)*NODESIZE;
const int32 mZ=g->m.z+j*NODESIZE, MZ=g->m.z+(j+1)*NODESIZE;
if(!((aaRectangles[k].position.x<mX && aaRectangles[k].position.x+aaRectangles[k].size.x<mX)
|| (aaRectangles[k].position.x>MX && aaRectangles[k].position.x+aaRectangles[k].size.x>MX)
|| (aaRectangles[k].position.z<mZ && aaRectangles[k].position.z+aaRectangles[k].size.z<mZ)
|| (aaRectangles[k].position.z>MZ && aaRectangles[k].position.z+aaRectangles[k].size.z>MZ)))
{
temp[n->length]=k;
n->length++;
}
}
}
if(n->length){n->data=allocateData(sizeof(u16)*n->length);memcpy(n->data,temp,n->length*sizeof(u16));}
else n->data==NULL;
}
}
fifoSendValue32(FIFO_USER_08,allocatorCounter);
}
void getOBBNodes(grid_struct* g, OBB_struct* o, u16* x, u16* X, u16* z, u16* Z)
{
if(!o)return;
if(!g)g=&AARgrid;
const vect3D m=vectDifference(o->AABBo,g->m);
const vect3D M=addVect(m,o->AABBs);
*x=m.x/NODESIZE;*z=m.z/NODESIZE;
*X=M.x/NODESIZE;*Z=M.z/NODESIZE;
}
AAR_struct* createAAR(u16 id, vect3D position, vect3D size, vect3D normal)
{
int i=id;
// for(i=0;i<NUMAARS;i++)
// {
if(!aaRectangles[i].used)
{
aaRectangles[i].used=true;
aaRectangles[i].position=position;
aaRectangles[i].size=size;
aaRectangles[i].normal=normal;
return &aaRectangles[i];
}
// }
return NULL;
}
bool pointInPortal(portal_struct* p, vect3D pos) //assuming correct normal
{
if(!p)return false;
vect3D v=vectDifference(pos, p->position); //then, project onto portal base
if(p->normal.x){return (abs(v.x)<16 && v.y>-PORTALSIZEY*4 && v.y<PORTALSIZEY*4 && v.z>-PORTALSIZEX*4 && v.z<PORTALSIZEX*4);}
else if(p->normal.y){return (abs(v.y)<16 && v.z>-PORTALSIZEY*4 && v.z<PORTALSIZEY*4 && v.x>-PORTALSIZEX*4 && v.x<PORTALSIZEX*4);}
else {return (abs(v.z)<16 && v.y>-PORTALSIZEY*4 && v.y<PORTALSIZEY*4 && v.x>-PORTALSIZEX*4 && v.x<PORTALSIZEX*4);}
}
void OBBAARContacts(AAR_struct* a, OBB_struct* o)
{
if(!a || !o || !o->used || !a->used)return;
vect3D u[3];
u[0]=vect(o->transformationMatrix[0],o->transformationMatrix[3],o->transformationMatrix[6]);
u[1]=vect(o->transformationMatrix[1],o->transformationMatrix[4],o->transformationMatrix[7]);
u[2]=vect(o->transformationMatrix[2],o->transformationMatrix[5],o->transformationMatrix[8]);
vect3D v[4], vv[4];
vect3D uu[2], uuu[2];
int32 s[2];
v[0]=vectDifference(a->position,o->position);
v[2]=addVect(v[0],a->size);
if(a->normal.x)
{
uu[0]=vect(0,inttof32(1),0);s[0]=a->size.y;
uu[1]=vect(0,0,inttof32(1));s[1]=a->size.z;
v[1]=addVect(v[0],vect(0,a->size.y,0));
v[3]=addVect(v[0],vect(0,0,a->size.z));
}else if(a->normal.y)
{
uu[0]=vect(inttof32(1),0,0);s[0]=a->size.x;
uu[1]=vect(0,0,inttof32(1));s[1]=a->size.z;
v[1]=addVect(v[0],vect(a->size.x,0,0));
v[3]=addVect(v[0],vect(0,0,a->size.z));
}else{
uu[0]=vect(inttof32(1),0,0);s[0]=a->size.x;
uu[1]=vect(0,inttof32(1),0);s[1]=a->size.y;
v[1]=addVect(v[0],vect(a->size.x,0,0));
v[3]=addVect(v[0],vect(0,a->size.y,0));
}
int i;
for(i=0;i<4;i++) //optimizeable
{
vv[i]=vect(dotProduct(v[i],u[0]),dotProduct(v[i],u[1]),dotProduct(v[i],u[2]));
v[i]=addVect(v[i],o->position);
}
uuu[0]=vect(dotProduct(uu[0],u[0]),dotProduct(uu[0],u[1]),dotProduct(uu[0],u[2]));
uuu[1]=vect(dotProduct(uu[1],u[0]),dotProduct(uu[1],u[1]),dotProduct(uu[1],u[2]));
int32 ss[3];
ss[0]=o->size.x;//+MAXPENETRATIONBOX;
ss[1]=o->size.y;//+MAXPENETRATIONBOX;
ss[2]=o->size.z;//+MAXPENETRATIONBOX;
for(i=0;i<NUMAARSEGMENTS;i++)
{
vect3D p1=v[AARSegments[i][0]];
vect3D p2=v[AARSegments[i][1]];
vect3D uu1=vv[AARSegments[i][0]];
vect3D uu2=vv[AARSegments[i][1]];
vect3D n1, n2;
int32 k1, k2;
bool b1, b2;
if(clipSegmentOBB(ss, u, &p1, &p2, uu[AARSegmentsPD[i][1]], &uu1, &uu2, uuu[AARSegmentsPD[i][1]], &n1, &n2, &b1, &b2, &k1, &k2))
{
if(b1)
{
bool b=false;
if((portal[0].normal.x&&a->normal.x)||(portal[0].normal.y&&a->normal.y)||(portal[0].normal.z&&a->normal.z))b=pointInPortal(&portal[0],p1);
if(!b&&((portal[1].normal.x&&a->normal.x)||(portal[1].normal.y&&a->normal.y)||(portal[1].normal.z&&a->normal.z)))b=pointInPortal(&portal[1],p1);
if(!b)
{
//p1=addVect(p1,vectMult(vv,k1));
o->contactPoints[o->numContactPoints].point=p1;
o->contactPoints[o->numContactPoints].type=PLANECOLLISION;
o->contactPoints[o->numContactPoints].normal=a->normal;
o->contactPoints[o->numContactPoints].penetration=0;
o->contactPoints[o->numContactPoints].target=NULL;
o->numContactPoints++;
}
}
if(b2)
{
bool b=false;
if((portal[0].normal.x&&a->normal.x)||(portal[0].normal.y&&a->normal.y)||(portal[0].normal.z&&a->normal.z))b=pointInPortal(&portal[0],p2);
if(!b&&((portal[1].normal.x&&a->normal.x)||(portal[1].normal.y&&a->normal.y)||(portal[1].normal.z&&a->normal.z)))b=pointInPortal(&portal[1],p2);
if(!b)
{
//p2=addVect(p2,vectMult(vv,k2));
o->contactPoints[o->numContactPoints].point=p2;
o->contactPoints[o->numContactPoints].type=PLANECOLLISION;
o->contactPoints[o->numContactPoints].normal=a->normal;
o->contactPoints[o->numContactPoints].penetration=0;
o->contactPoints[o->numContactPoints].target=NULL;
o->numContactPoints++;
}
}
}
}
}
void AAROBBContacts(AAR_struct* a, OBB_struct* o, vect3D* v)
{
if(!a || !o || !o->used || !a->used)return;
vect3D u[3];
u[0]=vect(o->transformationMatrix[0],o->transformationMatrix[3],o->transformationMatrix[6]);
u[1]=vect(o->transformationMatrix[1],o->transformationMatrix[4],o->transformationMatrix[7]);
u[2]=vect(o->transformationMatrix[2],o->transformationMatrix[5],o->transformationMatrix[8]);
if(a->normal.x)
{
if(a->position.x>o->AABBo.x+o->AABBs.x || a->position.x<o->AABBo.x)return;
int i;
bool vb[8];
for(i=0;i<8;i++)vb[i]=v[i].x>a->position.x;
for(i=0;i<NUMOBBSEGMENTS;i++) //possible to only check half !
{
if(vb[OBBSegments[i][0]]!=vb[OBBSegments[i][1]])
{
const vect3D uu=v[OBBSegmentsPD[i][0]];
const vect3D vv=u[OBBSegmentsPD[i][1]];
const int32 k=divv16(abs(uu.x-a->position.x),abs(vv.x));
const vect3D p=addVect(uu,vectMult(vv,k));
if(p.y>a->position.y && p.y<a->position.y+a->size.y && p.z>a->position.z && p.z<a->position.z+a->size.z)
{
bool b=false;
if(portal[0].normal.x)b=pointInPortal(&portal[0],p);
if(!b&&portal[1].normal.x)b=pointInPortal(&portal[1],p);
if(!b)
{
o->contactPoints[o->numContactPoints].point=p;
o->contactPoints[o->numContactPoints].type=AARCOLLISION;
o->contactPoints[o->numContactPoints].normal=a->normal;
o->contactPoints[o->numContactPoints].penetration=0;
o->contactPoints[o->numContactPoints].target=NULL;
o->numContactPoints++;
}
}
}
}
}else if(a->normal.y)
{
if(a->position.y>o->AABBo.y+o->AABBs.y || a->position.y<o->AABBo.y)return;
int i;
bool vb[8];
for(i=0;i<8;i++)vb[i]=v[i].y>a->position.y;
for(i=0;i<NUMOBBSEGMENTS;i++)
{
if(vb[OBBSegments[i][0]]!=vb[OBBSegments[i][1]])
{
const vect3D uu=v[OBBSegmentsPD[i][0]];
const vect3D vv=u[OBBSegmentsPD[i][1]];
const int32 k=divv16(abs(uu.y-a->position.y),abs(vv.y));
const vect3D p=addVect(uu,vectMult(vv,k));
if(p.x>a->position.x && p.x<a->position.x+a->size.x && p.z>a->position.z && p.z<a->position.z+a->size.z)
{
bool b=false;
if(portal[0].normal.y)b=pointInPortal(&portal[0],p);
if(!b&&portal[1].normal.y)b=pointInPortal(&portal[1],p);
if(!b)
{
o->contactPoints[o->numContactPoints].point=p;
o->contactPoints[o->numContactPoints].type=AARCOLLISION;
o->contactPoints[o->numContactPoints].normal=a->normal;
o->contactPoints[o->numContactPoints].penetration=0;
o->contactPoints[o->numContactPoints].target=NULL;
o->numContactPoints++;
}
}
}
}
}else{
if(a->position.z>o->AABBo.z+o->AABBs.z || a->position.z<o->AABBo.z)return;
int i;
bool vb[8];
for(i=0;i<8;i++)vb[i]=v[i].z>a->position.z;
for(i=0;i<NUMOBBSEGMENTS;i++)
{
if(vb[OBBSegments[i][0]]!=vb[OBBSegments[i][1]])
{
const vect3D uu=v[OBBSegmentsPD[i][0]];
const vect3D vv=u[OBBSegmentsPD[i][1]];
const int32 k=divv16(abs(uu.z-a->position.z),abs(vv.z));
const vect3D p=addVect(uu,vectMult(vv,k));
if(p.x>a->position.x && p.x<a->position.x+a->size.x && p.z>a->position.y && p.y<a->position.y+a->size.y)
{
bool b=false;
if(portal[0].normal.x)b=pointInPortal(&portal[0],p);
if(!b&&portal[1].normal.x)b=pointInPortal(&portal[1],p);
if(!b)
{
o->contactPoints[o->numContactPoints].point=p;
o->contactPoints[o->numContactPoints].type=AARCOLLISION;
o->contactPoints[o->numContactPoints].normal=a->normal;
o->contactPoints[o->numContactPoints].penetration=0;
o->contactPoints[o->numContactPoints].target=NULL;
o->numContactPoints++;
}
}
}
}
}
OBBAARContacts(a, o);
}
void AARsOBBContacts(OBB_struct* o)
{
int i, j, k;
vect3D v[8];
getOBBVertices(o,v);
u16 x, X, z, Z;
getOBBNodes(NULL, o, &x, &X, &z, &Z);
bool lalala[NUMAARS];
for(i=0;i<NUMAARS;i++)lalala[i]=0;
for(i=x;i<=X;i++)
{
for(j=z;j<=Z;j++)
{
node_struct* n=&AARgrid.nodes[i+j*AARgrid.width];
for(k=0;k<n->length;k++)
{
if(!lalala[n->data[k]])AAROBBContacts(&aaRectangles[n->data[k]], o, v);
lalala[n->data[k]]=1;
}
}
}
// for(i=0;i<NUMAARS;i++)
// {
// if(aaRectangles[i].used)AAROBBContacts(&aaRectangles[i], o, v);
// }
}

913
arm7/source/OBB.c Normal file
View File

@ -0,0 +1,913 @@
#include "stdafx.h"
#define TIMEPREC (6)
OBB_struct objects[NUMOBJECTS];
u32 coll, integ, impul;
/*s16 divLUT[4097];
void initDivision(void)
{
int i;
for(i=1;i<4097;i++)
{
divLUT[i]=divv16(4096,i);
}
divLUT[0]=0;
}*/
static inline int32 divv(int32 a, int32 b) // b in 1-4096
{
/*return divf32(a,b);
s32 r=(((s32)a)*((s32)divLUT[b]))>>12;
return (s16)r;*/
return divv16(a,b);
}
void initOBB(OBB_struct* o, vect3D size, vect3D pos)
{
if(!o)return;
o->used=true;
o->position=pos;
o->angularMomentum=vect(0,0,0);
o->numContactPoints=0;
o->size=size;
o->mass=inttof32(1);
o->maxPenetration=0;
o->velocity=vect(0,0,0);
o->angularVelocity=vect(0,0,0);
o->moment=vect(0,0,0);
o->forces=vect(0,0,0);
initTransformationMatrix(o->transformationMatrix);
int32 x2=mulf32(o->size.x,o->size.x);
int32 y2=mulf32(o->size.y,o->size.y);
int32 z2=mulf32(o->size.z,o->size.z);
int i;for(i=0;i<9;i++){o->invInertiaMatrix[i]=0;}
//o->invInertiaMatrix[0]=divf32(inttof32(3),(mulf32(o->mass,(y2+z2))));
//o->invInertiaMatrix[4]=divf32(inttof32(3),(mulf32(o->mass,(x2+z2))));
//o->invInertiaMatrix[8]=divf32(inttof32(3),(mulf32(o->mass,(x2+y2))));
o->invInertiaMatrix[0]=divv16(inttof32(3),(mulf32(o->mass,(y2+z2))));
o->invInertiaMatrix[4]=divv16(inttof32(3),(mulf32(o->mass,(x2+z2))));
o->invInertiaMatrix[8]=divv16(inttof32(3),(mulf32(o->mass,(x2+y2))));
//rotateMatrixX(o->transformationMatrix,4096,false);
//rotateMatrixZ(o->transformationMatrix,4096,false);
updateOBBPortals(o,0,true);
updateOBBPortals(o,1,true);
}
void initOBBs(void)
{
int i;
for(i=0;i<NUMOBJECTS;i++)
{
objects[i].used=false;
}
}
void copyOBB(OBB_struct* o1, OBB_struct* o2)
{
if(!o1 || !o2)return;
o2->angularMomentum=o1->angularMomentum;
o2->numContactPoints=o1->numContactPoints;
o2->mass=o1->mass;
o2->position=o1->position;
o2->size=o1->size;
o2->maxPenetration=o1->maxPenetration;
o2->velocity=o1->velocity;
o2->angularVelocity=o1->angularVelocity;
o2->forces=o1->forces;
o2->moment=o1->moment;
memcpy(o2->transformationMatrix,o1->transformationMatrix,sizeof(int32)*9);
memcpy(o2->invInertiaMatrix,o1->invInertiaMatrix,sizeof(int32)*9);
memcpy(o2->invWInertiaMatrix,o1->invWInertiaMatrix,sizeof(int32)*9);
memcpy(o2->contactPoints,o1->contactPoints,sizeof(contactPoint_struct)*o2->numContactPoints);
}
bool collideAABB(vect3D o1, vect3D s1, vect3D o2, vect3D s2)
{
return !(o2.x>o1.x+s1.x || o2.y>o1.y+s1.y || o2.z>o1.z+s1.z
|| o2.x+s2.x<o1.x || o2.y+s2.y<o1.y || o2.z+s2.z<=o1.z);
}
vect3D projectPointAABB(vect3D size, vect3D p, vect3D* n)
{
if(!n)return vect(0,0,0);
vect3D v=p;
*n=vect(0,0,0);
/*if(p.x<-size.x){v.x=-size.x;n->x=-1;}
else if(p.x>size.x){v.x=size.x;n->x=1;}
if(p.y<-size.y){v.y=-size.y;n->y=-1;}
else if(p.y>size.y){v.y=size.y;n->y=1;}
if(p.z<-size.z){v.z=-size.z;n->z=-1;}
else if(p.z>size.z){v.z=size.z;n->z=1;}*/
if(p.x<-size.x){v.x=-size.x;n->x=-1;}
else if(p.x>size.x){v.x=size.x;n->x=1;}
else if(p.y<-size.y){v.y=-size.y;n->y=-1;}
else if(p.y>size.y){v.y=size.y;n->y=1;}
else if(p.z<-size.z){v.z=-size.z;n->z=-1;}
else if(p.z>size.z){v.z=size.z;n->z=1;}
if(!n->x && !n->y && !n->z)
{
int32 d1=abs(p.x+size.x);int32 d2=abs(p.x-size.x);
int32 d3=abs(p.y+size.y);int32 d4=abs(p.y-size.y);
int32 d5=abs(p.z+size.z);int32 d6=abs(p.z-size.z);
int32 d=min(d1,d2);
d=min(d,min(d3,d4));
d=min(d,min(d5,d6));
if(d==d1){v.x=-size.x;n->x=-1;}
else if(d==d2){v.x=size.x;n->x=1;}
else if(d==d3){v.y=-size.y;n->y=-1;}
else if(d==d4){v.y=size.y;n->y=1;}
else if(d==d5){v.z=-size.z;n->z=-1;}
else {v.z=size.z;n->z=1;}
}
return v;
}
bool collideLineRectangle(vect3D ro, vect3D ru1, vect3D ru2, vect3D rn, int32 rs1, int32 rs2, vect3D o, vect3D v, int32 d, vect3D* ip)
{
int32 p1=dotProduct(v,rn);
if(abs(p1)>10) //margin of error
{
int32 p2=dotProduct(vectDifference(ro,o),rn);
//int32 k=divf32(p2,p1);
int32 k=divv16(p2,p1);
if(k<0 || k>d){return false;}
vect3D i=addVect(o,vectMult(v,k));
if(ip)*ip=i; //real position at this point
i=vectDifference(i,ro);
i=vect(dotProduct(i,ru1),dotProduct(i,ru2),0);
return i.x>=0 && i.x<=rs1 && i.y>=0 && i.y<=rs2;
}
return false;
}
bool clipSegmentOBB(int32* ss, vect3D *uu, vect3D* p1, vect3D* p2, vect3D vv, vect3D* uu1, vect3D* uu2, vect3D vv1, vect3D* n1, vect3D* n2, bool* b1, bool* b2, int32* k1, int32* k2)
{
if(!p1 || !p2 || !uu1 || !uu2 || !n1 || !n2 || !b1 || !b2 || !k1 || !k2)return false;
if(uu1->x<-ss[0])
{
if(uu2->x>-ss[0])
{
int32 k=divv(abs(uu1->x+ss[0]),abs(vv1.x));
*uu1=addVect(*uu1,vectMult(vv1,k));
*p1=addVect(*p1,vectMult(vv,k));
*k1=max(*k1,k);
*n1=vect(-uu[0].x,-uu[0].y,-uu[0].z);
*b1=true;
}else return false;
}else{
if(uu2->x<-ss[0])
{
int32 k=divv(abs(uu1->x+ss[0]),abs(vv1.x));
*uu2=addVect(*uu1,vectMult(vv1,k));
*p2=addVect(*p1,vectMult(vv,k));
*k2=min(*k2,k);
*n2=vect(-uu[0].x,-uu[0].y,-uu[0].z);
*b2=true;
}
}
if(uu1->x<ss[0])
{
if(uu2->x>ss[0])
{
int32 k=divv(abs(uu1->x-ss[0]),abs(vv1.x));
*uu2=addVect(*uu1,vectMult(vv1,k));
*p2=addVect(*p1,vectMult(vv,k));
*k2=min(*k2,k);
*n2=(uu[0]);
*b2=true;
}
}else{
if(uu2->x<ss[0])
{
int32 k=divv(abs(uu1->x-ss[0]),abs(vv1.x));
*uu1=addVect(*uu1,vectMult(vv1,k));
*p1=addVect(*p1,vectMult(vv,k));
*k1=max(*k1,k);
*n1=(uu[0]);
*b1=true;
}else return false;
}
if(uu1->y<-ss[1])
{
if(uu2->y>-ss[1])
{
int32 k=divv(abs(uu1->y+ss[1]),abs(vv1.y));
*uu1=addVect(*uu1,vectMult(vv1,k));
*p1=addVect(*p1,vectMult(vv,k));
*k1=max(*k1,k);
*n1=vect(-uu[1].x,-uu[1].y,-uu[1].z);
*b1=true;
}else return false;
}else{
if(uu2->y<-ss[1])
{
int32 k=divv(abs(uu1->y+ss[1]),abs(vv1.y));
*uu2=addVect(*uu1,vectMult(vv1,k));
*p2=addVect(*p1,vectMult(vv,k));
*k2=min(*k2,k);
*n2=vect(-uu[1].x,-uu[1].y,-uu[1].z);
*b2=true;
}
}
if(uu1->y<ss[1])
{
if(uu2->y>ss[1])
{
int32 k=divv(abs(uu1->y-ss[1]),abs(vv1.y));
*uu2=addVect(*uu1,vectMult(vv1,k));
*p2=addVect(*p1,vectMult(vv,k));
*k2=min(*k2,k);
*n2=(uu[1]);
*b2=true;
}
}else{
if(uu2->y<ss[1])
{
int32 k=divv(abs(uu1->y-ss[1]),abs(vv1.y));
*uu1=addVect(*uu1,vectMult(vv1,k));
*p1=addVect(*p1,vectMult(vv,k));
*k1=max(*k1,k);
*n1=(uu[1]);
*b1=true;
}else return false;
}
if(uu1->z<-ss[2])
{
if(uu2->z>-ss[2])
{
int32 k=divv(abs(uu1->z+ss[2]),abs(vv1.z));
*uu1=addVect(*uu1,vectMult(vv1,k));
*p1=addVect(*p1,vectMult(vv,k));
*k1=max(*k1,k);
*n1=vect(-uu[2].x,-uu[2].y,-uu[2].z);
*b1=true;
}else return false;
}else{
if(uu2->z<-ss[2])
{
int32 k=divv(abs(uu1->z+ss[2]),abs(vv1.z));
*uu2=addVect(*uu1,vectMult(vv1,k));
*p2=addVect(*p1,vectMult(vv,k));
*k2=min(*k2,k);
*n2=vect(-uu[2].x,-uu[2].y,-uu[2].z);
*b2=true;
}
}
if(uu1->z<ss[2])
{
if(uu2->z>ss[2])
{
int32 k=divv(abs(uu1->z-ss[2]),abs(vv1.z));
*uu2=addVect(*uu1,vectMult(vv1,k));
*p2=addVect(*p1,vectMult(vv,k));
*k2=min(*k2,k);
*n2=(uu[2]);
*b2=true;
}
}else{
if(uu2->z<ss[2])
{
int32 k=divv(abs(uu1->z-ss[2]),abs(vv1.z));
*uu1=addVect(*uu1,vectMult(vv1,k));
*p1=addVect(*p1,vectMult(vv,k));
*k1=max(*k1,k);
*n1=(uu[2]);
*b1=true;
}else return false;
}
return true;
}
void collideOBBs(OBB_struct* o1, OBB_struct* o2)
{
if(!o1 || !o2)return;
if(o1==o2)return;
if(!collideAABB(vect(o1->AABBo.x-MAXPENETRATIONBOX,o1->AABBo.y-MAXPENETRATIONBOX,o1->AABBo.z-MAXPENETRATIONBOX),
vect(o1->AABBs.x+2*MAXPENETRATIONBOX,o1->AABBs.y+2*MAXPENETRATIONBOX,o1->AABBs.z+2*MAXPENETRATIONBOX),
vect(o2->AABBo.x-MAXPENETRATIONBOX,o2->AABBo.y-MAXPENETRATIONBOX,o2->AABBo.z-MAXPENETRATIONBOX),
vect(o2->AABBs.x+2*MAXPENETRATIONBOX,o2->AABBs.y+2*MAXPENETRATIONBOX,o2->AABBs.z+2*MAXPENETRATIONBOX)))return;
vect3D v[8],v2[8];
getOBBVertices(o1,v);
vect3D z1=vect(o1->transformationMatrix[0],o1->transformationMatrix[3],o1->transformationMatrix[6]);
vect3D z2=vect(o1->transformationMatrix[1],o1->transformationMatrix[4],o1->transformationMatrix[7]);
vect3D z3=vect(o1->transformationMatrix[2],o1->transformationMatrix[5],o1->transformationMatrix[8]);
vect3D u1=vect(o2->transformationMatrix[0],o2->transformationMatrix[3],o2->transformationMatrix[6]);
vect3D u2=vect(o2->transformationMatrix[1],o2->transformationMatrix[4],o2->transformationMatrix[7]);
vect3D u3=vect(o2->transformationMatrix[2],o2->transformationMatrix[5],o2->transformationMatrix[8]);
vect3D pp=vectDifference(o1->position,o2->position);
getVertices(o1->size, vect(dotProduct(pp,u1),dotProduct(pp,u2),dotProduct(pp,u3)), vect(dotProduct(z1,u1),dotProduct(z1,u2),dotProduct(z1,u3)),
vect(dotProduct(z2,u1),dotProduct(z2,u2),dotProduct(z2,u3)), vect(dotProduct(z3,u1),dotProduct(z3,u2),dotProduct(z3,u3)), v2);
int i;
/*for(i=0;i<8;i++)
{
//v2[i]=vectDifference(v[i],o2->position);
//v2[i]=vect(dotProduct(v2[i],u1),dotProduct(v2[i],u2),dotProduct(v2[i],u3));
if(v2[i].x>-o2->size.x-MAXPENETRATIONBOX && v2[i].x<o2->size.x+MAXPENETRATIONBOX
&& v2[i].y>-o2->size.y-MAXPENETRATIONBOX && v2[i].y<o2->size.y+MAXPENETRATIONBOX
&& v2[i].z>-o2->size.z-MAXPENETRATIONBOX && v2[i].z<o2->size.z+MAXPENETRATIONBOX)
{
vect3D n;
vect3D p=projectPointAABB(o2->size,v2[i],&n);
o1->contactPoints[o1->numContactPoints].point=v[i];
o1->contactPoints[o1->numContactPoints].normal=normalize(vect(n.x*u1.x+n.y*u2.x+n.z*u3.x,n.x*u1.y+n.y*u2.y+n.z*u3.y,n.x*u1.z+n.y*u2.z+n.z*u3.z));
if(abs(n.x)+abs(n.y)+abs(n.z)!=1)
{
printf("erf\n");
}
o1->contactPoints[o1->numContactPoints].penetration=distance(v2[i],p);
o1->contactPoints[o1->numContactPoints].penetration=0;
o1->contactPoints[o1->numContactPoints].target=o2;
o1->contactPoints[o1->numContactPoints].type=BOXCOLLISION;
o1->maxPenetration=max(o1->maxPenetration,o1->contactPoints[o1->numContactPoints].penetration);
o1->numContactPoints++;
}
}*/
//optimize by working in o2 space ?
int j;
vect3D vv2[8];
getOBBVertices(o2,vv2);
vect3D u[3];
u[0]=vect(o1->transformationMatrix[0],o1->transformationMatrix[3],o1->transformationMatrix[6]);
u[1]=vect(o1->transformationMatrix[1],o1->transformationMatrix[4],o1->transformationMatrix[7]);
u[2]=vect(o1->transformationMatrix[2],o1->transformationMatrix[5],o1->transformationMatrix[8]);
vect3D uu[3];
uu[0]=vect(o2->transformationMatrix[0],o2->transformationMatrix[3],o2->transformationMatrix[6]);
uu[1]=vect(o2->transformationMatrix[1],o2->transformationMatrix[4],o2->transformationMatrix[7]);
uu[2]=vect(o2->transformationMatrix[2],o2->transformationMatrix[5],o2->transformationMatrix[8]);
int32 s[3];
s[0]=o1->size.x;
s[1]=o1->size.y;
s[2]=o1->size.z;
int32 ss[3];
ss[0]=o2->size.x;//+MAXPENETRATIONBOX;
ss[1]=o2->size.y;//+MAXPENETRATIONBOX;
ss[2]=o2->size.z;//+MAXPENETRATIONBOX;
for(i=0;i<NUMOBBSEGMENTS;i++)
{
vect3D uu1=v2[OBBSegments[i][0]];
vect3D uu2=v2[OBBSegments[i][1]];
const bool t=!((uu1.x<-ss[0] && uu2.x<-ss[0]) || (uu1.x>ss[0] && uu2.x>ss[0])
|| (uu1.y<-ss[1] && uu2.y<-ss[1]) || (uu1.y>ss[1] && uu2.y>ss[1])
|| (uu1.z<-ss[2] && uu2.z<-ss[2]) || (uu1.z>ss[2] && uu2.z>ss[2]));
if(t)
{
/*vect3D dir=u[OBBSegmentsPD[i][1]];
int32 l=s[OBBSegmentsPD[i][1]]*2;
u8 num=0;
o1->contactPoints[o1->numContactPoints].point=vect(0,0,0);
o1->contactPoints[o1->numContactPoints].normal=vect(0,0,0);
for(j=0;j<NUMOBBFACES;j++)
{
vect3D u1=uu[OBBFacesPDDN[j][1]];
vect3D u2=uu[OBBFacesPDDN[j][2]];
s8 d=OBBFacesPDDN[j][3];
vect3D n=uu[abs(d)-1];
if(d<0)n=vectMultInt(n,-1);
int32 s1=ss[OBBFacesPDDN[j][1]]*2;
int32 s2=ss[OBBFacesPDDN[j][2]]*2;
vect3D ip;
if(collideLineRectangle(vv2[OBBFacesPDDN[j][0]], u1, u2, n, s1, s2, v[OBBSegmentsPD[i][0]], dir, l, &ip))
{
o1->contactPoints[o1->numContactPoints].point=addVect(o1->contactPoints[o1->numContactPoints].point,ip);
o1->contactPoints[o1->numContactPoints].penetration=0;
o1->contactPoints[o1->numContactPoints].target=o2;
o1->contactPoints[o1->numContactPoints].type=TESTPOINT;
num++;
}
}
if(num)
{
o1->contactPoints[o1->numContactPoints].point=vectDivInt(o1->contactPoints[o1->numContactPoints].point,num);
vect3D vv=vectDifference(o1->contactPoints[o1->numContactPoints].point,o2->position);
vect3D n;
vv=vect(dotProduct(vv,u1),dotProduct(vv,u2),dotProduct(vv,u3));
vect3D p=projectPointAABB(o2->size,vv,&n);
//o1->contactPoints[o1->numContactPoints].normal=normalize(vect(n.x*u1.x+n.y*u2.x+n.z*u3.x,n.x*u1.y+n.y*u2.y+n.z*u3.y,n.x*u1.z+n.y*u2.z+n.z*u3.z));
o1->contactPoints[o1->numContactPoints].normal=(vect(n.x*u1.x+n.y*u2.x+n.z*u3.x,n.x*u1.y+n.y*u2.y+n.z*u3.y,n.x*u1.z+n.y*u2.z+n.z*u3.z));
o1->contactPoints[o1->numContactPoints].penetration=distance(vv,p);
//o1->numContactPoints++;
}
*/
do{
const vect3D vv=u[OBBSegmentsPD[i][1]];
const vect3D vv1=vect(dotProduct(vv,uu[0]),dotProduct(vv,uu[1]),dotProduct(vv,uu[2]));
vect3D p1=v[OBBSegments[i][0]];
vect3D p2=v[OBBSegments[i][1]];
vect3D n1=vect(0,0,0);
vect3D n2=vect(0,0,0);
int32 k1=0;
int32 k2=s[OBBSegmentsPD[i][1]]*2;
bool b1=false;
bool b2=false;
if(!clipSegmentOBB(ss,uu,&p1,&p2,vv,&uu1,&uu2,vv1,&n1,&n2,&b1,&b2,&k1,&k2))break;
if(b1&&b2)
{
//p1=addVect(p1,vectMult(vv,k1));
//p2=addVect(p2,vectMult(vv,k2));
o1->contactPoints[o1->numContactPoints].point=vectDivInt(addVect(p1,p2),2);
o1->contactPoints[o1->numContactPoints].type=TESTPOINT;
vect3D n;
vect3D oo=vectDivInt(addVect(uu1,uu2),2);
vect3D p=projectPointAABB(o2->size,oo,&n);
o1->contactPoints[o1->numContactPoints].normal=(vect(n.x*u1.x+n.y*u2.x+n.z*u3.x,n.x*u1.y+n.y*u2.y+n.z*u3.y,n.x*u1.z+n.y*u2.z+n.z*u3.z));
o1->contactPoints[o1->numContactPoints].penetration=distance(p,oo);
//o1->contactPoints[o1->numContactPoints].penetration=0;
o1->contactPoints[o1->numContactPoints].target=o2;
o1->numContactPoints++;
}else{
if(b1)
{
//p1=addVect(p1,vectMult(vv,k1));
o1->contactPoints[o1->numContactPoints].point=p1;
o1->contactPoints[o1->numContactPoints].type=TESTPOINT;
o1->contactPoints[o1->numContactPoints].normal=n1;
o1->contactPoints[o1->numContactPoints].penetration=0;
o1->contactPoints[o1->numContactPoints].target=o2;
o1->numContactPoints++;
}
if(b2)
{
//p2=addVect(p2,vectMult(vv,k2));
o1->contactPoints[o1->numContactPoints].point=p2;
o1->contactPoints[o1->numContactPoints].type=TESTPOINT;
o1->contactPoints[o1->numContactPoints].normal=n2;
o1->contactPoints[o1->numContactPoints].penetration=0;
o1->contactPoints[o1->numContactPoints].target=o2;
o1->numContactPoints++;
}
}
}while(0);
}
}
}
void initTransformationMatrix(int32* m)
{
if(!m)return;
int i;
for(i=0;i<9;i++)m[i]=0;
m[0]=inttof32(1);
m[4]=inttof32(1);
m[8]=inttof32(1);
}
void getVertices(vect3D s, vect3D p, vect3D u1, vect3D u2, vect3D u3, vect3D* v)
{
int32 m2[9];
m2[0]=mulf32(u1.x,s.x);m2[3]=mulf32(u1.y,s.x);m2[6]=mulf32(u1.z,s.x);
m2[1]=mulf32(u2.x,s.y);m2[4]=mulf32(u2.y,s.y);m2[7]=mulf32(u2.z,s.y);
m2[2]=mulf32(u3.x,s.z);m2[5]=mulf32(u3.y,s.z);m2[8]=mulf32(u3.z,s.z);
v[0]=vect(-m2[0]-m2[1]-m2[2],-m2[3]-m2[4]-m2[5],-m2[6]-m2[7]-m2[8]);
v[1]=vect(m2[0]-m2[1]-m2[2],m2[3]-m2[4]-m2[5],m2[6]-m2[7]-m2[8]);
v[2]=vect(m2[0]-m2[1]+m2[2],m2[3]-m2[4]+m2[5],m2[6]-m2[7]+m2[8]);
v[3]=vect(-m2[0]-m2[1]+m2[2],-m2[3]-m2[4]+m2[5],-m2[6]-m2[7]+m2[8]);
v[4]=vect(-v[1].x,-v[1].y,-v[1].z);
v[5]=vect(-v[2].x,-v[2].y,-v[2].z);
v[6]=vect(-v[3].x,-v[3].y,-v[3].z);
v[7]=vect(-v[0].x,-v[0].y,-v[0].z);
v[0]=addVect(v[0],p);v[1]=addVect(v[1],p);v[2]=addVect(v[2],p);v[3]=addVect(v[3],p);
v[4]=addVect(v[4],p);v[5]=addVect(v[5],p);v[6]=addVect(v[6],p);v[7]=addVect(v[7],p);
}
void getOBBVertices(OBB_struct* o, vect3D* v)
{
if(!o || !v)return;
int32* m=o->transformationMatrix;
getVertices(o->size,o->position,vect(m[0],m[3],m[6]),vect(m[1],m[4],m[7]),vect(m[2],m[5],m[8]),v);
int i;
vect3D mm=o->position;
vect3D M=o->position;
for(i=0;i<8;i++)
{
//v[i]=addVect(v[i],o->position);
if(v[i].x<mm.x)mm.x=v[i].x;
if(v[i].y<mm.y)mm.y=v[i].y;
if(v[i].z<mm.z)mm.z=v[i].z;
if(v[i].x>M.x)M.x=v[i].x;
if(v[i].y>M.y)M.y=v[i].y;
if(v[i].z>M.z)M.z=v[i].z;
}
o->AABBo=mm;
o->AABBs=vectDifference(M,mm);
}
void applyOBBForce(OBB_struct* o, vect3D p, vect3D f)
{
if(!o)return;
o->forces=addVect(o->forces,f);
o->moment=addVect(o->moment,vectProduct(vectDifference(p,o->position),f));
}
void applyOBBImpulsePlane(OBB_struct* o, u8 pID)
{
if(!o || pID>=o->numContactPoints)return;
contactPoint_struct* cp=&o->contactPoints[pID];
vect3D r=vectDifference(cp->point,o->position);
vect3D v=addVect(o->velocity,vectProduct(o->angularVelocity,r));
const int32 CoefficientOfRestitution=floattof32(0.2f);
int32 iN=-mulf32((floattof32(1)+CoefficientOfRestitution),dotProduct(v,cp->normal));
//int32 invMass=divf32(inttof32(1),o->mass);
int32 invMass=divv16(inttof32(1),o->mass);
int32 iD=invMass+dotProduct(vectProduct(evalVectMatrix33(o->invWInertiaMatrix,vectProduct(r,cp->normal)),r),cp->normal);
//iN=divf32(iN,iD);
iN=divv16(iN,iD);
if(iN<0)iN=0;
//vect3D imp=vectMult(cp->normal,iN);
vect3D imp=vectMult(cp->normal,iN+cp->penetration/2); //added bias adds jitter, but prevents sinking.
//printf("imp : %d",iN);
// apply impulse to primary quantities
o->velocity=addVect(o->velocity,vectMult(imp,invMass));
o->angularMomentum=addVect(o->angularMomentum,vectProduct(r,imp));
// compute affected auxiliary quantities
o->angularVelocity=evalVectMatrix33(o->invWInertiaMatrix,o->angularMomentum);
{
vect3D tangent=vect(0,0,0);
tangent=vectDifference(v,(vectMult(cp->normal,dotProduct(v, cp->normal))));
if(magnitude(tangent)<1)return;
tangent=normalize(tangent);
int32 kTangent=invMass+dotProduct(tangent,vectProduct(evalVectMatrix33(o->invWInertiaMatrix,(vectProduct(r, tangent))), r));
int32 vt = dotProduct(v, tangent);
//int32 dPt = divf32((-vt),kTangent);
int32 dPt = divv16((-vt),kTangent);
const int32 frictionCONST=floattof32(1.0f);
int32 maxPt=abs(mulf32(frictionCONST,iN));
if(dPt<-maxPt)dPt=-maxPt;
else if(dPt>maxPt)dPt=maxPt;
// Apply contact impulse
vect3D P = vectMult(tangent,dPt);
o->velocity=addVect(o->velocity,vectMult(P,invMass));
o->angularMomentum=addVect(o->angularMomentum,vectProduct(r,P));
// compute affected auxiliary quantities
o->angularVelocity=evalVectMatrix33(o->invWInertiaMatrix,o->angularMomentum);
}
}
void applyOBBImpulseOBB(OBB_struct* o, u8 pID)
{
if(!o || pID>=o->numContactPoints)return;
contactPoint_struct* cp=&o->contactPoints[pID];
OBB_struct* o2=(OBB_struct*)cp->target;
if(!o2)return;
vect3D r1=vectDifference(cp->point,o->position);
vect3D r2=vectDifference(cp->point,o2->position);
vect3D v1=addVect(o->velocity,vectProduct(o->angularVelocity,r1));
vect3D v2=addVect(o2->velocity,vectProduct(o2->angularVelocity,r2));
vect3D dv=vectDifference(v1,v2);
const int32 CoefficientOfRestitution=floattof32(0.5f);
int32 iN=-mulf32((floattof32(1)+CoefficientOfRestitution),dotProduct(dv,cp->normal));
//int32 invMass1=divf32(inttof32(1),o->mass);
//int32 invMass2=divf32(inttof32(1),o2->mass);
int32 invMass1=divv16(inttof32(1),o->mass);
int32 invMass2=divv16(inttof32(1),o2->mass);
int32 iD=invMass1+invMass2+dotProduct(addVect(vectProduct(evalVectMatrix33(o->invWInertiaMatrix,vectProduct(r1,cp->normal)),r1),vectProduct(evalVectMatrix33(o2->invWInertiaMatrix,vectProduct(r2,cp->normal)),r2)),cp->normal);
//iN=divf32(iN,iD);
iN=divv16(iN,iD);
if(iN<0)iN=0;
//vect3D imp=vectMult(cp->normal,iN);
vect3D imp=vectMult(cp->normal,iN+cp->penetration); //added bias adds jitter, but prevents sinking.
//printf("norm : %d %d %d\n",cp->normal.x,cp->normal.y,cp->normal.z);
// apply impulse to primary quantities
o->velocity=addVect(o->velocity,vectMult(imp,invMass1));
o->angularMomentum=addVect(o->angularMomentum,vectProduct(r1,imp));
o2->velocity=vectDifference(o2->velocity,vectMult(imp,invMass2));
o2->angularMomentum=vectDifference(o2->angularMomentum,vectProduct(r2,imp));
// compute affected auxiliary quantities
o->angularVelocity=evalVectMatrix33(o->invWInertiaMatrix,o->angularMomentum);
o2->angularVelocity=evalVectMatrix33(o2->invWInertiaMatrix,o2->angularMomentum);
{
vect3D tangent=vect(0,0,0);
tangent=vectDifference(dv,(vectMult(cp->normal,dotProduct(dv, cp->normal))));
if(magnitude(tangent)<1)return;
tangent=normalize(tangent);
int32 kTangent=invMass1+invMass2+dotProduct(tangent,addVect(vectProduct(evalVectMatrix33(o->invWInertiaMatrix,(vectProduct(r1, tangent))), r1),
vectProduct(evalVectMatrix33(o->invWInertiaMatrix,(vectProduct(r2, tangent))), r2)));
int32 vt = dotProduct(dv, tangent);
//int32 dPt = divf32((-vt),kTangent);
int32 dPt = divv16((-vt),kTangent);
const int32 frictionCONST=floattof32(0.5f);
int32 maxPt=abs(mulf32(frictionCONST,iN));
if(dPt<-maxPt)dPt=-maxPt;
else if(dPt>maxPt)dPt=maxPt;
// Apply contact impulse
vect3D P = vectMult(tangent,dPt);
o->velocity=addVect(o->velocity,vectMult(P,invMass1));
o->angularMomentum=addVect(o->angularMomentum,vectProduct(r1,P));
o2->velocity=vectDifference(o2->velocity,vectMult(P,invMass2));
o2->angularMomentum=vectDifference(o2->angularMomentum,vectProduct(r2,P));
// compute affected auxiliary quantities
o->angularVelocity=evalVectMatrix33(o->invWInertiaMatrix,o->angularMomentum);
o2->angularVelocity=evalVectMatrix33(o2->invWInertiaMatrix,o2->angularMomentum);
}
}
void applyOBBImpulses(OBB_struct* o)
{
if(!o)return;
int i;
for(i=0;i<o->numContactPoints;i++)
{
switch(o->contactPoints[i].type)
{
case PLANECOLLISION:
applyOBBImpulsePlane(o,i);
break;
case AARCOLLISION:
applyOBBImpulsePlane(o,i);
break;
case BOXCOLLISION:
// printf("collision ! %d",i);
//applyOBBImpulseOBB(o,i);
break;
case TESTPOINT:
// printf("test collision ! %d",i);
applyOBBImpulseOBB(o,i);
break;
}
}
}
void integrate(OBB_struct* o, float dt)
{
if(!o)return;
//o->position=addVect(o->position,vectMult(o->velocity,dt));
//o->position=addVect(o->position,vect(mulf32(o->velocity.x,dt)>>TIMEPREC,mulf32(o->velocity.y,dt)>>TIMEPREC,mulf32(o->velocity.z,dt)>>TIMEPREC));
//o->position=addVect(o->position,vect((mulf32((o->velocity.x+o->oldVelocity.x)/2,dt)>>TIMEPREC),
// (mulf32((o->velocity.y+o->oldVelocity.y)/2,dt)>>TIMEPREC),
// (mulf32((o->velocity.z+o->oldVelocity.z)/2,dt)>>TIMEPREC)));
o->position=addVect(o->position,vect(o->velocity.x*dt,o->velocity.y*dt,o->velocity.z*dt));
int32 m[9], m2[9];
//m[0]=0;m[1]=-(mulf32(dt,o->angularVelocity.z));m[2]=(mulf32(dt,o->angularVelocity.y));
//m[3]=-m[1];m[4]=0;m[5]=-(mulf32(dt,o->angularVelocity.x));
//m[0]=0;m[1]=-(mulf32(dt,o->angularVelocity.z)>>TIMEPREC);m[2]=(mulf32(dt,o->angularVelocity.y)>>TIMEPREC);
//m[3]=-m[1];m[4]=0;m[5]=-(mulf32(dt,o->angularVelocity.x)>>TIMEPREC);
//m[0]=0;m[1]=-((mulf32(dt,(o->angularVelocity.z+o->oldAngularVelocity.z)/2)>>TIMEPREC));m[2]=((mulf32(dt,(o->angularVelocity.y+o->oldAngularVelocity.y)/2)>>TIMEPREC));
//m[3]=-m[1];m[4]=0;m[5]=-((mulf32(dt,(o->angularVelocity.x+o->oldAngularVelocity.x)/2)>>TIMEPREC));
m[0]=0;m[1]=-((dt*o->angularVelocity.z));m[2]=((dt*o->angularVelocity.y));
m[3]=-m[1];m[4]=0;m[5]=-((dt*o->angularVelocity.x));
m[6]=-m[2];m[7]=-m[5];m[8]=0;
multMatrix33(m,o->transformationMatrix,m2);
addMatrix33(o->transformationMatrix,m2,o->transformationMatrix);
//o->velocity=addVect(o->velocity,divideVect(vectMult(o->forces,dt),o->mass));
//o->velocity=addVect(o->velocity,divideVect(vect(mulf32(o->forces.x,dt)>>TIMEPREC,mulf32(o->forces.y,dt)>>TIMEPREC,mulf32(o->forces.z,dt)>>TIMEPREC),o->mass));
//o->velocity=addVect(o->velocity,divideVect(vect((mulf32((o->forces.x+o->oldForces.x)/2,dt)>>TIMEPREC),
// (mulf32((o->forces.y+o->oldForces.y)/2,dt)>>TIMEPREC),
// (mulf32((o->forces.z+o->oldForces.z)/2,dt)>>TIMEPREC)),o->mass));
o->velocity=addVect(o->velocity,divideVect(vect(o->forces.x*dt,o->forces.y*dt,o->forces.z*dt),o->mass));
//o->angularMomentum=addVect(o->angularMomentum,vectMult(o->moment,dt));
//o->angularMomentum=addVect(o->angularMomentum,vect(mulf32(o->moment.x,dt)>>TIMEPREC,mulf32(o->moment.y,dt)>>TIMEPREC,mulf32(o->moment.z,dt)>>TIMEPREC));
//o->angularMomentum=addVect(o->angularMomentum,vect((mulf32((o->moment.x+o->oldMoment.x)/2,dt)>>TIMEPREC),
// (mulf32((o->moment.y+o->oldMoment.y)/2,dt)>>TIMEPREC),
// (mulf32((o->moment.z+o->oldMoment.z)/2,dt)>>TIMEPREC)));
o->angularMomentum=addVect(o->angularMomentum,vect(o->moment.x*dt,o->moment.y*dt,o->moment.z*dt));
fixMatrix(o->transformationMatrix);
// compute auxiliary quantities
transposeMatrix33(o->transformationMatrix,m2);
multMatrix33(m2,o->invInertiaMatrix,m);
multMatrix33(m,o->transformationMatrix,o->invWInertiaMatrix);
o->angularVelocity=evalVectMatrix33(o->invWInertiaMatrix,o->angularMomentum);
}
extern plane_struct testPlane;
extern OBB_struct *testOBB, *testOBB2;
void checkOBBCollisions(OBB_struct* o)
{
if(!o)return;
int i;
o->numContactPoints=0;
// planeOBBContacts(&testPlane,o);
for(i=0;i<NUMOBJECTS;i++)
{
if(objects[i].used && o!=&objects[i])
{
collideOBBs(o,&objects[i]);
}
}
AARsOBBContacts(o);
}
void simulate(OBB_struct* o, float dt2)
{
if(!o)return;
//int32 dt=(dt2)<<TIMEPREC;
float dt=f32tofloat(dt2);
float currentTime=0;
float targetTime=dt;
applyOBBForce(o,o->position,vect(0,-inttof32(2),0)); //gravity
o->forces=addVect(o->forces,vectDivInt(o->velocity,-25));
o->moment=addVect(o->moment,vectDivInt(o->angularVelocity,-20));
while(currentTime<dt)
{
OBB_struct bkp;
copyOBB(o,&bkp);
cpuStartTiming(0);
integrate(o,targetTime-currentTime);
integ+=cpuEndTiming();
cpuStartTiming(0);
checkOBBCollisions(o);
coll+=cpuEndTiming();
cpuStartTiming(0);
if(o->numContactPoints && o->maxPenetration>PENETRATIONTHRESHOLD)
{
targetTime=(currentTime+targetTime)/2;
copyOBB(&bkp,o);
if(targetTime-currentTime<=0.000001f)
{
// printf("desp impulse\n");
checkOBBCollisions(o);
applyOBBImpulses(o);
currentTime=targetTime;
targetTime=dt;
}
}else if(o->numContactPoints)
{
// printf("impulse\n");
applyOBBImpulses(o);
currentTime=targetTime;
targetTime=dt;
}else{
currentTime=targetTime;
targetTime=dt;
}
impul+=cpuEndTiming();
}
o->forces=vect(0,0,0);
o->moment=vect(0,0,0);
}
void warpMatrix(portal_struct* p, int32* m) //3x3
{
if(!m)return;
vect3D x=warpVector(p,vect(m[0],m[3],m[6]));
vect3D y=warpVector(p,vect(m[1],m[4],m[7]));
vect3D z=warpVector(p,vect(m[2],m[5],m[8]));
m[0]=x.x;m[3]=x.y;m[6]=x.z;
m[1]=y.x;m[4]=y.y;m[7]=y.z;
m[2]=z.x;m[5]=z.y;m[8]=z.z;
}
void updateOBBPortals(OBB_struct* o, u8 id, bool init)
{
if(!o&&id<2)return;
o->oldPortal[id]=o->portal[id];
o->portal[id]=dotProduct(vectDifference(o->position,portal[id].position),portal[id].normal)>0; //add boundaries
switch(init)
{
case false:
if(o->oldPortal[id] && !o->portal[id])
{
o->position=addVect(portal[id].targetPortal->position,warpVector(&portal[id],vectDifference(o->position,portal[id].position)));
o->velocity=warpVector(&portal[id],o->velocity);
o->forces=warpVector(&portal[id],o->forces);
o->angularVelocity=warpVector(&portal[id],o->angularVelocity);
o->moment=warpVector(&portal[id],o->moment);
warpMatrix(&portal[id], o->transformationMatrix);
warpMatrix(&portal[id], o->invWInertiaMatrix);
}
break;
default:
o->oldPortal[id]=o->portal[id];
break;
}
}
void updateOBB(OBB_struct* o)
{
if(!o)return;
simulate(o,20);
updateOBBPortals(o,0,false);
updateOBBPortals(o,1,false);
}
void updateOBBs(void)
{
int i;
for(i=0;i<NUMOBJECTS;i++)
{
if(objects[i].used)
{
updateOBB(&objects[i]);
}
}
}
OBB_struct* createOBB(u8 id, vect3D size, vect3D position)
{
int i=id;
if(!objects[i].used)
{
initOBB(&objects[i],size,position);
return &objects[i];
}
return NULL;
}
void drawOBBs(void)
{
int i;
for(i=0;i<NUMOBJECTS;i++)
{
if(objects[i].used)
{
drawOBB(&objects[i]);
}
}
}
void drawOBB(OBB_struct* o)
{
}

195
arm7/source/PI7.c Normal file
View File

@ -0,0 +1,195 @@
#include "stdafx.h"
bool PI7running;
player_struct player;
portal_struct portal[2];
void initPI7(void)
{
initOBBs();
initAARs();
player.position=vect(0,0,0);
portal[0].targetPortal=&portal[1];
portal[1].targetPortal=&portal[0];
PI7running=false;
}
bool getPI7Status(void)
{
return PI7running;
}
void listenPI7(void)
{
while(fifoCheckValue32(FIFO_USER_08))
{
u32 signal=fifoGetValue32(FIFO_USER_08);
switch(signal&PISIGNALMASK)
{
case PI_START:
PI7running=true;
break;
case PI_PAUSE:
PI7running=false;
break;
case PI_STOP:
PI7running=false;
break;
case PI_RESET:
initOBBs();
PI7running=true;
break;
case PI_ADDBOX:
{
vect3D pos, size;
u32 mass;
u8 id=signal>>PISIGNALDATA;
while(!fifoCheckValue32(FIFO_USER_08));
u32 x=fifoGetValue32(FIFO_USER_08);
size.x=x&((1<<16)-1);
size.y=(x>>16)&((1<<16)-1);
while(!fifoCheckValue32(FIFO_USER_08));
x=fifoGetValue32(FIFO_USER_08);
size.z=x&((1<<16)-1);
mass=(x>>16)&((1<<16)-1);
while(!fifoCheckValue32(FIFO_USER_08));
pos.x=fifoGetValue32(FIFO_USER_08);
while(!fifoCheckValue32(FIFO_USER_08));
pos.y=fifoGetValue32(FIFO_USER_08);
while(!fifoCheckValue32(FIFO_USER_08));
pos.z=fifoGetValue32(FIFO_USER_08);
createOBB(id,size,pos);
}
break;
case PI_APPLYFORCE:
{
vect3D pos, v;
u8 id=signal>>PISIGNALDATA;
while(!fifoCheckValue32(FIFO_USER_08));
u32 x=fifoGetValue32(FIFO_USER_08);
pos.x=(s16)x;
pos.y=(s16)(x>>16);
while(!fifoCheckValue32(FIFO_USER_08));
x=fifoGetValue32(FIFO_USER_08);
pos.z=(s16)x;
while(!fifoCheckValue32(FIFO_USER_08));
v.x=fifoGetValue32(FIFO_USER_08);
while(!fifoCheckValue32(FIFO_USER_08));
v.y=fifoGetValue32(FIFO_USER_08);
while(!fifoCheckValue32(FIFO_USER_08));
v.z=fifoGetValue32(FIFO_USER_08);
if(id<NUMOBJECTS && objects[id].used)applyOBBForce(&objects[id],addVect(objects[id].position,pos),v);
}
break;
case PI_ADDAAR:
{
vect3D pos, size;
vect3D normal=vect(0,0,0);
u8 id=signal>>PISIGNALDATA;
while(!fifoCheckValue32(FIFO_USER_08));
u32 x=fifoGetValue32(FIFO_USER_08);
size.x=x&((1<<16)-1);
size.y=(x>>16)&((1<<16)-1);
while(!fifoCheckValue32(FIFO_USER_08));
x=fifoGetValue32(FIFO_USER_08);
size.z=x&((1<<16)-1);
x=x>>16;
if(x&1)normal.x=-inttof32(1);
else if(x&2)normal.x=inttof32(1);
if(x&4)normal.y=-inttof32(1);
else if(x&8)normal.y=inttof32(1);
if(x&16)normal.z=-inttof32(1);
else if(x&32)normal.z=inttof32(1);
while(!fifoCheckValue32(FIFO_USER_08));
pos.x=fifoGetValue32(FIFO_USER_08);
while(!fifoCheckValue32(FIFO_USER_08));
pos.y=fifoGetValue32(FIFO_USER_08);
while(!fifoCheckValue32(FIFO_USER_08));
pos.z=fifoGetValue32(FIFO_USER_08);
createAAR(id,pos,size,normal);
}
break;
case PI_MAKEGRID:
generateGrid(NULL);
break;
case PI_SETVELOCITY:
{
vect3D v;
u8 id=signal>>PISIGNALDATA;
while(!fifoCheckValue32(FIFO_USER_08));
v.x=fifoGetValue32(FIFO_USER_08);
while(!fifoCheckValue32(FIFO_USER_08));
v.y=fifoGetValue32(FIFO_USER_08);
while(!fifoCheckValue32(FIFO_USER_08));
v.z=fifoGetValue32(FIFO_USER_08);
if(id<NUMOBJECTS && objects[id].used)objects[id].velocity=v;
}
break;
case PI_UPDATEPLAYER:
{
vect3D v;
while(!fifoCheckValue32(FIFO_USER_08));
v.x=fifoGetValue32(FIFO_USER_08);
while(!fifoCheckValue32(FIFO_USER_08));
v.y=fifoGetValue32(FIFO_USER_08);
while(!fifoCheckValue32(FIFO_USER_08));
v.z=fifoGetValue32(FIFO_USER_08);
player.position=v;
}
break;
case PI_UPDATEPORTAL:
{
vect3D pos;
vect3D normal=vect(0,0,0);
u8 id=signal>>PISIGNALDATA;
while(!fifoCheckValue32(FIFO_USER_08));
pos.x=fifoGetValue32(FIFO_USER_08);
while(!fifoCheckValue32(FIFO_USER_08));
pos.y=fifoGetValue32(FIFO_USER_08);
while(!fifoCheckValue32(FIFO_USER_08));
pos.z=fifoGetValue32(FIFO_USER_08);
while(!fifoCheckValue32(FIFO_USER_08));
u32 x=fifoGetValue32(FIFO_USER_08);
if(x&1)normal.x=-inttof32(1);
else if(x&2)normal.x=inttof32(1);
if(x&4)normal.y=-inttof32(1);
else if(x&8)normal.y=inttof32(1);
if(x&16)normal.z=-inttof32(1);
else if(x&32)normal.z=inttof32(1);
if(id<2)
{
portal[id].position=pos;
portal[id].normal=normal;
portal[id].cos=inttof32(1);
portal[id].sin=0;
computePortalPlane(&portal[id]);
}
}
break;
default:
while(fifoCheckValue32(FIFO_USER_08))fifoGetValue32(FIFO_USER_08);
break;
}
}
}
void sendDataPI7(void)
{
int i;
for(i=0;i<NUMOBJECTS;i++)
{
if(objects[i].used)
{
fifoSendValue32(FIFO_USER_01,i);
fifoSendValue32(FIFO_USER_02,objects[i].position.x);
fifoSendValue32(FIFO_USER_03,objects[i].position.y);
fifoSendValue32(FIFO_USER_04,objects[i].position.z);
fifoSendValue32(FIFO_USER_05,((objects[i].transformationMatrix[3]+4096)<<16)|((u16)objects[i].transformationMatrix[0]+4096));
fifoSendValue32(FIFO_USER_06,((objects[i].transformationMatrix[1]+4096)<<16)|((u16)objects[i].transformationMatrix[6]+4096));
fifoSendValue32(FIFO_USER_07,((objects[i].transformationMatrix[7]+4096)<<16)|((u16)objects[i].transformationMatrix[4]+4096));
}
}
}

View File

@ -0,0 +1,85 @@
@ ------------------------------------------------------------------------------
@
@ This function can be used to output No$gba debug messages.
@
@ Author: Peter Schraut (www.console-dev.de)
@ Date..: 2005-Jan-20
@
@ extern "C" int N3DNoCashMsg(const char *pText);
@
@ ------------------------------------------------------------------------------
@
@ Copyright 2005-2007 by Peter Schraut www.console-dev.de
@
@ This file is distributed as freeware.
@
@ You are free to use it as part of your program for any purpose including
@ freeware, shareware and commercial programs.
@
@ The origin of this software must not be misrepresented; you must not claim your
@ authorship. All redistributions must retain the original copyright notice and web
@ site addresses.
@
@ Commercial redistribution of this file is allowed only with an explicit written
@ permission from the author.
@
@ This software is provided 'as-is', without warranty of any kind, either expressed or
@ implied. In no event shall the author be held liable for any damages arising from the
@ use of this software.
@
@ ------------------------------------------------------------------------------
@.section .iwram,"ax",%progbits
.arm
.align 4
.global N3DNoCashMsg
.type N3DNoCashMsg, %function
@ r0 = Text
@ r1 = Address of target buffer
@ r2 = Maximum amount of characters, descrements each iteration
@ r3 = Current char of text
.equiv BUFFER_SIZE, 120
N3DNoCashMsg:
stmfd sp!, {r1-r3}
adr r1, .Buffer @ Get target buffer address
mov r2, #BUFFER_SIZE @ Maximum amount of supported characters
@ This loop copies the incoming data into the
@ Buffer below. If it encounters a NULL-terminator
@ or is beyond the 120th character, it will break.
.Loop:
ldrb r3, [r0], #1 @ Load current byte from text
strb r3, [r1], #1 @ Store currrent byte into Buffer
subs r2, r2, #1 @ One further byte added
cmpne r3, #0 @ Came across a NULL-terminator?
beq .MsgTag @ Last Char or NULL-terminator? Then branch to MsgTag
b .Loop @ Just loop
@ Here starts the actual no$gba Message Tag
.MsgTag:
mov r12, r12 @ First no$gba ID
b .Continue
.short 0x6464 @ Second no$gba ID
.short 0 @ Reserved for flags
.Buffer:
.space BUFFER_SIZE @ 120 bytes for the message
.byte 0 @ Trailing zero as NULL-Terminator
.align 4
.Continue:
ldr r0, =(BUFFER_SIZE-1) @ Return length of Text without NULL-terminator
sub r0, r0, r2
ldmfd sp!, {r1-r3}
bx lr
.align 4
.size N3DNoCashMsg, .-N3DNoCashMsg

51
arm7/source/plane.c Normal file
View File

@ -0,0 +1,51 @@
#include "stdafx.h"
void initPlane(plane_struct* pl, int32 A, int32 B, int32 C, int32 D)
{
if(!pl)return;
pl->A=A;pl->B=B;pl->C=C;pl->D=D;
int32 r=magnitude(vect(A,B,C));
pl->A=divv16(pl->A,r);
pl->B=divv16(pl->B,r);
pl->C=divv16(pl->C,r);
pl->D=divv16(pl->D,r);
pl->point.x=-mulf32(pl->D,pl->A);
pl->point.y=-mulf32(pl->D,pl->B);
pl->point.z=-mulf32(pl->D,pl->C);
}
vect3D intersectSegmentPlane(plane_struct* pl, vect3D o, vect3D v, int32 d)
{
if(!pl)return o;
vect3D n=vect(pl->A,pl->B,pl->C);
int32 p1=dotProduct(v,n);
vect3D p=pl->point;
int32 p2=dotProduct(vectDifference(p,o),n);
int32 k=divv16(p2,p1);
return addVect(o,vectMult(v,k));
}
void planeOBBContacts(plane_struct* p, OBB_struct* o)
{
if(!p || !o)return;
int i;
vect3D v[8];
getOBBVertices(o,v);
o->maxPenetration=0;
o->numContactPoints=0;
for(i=0;i<8;i++)
{
int32 val1=evaluatePlanePoint(p,v[i]);
if(val1<=PENETRATIONTHRESHOLD)
{
o->contactPoints[o->numContactPoints].point=v[i];
o->contactPoints[o->numContactPoints].normal=vect(p->A,p->B,p->C);
o->contactPoints[o->numContactPoints].penetration=abs(val1);
o->contactPoints[o->numContactPoints].target=p;
o->contactPoints[o->numContactPoints].type=PLANECOLLISION;
o->maxPenetration=max(o->maxPenetration,-(min(val1,0)));
o->numContactPoints++;
}
}
}

130
arm7/source/template.c Normal file
View File

@ -0,0 +1,130 @@
/*---------------------------------------------------------------------------------
default ARM7 core
Copyright (C) 2005 - 2010
Michael Noland (joat)
Jason Rogers (dovoto)
Dave Murphy (WinterMute)
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you
must not claim that you wrote the original software. If you use
this software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
---------------------------------------------------------------------------------*/
#include <nds.h>
#include "stdafx.h"
u32 cnt=0;
//---------------------------------------------------------------------------------
void VblankHandler(void) {
//---------------------------------------------------------------------------------
// Wifi_Update();
}
//---------------------------------------------------------------------------------
void VcountHandler() {
//---------------------------------------------------------------------------------
inputGetAndSend();
// fifoSendValue32(FIFO_USER_05,cnt); //debug
}
volatile bool exitflag = false;
//---------------------------------------------------------------------------------
void powerButtonCB() {
//---------------------------------------------------------------------------------
exitflag = true;
}
OBB_struct *testOBB, *testOBB2;
plane_struct testPlane;
extern u32 coll, integ, impul;
//---------------------------------------------------------------------------------
int main() {
//---------------------------------------------------------------------------------
readUserSettings();
irqInit();
// Start the RTC tracking IRQ
initClockIRQ();
fifoInit();
// mmInstall(FIFO_MAXMOD);
SetYtrigger(80);
// installWifiFIFO();
// installSoundFIFO();
installSystemFIFO();
irqSet(IRQ_VCOUNT, VcountHandler);
irqSet(IRQ_VBLANK, VblankHandler);
irqEnable(IRQ_VBLANK | IRQ_VCOUNT);
setPowerButtonCB(powerButtonCB);
initPI7();
// initPlane(&testPlane, 0, inttof32(1), 0, inttof32(3)/2);
// createAAR(0, vect(-inttof32(0),-inttof32(1)/2,-inttof32(3)), vect(inttof32(6),0,inttof32(6)), vect(0,inttof32(1),0));
// createAAR(1, vect(-inttof32(0),-inttof32(1)/2-inttof32(6),-inttof32(3)), vect(0,inttof32(6),inttof32(6)), vect(-inttof32(1),0,0));
u32 tm=0;
u32 tm2=0;
while(!exitflag)
{
if(getPI7Status())
{
// cpuStartTiming(0);
coll=impul=integ=0;
updateOBBs();
updateOBBs();
updateOBBs();
updateOBBs();
updateOBBs();
// updateOBBs();
// updateOBBs();
// updateOBBs();
// updateOBBs();
// updateOBBs();
// fifoSendValue32(FIFO_USER_08,integ);
// fifoSendValue32(FIFO_USER_08,coll);
// fifoSendValue32(FIFO_USER_08,impul);
// fifoSendValue32(FIFO_USER_08,cpuEndTiming());
sendDataPI7();
// u32 key=REG_KEYINPUT;
// if(0==(key&(KEY_B)))applyOBBForce(&objects[0],addVect(testOBB->position,vect(-inttof32(1),0,0)),vect(0,inttof32(100),0));
}
listenPI7();
swiWaitForVBlank();
cnt++;
}
return 0;
}

BIN
arm9/.elf Normal file

Binary file not shown.

137
arm9/Makefile Normal file
View File

@ -0,0 +1,137 @@
#---------------------------------------------------------------------------------
.SUFFIXES:
#---------------------------------------------------------------------------------
ifeq ($(strip $(DEVKITARM)),)
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
endif
include $(DEVKITARM)/ds_rules
#---------------------------------------------------------------------------------
# BUILD is the directory where object files & intermediate files will be placed
# SOURCES is a list of directories containing source code
# INCLUDES is a list of directories containing extra header files
# DATA is a list of directories containing binary files
# all directories are relative to this makefile
#---------------------------------------------------------------------------------
BUILD := build
SOURCES := source source/debug source/game source/editor source/acotmenu
INCLUDES := include
DATA := data
MUSIC := maxmod_data
#---------------------------------------------------------------------------------
# options for code generation
#--------------------------------------------------------------------------------- -mthumb -mthumb-interwork
ARCH :=
CFLAGS := -save-temps -g -Wall -O3\
-march=armv5te -mtune=arm946e-s -fomit-frame-pointer\
-ffast-math \
$(ARCH)
CFLAGS += $(INCLUDE) -DARM9
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions
ASFLAGS := -g $(ARCH) -march=armv5te -mtune=arm946e-s
LDFLAGS = -specs=ds_arm9.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
#---------------------------------------------------------------------------------
# any extra libraries we wish to link with the project
#---------------------------------------------------------------------------------
LIBS := -lmm9 -lfilesystem -lfat -lnds9
#---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing
# include and lib
#---------------------------------------------------------------------------------
LIBDIRS := $(LIBNDS)
#---------------------------------------------------------------------------------
# no real need to edit anything past this point unless you need to add additional
# rules for different file extensions
#---------------------------------------------------------------------------------
ifneq ($(BUILD),$(notdir $(CURDIR)))
#---------------------------------------------------------------------------------
export ARM9ELF := $(CURDIR)/$(TARGET).elf
export DEPSDIR := $(CURDIR)/$(BUILD)
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) soundbank.bin
export AUDIOFILES := $(foreach dir,$(notdir $(wildcard $(MUSIC)/*.*)),$(CURDIR)/$(MUSIC)/$(dir))
#---------------------------------------------------------------------------------
# use CXX for linking C++ projects, CC for standard C
#---------------------------------------------------------------------------------
ifeq ($(strip $(CPPFILES)),)
#---------------------------------------------------------------------------------
export LD := $(CC)
#---------------------------------------------------------------------------------
else
#---------------------------------------------------------------------------------
export LD := $(CXX)
#---------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------
export OFILES := $(addsuffix .o,$(BINFILES)) \
$(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
-I$(CURDIR)/$(BUILD)
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
.PHONY: $(BUILD) clean
#---------------------------------------------------------------------------------
$(BUILD):
@[ -d $@ ] || mkdir -p $@
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
#---------------------------------------------------------------------------------
clean:
@echo clean ...
@rm -fr $(BUILD) *.elf *.nds* *.bin
#---------------------------------------------------------------------------------
else
#---------------------------------------------------------------------------------
# main targets
#---------------------------------------------------------------------------------
$(ARM9ELF) : $(OFILES)
@echo linking $(notdir $@)
@$(LD) $(LDFLAGS) $(OFILES) $(LIBPATHS) $(LIBS) -o $@
#---------------------------------------------------------------------------------
# rule to build soundbank from music files
#---------------------------------------------------------------------------------
soundbank.bin : $(AUDIOFILES)
#---------------------------------------------------------------------------------
@mmutil $^ -d -osoundbank.bin -hsoundbank.h
#---------------------------------------------------------------------------------
# This rule links in binary data with the .bin extension
#---------------------------------------------------------------------------------
%.bin.o : %.bin
#---------------------------------------------------------------------------------
@echo $(notdir $<)
@$(bin2o)
-include $(DEPSDIR)/*.d
#---------------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------------

37
arm9/include/PI9.h Normal file
View File

@ -0,0 +1,37 @@
#ifndef PI9_H
#define PI9_H
#include "math.h"
#include "../../arm7/include/PIC.h"
#define NUMOBJECTS (16)
#define NUMAARS (150)
typedef struct
{
int32 transformationMatrix[9];
vect3D position, size;
int32 mass;
bool used;
u8 id;
}OBB_struct;
typedef struct
{
vect3D position, size;
bool used;
u16 id;
}AAR_struct;
void initPI9(void);
void startPI(void);
void pausePI(void);
void listenPI9(void);
void applyForce(u8 id, vect3D pos, vect3D v);
void createBox(vect3D size, vect3D pos, int32 mass);
void createAAR(vect3D size, vect3D pos, vect3D normal);
void drawOBBs(void);
void drawAARs(void);
#endif

View File

@ -0,0 +1,9 @@
#ifndef __ACOTMENUEX9__
#define __ACOTMENUEX9__
void initACOTMenu(void);
void ACOTMenuFrame(void);
void killACOTMenu(void);
void ACOTMenuVBL(void);
#endif

View File

@ -0,0 +1,6 @@
#ifndef __ACOTMENU9__
#define __ACOTMENU9__
#include "common/general.h"
#endif

136
arm9/include/common/GUI.h Normal file
View File

@ -0,0 +1,136 @@
#ifndef __API9__
#define __API9__
typedef void(*guiDrawFunction)(void* e);
typedef struct
{
s32 x, y;
}coord2Ds;
typedef struct
{
u32 x, y;
}coord2Du;
typedef struct guiEntity_struct
{
u16 id, type;
u8 timep;
u8 times;
u8 timea;
s16 prio;
s16 alpha;
u16 color;
u8 t_timep;
u8 t_times;
u8 t_timea;
void* data;
u8 outline;
s16 t_alpha;
bool halpha;
bool shadow;
bool bastard;
u8 kidToDate;
coord2Ds Size;
coord2Ds Ratio;
coord2Ds a_Size;
coord2Ds o_Size;
coord2Ds b_Size;
coord2Ds t_Size;
GLvector scaleVs;
u16 outline_color;
coord2Ds Position;
coord2Ds a_Position;
coord2Ds o_Position;
coord2Ds t_Position;
guiDrawFunction Draw;
struct guiEntity_struct *father;
struct guiEntity_struct *temp_son;
struct guiEntity_struct *up, *down, *left, *right;
}guiEntity_struct;
typedef void(*guiFunction)(guiEntity_struct* e);
typedef struct
{
mtlImg_struct *background;
}guiWindowData_struct;
typedef struct
{
// mtlImg_struct *background;
char* string;
u16 width;
u16 color;
}guiLabelData_struct;
typedef struct
{
bool over, clicked, colorTakeover;
mtlImg_struct *background;
guiEntity_struct* label;
guiFunction function;
bool clickable, activated;
}guiButtonData_struct;
typedef struct
{
bool over, checked, clickable;
mtlImg_struct *background;
guiEntity_struct* label;
guiFunction function;
}guiCheckBoxData_struct;
typedef struct
{
s16 position, oldpos, size;
guiEntity_struct* label;
bool over, selected;
mtlImg_struct *background;
guiFunction function;
}guiSliderData_struct;
typedef struct guiListElement_struct
{
struct guiListElement_struct *previous, *next;
guiEntity_struct *entity;
}guiListElement_struct;
typedef struct
{
guiListElement_struct *first, *last;
u16 count;
}guiEntityList_struct;
void guiCall(void);
void initGui(void);
void cleanUpGui(void);
void projectGui(void);
void toggleShadow(guiEntity_struct* e);
bool collideGui(guiEntityList_struct *cl, int px, int py);
void updateGui(guiEntityList_struct *cl, touchPosition* tp);
void setAlpha(guiEntity_struct* e, u8 alpha);
void setSize(guiEntity_struct* e, u16 x, u16 y);
void setAlphaSons(guiEntity_struct* f, u8 alpha);
void setPositionX(guiEntity_struct* e, s16 x);
void setPosition(guiEntity_struct* e, s16 x, s16 y);
void fadeSons(guiEntity_struct* f, u8 alpha, u8 time);
void fadeGuiEntity(guiEntity_struct* e, u8 alpha, u8 time);
void computeDirections(guiEntityList_struct *cl, u8 force);
void moveGuiEntity(guiEntity_struct* e, s16 x, s16 y, u8 time);
void resizeGuiEntity(guiEntity_struct* e, u16 x, u16 y, u8 time);
void deleteGuiEntitySons(guiEntityList_struct *cl, guiEntity_struct* father);
void computeGuiDirectionsEntity(guiEntityList_struct *cl, guiEntity_struct *e, u8 force);
void updateLabelText(guiEntity_struct* e, char* text);
void updateButtonText(guiEntity_struct* e, char* text);
void setSizeA(guiEntity_struct* e, u16 x, u16 y);
guiEntity_struct* createLabel(s16 x, s16 y, u16 color, char* text);
guiEntity_struct* createLabelFather(s16 x, s16 y, u16 color, guiEntity_struct* father, char* text, bool halpha);
guiEntity_struct* createCheckBoxFather(s16 x, s16 y, guiFunction function, guiEntity_struct* father, char* text, bool halpha);
guiEntity_struct* createSliderFather(s16 x, s16 y, u8 size, guiFunction function, guiEntity_struct* father, char* text, bool halpha);
guiEntity_struct* createVSliderFather(s16 x, s16 y, u8 size, guiFunction function, guiEntity_struct* father, char* text, bool halpha);
guiEntity_struct* createWindow(s16 x, s16 y, u16 sx, u16 sy, u8 alpha, u16 color, u8 outline, u16 outline_color, char* filename);
guiEntity_struct* createButtonFather(s16 x, s16 y, u16 color, guiFunction function, guiEntity_struct* father, char* text, char* filename, bool halpha);
#endif

View File

@ -0,0 +1,166 @@
/*
* anorms.h - header file
*/
{ NORMAL_PACK(floattov10(-0.525731f), floattov10( 0.000000f), floattov10( 0.850651f )),
NORMAL_PACK(floattov10(-0.442863f), floattov10( 0.238856f), floattov10( 0.864188f )),
NORMAL_PACK(floattov10(-0.295242f), floattov10( 0.000000f), floattov10( 0.955423f )),
NORMAL_PACK(floattov10(-0.309017f), floattov10( 0.500000f), floattov10( 0.809017f )),
NORMAL_PACK(floattov10(-0.162460f), floattov10( 0.262866f), floattov10( 0.951056f )),
NORMAL_PACK(floattov10( 0.000000f), floattov10( 0.000000f), floattov10( 1.000000f )),
NORMAL_PACK(floattov10( 0.000000f), floattov10( 0.850651f), floattov10( 0.525731f )),
NORMAL_PACK(floattov10(-0.147621f), floattov10( 0.716567f), floattov10( 0.681718f )),
NORMAL_PACK(floattov10( 0.147621f), floattov10( 0.716567f), floattov10( 0.681718f )),
NORMAL_PACK(floattov10( 0.000000f), floattov10( 0.525731f), floattov10( 0.850651f )),
NORMAL_PACK(floattov10( 0.309017f), floattov10( 0.500000f), floattov10( 0.809017f )),
NORMAL_PACK(floattov10( 0.525731f), floattov10( 0.000000f), floattov10( 0.850651f )),
NORMAL_PACK(floattov10( 0.295242f), floattov10( 0.000000f), floattov10( 0.955423f )),
NORMAL_PACK(floattov10( 0.442863f), floattov10( 0.238856f), floattov10( 0.864188f )),
NORMAL_PACK(floattov10( 0.162460f), floattov10( 0.262866f), floattov10( 0.951056f )),
NORMAL_PACK(floattov10(-0.681718f), floattov10( 0.147621f), floattov10( 0.716567f )),
NORMAL_PACK(floattov10(-0.809017f), floattov10( 0.309017f), floattov10( 0.500000f )),
NORMAL_PACK(floattov10(-0.587785f), floattov10( 0.425325f), floattov10( 0.688191f )),
NORMAL_PACK(floattov10(-0.850651f), floattov10( 0.525731f), floattov10( 0.000000f )),
NORMAL_PACK(floattov10(-0.864188f), floattov10( 0.442863f), floattov10( 0.238856f )),
NORMAL_PACK(floattov10(-0.716567f), floattov10( 0.681718f), floattov10( 0.147621f )),
NORMAL_PACK(floattov10(-0.688191f), floattov10( 0.587785f), floattov10( 0.425325f )),
NORMAL_PACK(floattov10(-0.500000f), floattov10( 0.809017f), floattov10( 0.309017f )),
NORMAL_PACK(floattov10(-0.238856f), floattov10( 0.864188f), floattov10( 0.442863f )),
NORMAL_PACK(floattov10(-0.425325f), floattov10( 0.688191f), floattov10( 0.587785f )),
NORMAL_PACK(floattov10(-0.716567f), floattov10( 0.681718f), floattov10(-0.147621f )),
NORMAL_PACK(floattov10(-0.500000f), floattov10( 0.809017f), floattov10(-0.309017f )),
NORMAL_PACK(floattov10(-0.525731f), floattov10( 0.850651f), floattov10( 0.000000f )),
NORMAL_PACK(floattov10( 0.000000f), floattov10( 0.850651f), floattov10(-0.525731f )),
NORMAL_PACK(floattov10(-0.238856f), floattov10( 0.864188f), floattov10(-0.442863f )),
NORMAL_PACK(floattov10( 0.000000f), floattov10( 0.955423f), floattov10(-0.295242f )),
NORMAL_PACK(floattov10(-0.262866f), floattov10( 0.951056f), floattov10(-0.162460f )),
NORMAL_PACK(floattov10( 0.000000f), floattov10( 1.000000f), floattov10( 0.000000f )),
NORMAL_PACK(floattov10( 0.000000f), floattov10( 0.955423f), floattov10( 0.295242f )),
NORMAL_PACK(floattov10(-0.262866f), floattov10( 0.951056f), floattov10( 0.162460f )),
NORMAL_PACK(floattov10( 0.238856f), floattov10( 0.864188f), floattov10( 0.442863f )),
NORMAL_PACK(floattov10( 0.262866f), floattov10( 0.951056f), floattov10( 0.162460f )),
NORMAL_PACK(floattov10( 0.500000f), floattov10( 0.809017f), floattov10( 0.309017f )),
NORMAL_PACK(floattov10( 0.238856f), floattov10( 0.864188f), floattov10(-0.442863f )),
NORMAL_PACK(floattov10( 0.262866f), floattov10( 0.951056f), floattov10(-0.162460f )),
NORMAL_PACK(floattov10( 0.500000f), floattov10( 0.809017f), floattov10(-0.309017f )),
NORMAL_PACK(floattov10( 0.850651f), floattov10( 0.525731f), floattov10( 0.000000f )),
NORMAL_PACK(floattov10( 0.716567f), floattov10( 0.681718f), floattov10( 0.147621f )),
NORMAL_PACK(floattov10( 0.716567f), floattov10( 0.681718f), floattov10(-0.147621f )),
NORMAL_PACK(floattov10( 0.525731f), floattov10( 0.850651f), floattov10( 0.000000f )),
NORMAL_PACK(floattov10( 0.425325f), floattov10( 0.688191f), floattov10( 0.587785f )),
NORMAL_PACK(floattov10( 0.864188f), floattov10( 0.442863f), floattov10( 0.238856f )),
NORMAL_PACK(floattov10( 0.688191f), floattov10( 0.587785f), floattov10( 0.425325f )),
NORMAL_PACK(floattov10( 0.809017f), floattov10( 0.309017f), floattov10( 0.500000f )),
NORMAL_PACK(floattov10( 0.681718f), floattov10( 0.147621f), floattov10( 0.716567f )),
NORMAL_PACK(floattov10( 0.587785f), floattov10( 0.425325f), floattov10( 0.688191f )),
NORMAL_PACK(floattov10( 0.955423f), floattov10( 0.295242f), floattov10( 0.000000f )),
NORMAL_PACK(floattov10( 1.000000f), floattov10( 0.000000f), floattov10( 0.000000f )),
NORMAL_PACK(floattov10( 0.951056f), floattov10( 0.162460f), floattov10( 0.262866f )),
NORMAL_PACK(floattov10( 0.850651f), floattov10(-0.525731f), floattov10( 0.000000f )),
NORMAL_PACK(floattov10( 0.955423f), floattov10(-0.295242f), floattov10( 0.000000f )),
NORMAL_PACK(floattov10( 0.864188f), floattov10(-0.442863f), floattov10( 0.238856f )),
NORMAL_PACK(floattov10( 0.951056f), floattov10(-0.162460f), floattov10( 0.262866f )),
NORMAL_PACK(floattov10( 0.809017f), floattov10(-0.309017f), floattov10( 0.500000f )),
NORMAL_PACK(floattov10( 0.681718f), floattov10(-0.147621f), floattov10( 0.716567f )),
NORMAL_PACK(floattov10( 0.850651f), floattov10( 0.000000f), floattov10( 0.525731f )),
NORMAL_PACK(floattov10( 0.864188f), floattov10( 0.442863f), floattov10(-0.238856f )),
NORMAL_PACK(floattov10( 0.809017f), floattov10( 0.309017f), floattov10(-0.500000f )),
NORMAL_PACK(floattov10( 0.951056f), floattov10( 0.162460f), floattov10(-0.262866f )),
NORMAL_PACK(floattov10( 0.525731f), floattov10( 0.000000f), floattov10(-0.850651f )),
NORMAL_PACK(floattov10( 0.681718f), floattov10( 0.147621f), floattov10(-0.716567f )),
NORMAL_PACK(floattov10( 0.681718f), floattov10(-0.147621f), floattov10(-0.716567f )),
NORMAL_PACK(floattov10( 0.850651f), floattov10( 0.000000f), floattov10(-0.525731f )),
NORMAL_PACK(floattov10( 0.809017f), floattov10(-0.309017f), floattov10(-0.500000f )),
NORMAL_PACK(floattov10( 0.864188f), floattov10(-0.442863f), floattov10(-0.238856f )),
NORMAL_PACK(floattov10( 0.951056f), floattov10(-0.162460f), floattov10(-0.262866f )),
NORMAL_PACK(floattov10( 0.147621f), floattov10( 0.716567f), floattov10(-0.681718f )),
NORMAL_PACK(floattov10( 0.309017f), floattov10( 0.500000f), floattov10(-0.809017f )),
NORMAL_PACK(floattov10( 0.425325f), floattov10( 0.688191f), floattov10(-0.587785f )),
NORMAL_PACK(floattov10( 0.442863f), floattov10( 0.238856f), floattov10(-0.864188f )),
NORMAL_PACK(floattov10( 0.587785f), floattov10( 0.425325f), floattov10(-0.688191f )),
NORMAL_PACK(floattov10( 0.688191f), floattov10( 0.587785f), floattov10(-0.425325f )),
NORMAL_PACK(floattov10(-0.147621f), floattov10( 0.716567f), floattov10(-0.681718f )),
NORMAL_PACK(floattov10(-0.309017f), floattov10( 0.500000f), floattov10(-0.809017f )),
NORMAL_PACK(floattov10( 0.000000f), floattov10( 0.525731f), floattov10(-0.850651f )),
NORMAL_PACK(floattov10(-0.525731f), floattov10( 0.000000f), floattov10(-0.850651f )),
NORMAL_PACK(floattov10(-0.442863f), floattov10( 0.238856f), floattov10(-0.864188f )),
NORMAL_PACK(floattov10(-0.295242f), floattov10( 0.000000f), floattov10(-0.955423f )),
NORMAL_PACK(floattov10(-0.162460f), floattov10( 0.262866f), floattov10(-0.951056f )),
NORMAL_PACK(floattov10( 0.000000f), floattov10( 0.000000f), floattov10(-1.000000f )),
NORMAL_PACK(floattov10( 0.295242f), floattov10( 0.000000f), floattov10(-0.955423f )),
NORMAL_PACK(floattov10( 0.162460f), floattov10( 0.262866f), floattov10(-0.951056f )),
NORMAL_PACK(floattov10(-0.442863f), floattov10(-0.238856f), floattov10(-0.864188f )),
NORMAL_PACK(floattov10(-0.309017f), floattov10(-0.500000f), floattov10(-0.809017f )),
NORMAL_PACK(floattov10(-0.162460f), floattov10(-0.262866f), floattov10(-0.951056f )),
NORMAL_PACK(floattov10( 0.000000f), floattov10(-0.850651f), floattov10(-0.525731f )),
NORMAL_PACK(floattov10(-0.147621f), floattov10(-0.716567f), floattov10(-0.681718f )),
NORMAL_PACK(floattov10( 0.147621f), floattov10(-0.716567f), floattov10(-0.681718f )),
NORMAL_PACK(floattov10( 0.000000f), floattov10(-0.525731f), floattov10(-0.850651f )),
NORMAL_PACK(floattov10( 0.309017f), floattov10(-0.500000f), floattov10(-0.809017f )),
NORMAL_PACK(floattov10( 0.442863f), floattov10(-0.238856f), floattov10(-0.864188f )),
NORMAL_PACK(floattov10( 0.162460f), floattov10(-0.262866f), floattov10(-0.951056f )),
NORMAL_PACK(floattov10( 0.238856f), floattov10(-0.864188f), floattov10(-0.442863f )),
NORMAL_PACK(floattov10( 0.500000f), floattov10(-0.809017f), floattov10(-0.309017f )),
NORMAL_PACK(floattov10( 0.425325f), floattov10(-0.688191f), floattov10(-0.587785f )),
NORMAL_PACK(floattov10( 0.716567f), floattov10(-0.681718f), floattov10(-0.147621f )),
NORMAL_PACK(floattov10( 0.688191f), floattov10(-0.587785f), floattov10(-0.425325f )),
NORMAL_PACK(floattov10( 0.587785f), floattov10(-0.425325f), floattov10(-0.688191f )),
NORMAL_PACK(floattov10( 0.000000f), floattov10(-0.955423f), floattov10(-0.295242f )),
NORMAL_PACK(floattov10( 0.000000f), floattov10(-1.000000f), floattov10( 0.000000f )),
NORMAL_PACK(floattov10( 0.262866f), floattov10(-0.951056f), floattov10(-0.162460f )),
NORMAL_PACK(floattov10( 0.000000f), floattov10(-0.850651f), floattov10( 0.525731f )),
NORMAL_PACK(floattov10( 0.000000f), floattov10(-0.955423f), floattov10( 0.295242f )),
NORMAL_PACK(floattov10( 0.238856f), floattov10(-0.864188f), floattov10( 0.442863f )),
NORMAL_PACK(floattov10( 0.262866f), floattov10(-0.951056f), floattov10( 0.162460f )),
NORMAL_PACK(floattov10( 0.500000f), floattov10(-0.809017f), floattov10( 0.309017f )),
NORMAL_PACK(floattov10( 0.716567f), floattov10(-0.681718f), floattov10( 0.147621f )),
NORMAL_PACK(floattov10( 0.525731f), floattov10(-0.850651f), floattov10( 0.000000f )),
NORMAL_PACK(floattov10(-0.238856f), floattov10(-0.864188f), floattov10(-0.442863f )),
NORMAL_PACK(floattov10(-0.500000f), floattov10(-0.809017f), floattov10(-0.309017f )),
NORMAL_PACK(floattov10(-0.262866f), floattov10(-0.951056f), floattov10(-0.162460f )),
NORMAL_PACK(floattov10(-0.850651f), floattov10(-0.525731f), floattov10( 0.000000f )),
NORMAL_PACK(floattov10(-0.716567f), floattov10(-0.681718f), floattov10(-0.147621f )),
NORMAL_PACK(floattov10(-0.716567f), floattov10(-0.681718f), floattov10( 0.147621f )),
NORMAL_PACK(floattov10(-0.525731f), floattov10(-0.850651f), floattov10( 0.000000f )),
NORMAL_PACK(floattov10(-0.500000f), floattov10(-0.809017f), floattov10( 0.309017f )),
NORMAL_PACK(floattov10(-0.238856f), floattov10(-0.864188f), floattov10( 0.442863f )),
NORMAL_PACK(floattov10(-0.262866f), floattov10(-0.951056f), floattov10( 0.162460f )),
NORMAL_PACK(floattov10(-0.864188f), floattov10(-0.442863f), floattov10( 0.238856f )),
NORMAL_PACK(floattov10(-0.809017f), floattov10(-0.309017f), floattov10( 0.500000f )),
NORMAL_PACK(floattov10(-0.688191f), floattov10(-0.587785f), floattov10( 0.425325f )),
NORMAL_PACK(floattov10(-0.681718f), floattov10(-0.147621f), floattov10( 0.716567f )),
NORMAL_PACK(floattov10(-0.442863f), floattov10(-0.238856f), floattov10( 0.864188f )),
NORMAL_PACK(floattov10(-0.587785f), floattov10(-0.425325f), floattov10( 0.688191f )),
NORMAL_PACK(floattov10(-0.309017f), floattov10(-0.500000f), floattov10( 0.809017f )),
NORMAL_PACK(floattov10(-0.147621f), floattov10(-0.716567f), floattov10( 0.681718f )),
NORMAL_PACK(floattov10(-0.425325f), floattov10(-0.688191f), floattov10( 0.587785f )),
NORMAL_PACK(floattov10(-0.162460f), floattov10(-0.262866f), floattov10( 0.951056f )),
NORMAL_PACK(floattov10( 0.442863f), floattov10(-0.238856f), floattov10( 0.864188f )),
NORMAL_PACK(floattov10( 0.162460f), floattov10(-0.262866f), floattov10( 0.951056f )),
NORMAL_PACK(floattov10( 0.309017f), floattov10(-0.500000f), floattov10( 0.809017f )),
NORMAL_PACK(floattov10( 0.147621f), floattov10(-0.716567f), floattov10( 0.681718f )),
NORMAL_PACK(floattov10( 0.000000f), floattov10(-0.525731f), floattov10( 0.850651f )),
NORMAL_PACK(floattov10( 0.425325f), floattov10(-0.688191f), floattov10( 0.587785f )),
NORMAL_PACK(floattov10( 0.587785f), floattov10(-0.425325f), floattov10( 0.688191f )),
NORMAL_PACK(floattov10( 0.688191f), floattov10(-0.587785f), floattov10( 0.425325f )),
NORMAL_PACK(floattov10(-0.955423f), floattov10( 0.295242f), floattov10( 0.000000f )),
NORMAL_PACK(floattov10(-0.951056f), floattov10( 0.162460f), floattov10( 0.262866f )),
NORMAL_PACK(floattov10(-1.000000f), floattov10( 0.000000f), floattov10( 0.000000f )),
NORMAL_PACK(floattov10(-0.850651f), floattov10( 0.000000f), floattov10( 0.525731f )),
NORMAL_PACK(floattov10(-0.955423f), floattov10(-0.295242f), floattov10( 0.000000f )),
NORMAL_PACK(floattov10(-0.951056f), floattov10(-0.162460f), floattov10( 0.262866f )),
NORMAL_PACK(floattov10(-0.864188f), floattov10( 0.442863f), floattov10(-0.238856f )),
NORMAL_PACK(floattov10(-0.951056f), floattov10( 0.162460f), floattov10(-0.262866f )),
NORMAL_PACK(floattov10(-0.809017f), floattov10( 0.309017f), floattov10(-0.500000f )),
NORMAL_PACK(floattov10(-0.864188f), floattov10(-0.442863f), floattov10(-0.238856f )),
NORMAL_PACK(floattov10(-0.951056f), floattov10(-0.162460f), floattov10(-0.262866f )),
NORMAL_PACK(floattov10(-0.809017f), floattov10(-0.309017f), floattov10(-0.500000f )),
NORMAL_PACK(floattov10(-0.681718f), floattov10( 0.147621f), floattov10(-0.716567f )),
NORMAL_PACK(floattov10(-0.681718f), floattov10(-0.147621f), floattov10(-0.716567f )),
NORMAL_PACK(floattov10(-0.850651f), floattov10( 0.000000f), floattov10(-0.525731f )),
NORMAL_PACK(floattov10(-0.688191f), floattov10( 0.587785f), floattov10(-0.425325f )),
NORMAL_PACK(floattov10(-0.587785f), floattov10( 0.425325f), floattov10(-0.688191f )),
NORMAL_PACK(floattov10(-0.425325f), floattov10( 0.688191f), floattov10(-0.587785f )),
NORMAL_PACK(floattov10(-0.425325f), floattov10(-0.688191f), floattov10(-0.587785f )),
NORMAL_PACK(floattov10(-0.587785f), floattov10(-0.425325f), floattov10(-0.688191f )),
NORMAL_PACK(floattov10(-0.688191f), floattov10(-0.587785f), floattov10(-0.425325f))}

View File

@ -0,0 +1,166 @@
/*
* anorms.h - header file
*/
{ vect(floattof32(-0.525731f), floattof32( 0.000000f), floattof32( 0.850651f )),
vect(floattof32(-0.442863f), floattof32( 0.238856f), floattof32( 0.864188f )),
vect(floattof32(-0.295242f), floattof32( 0.000000f), floattof32( 0.955423f )),
vect(floattof32(-0.309017f), floattof32( 0.500000f), floattof32( 0.809017f )),
vect(floattof32(-0.162460f), floattof32( 0.262866f), floattof32( 0.951056f )),
vect(floattof32( 0.000000f), floattof32( 0.000000f), floattof32( 1.000000f )),
vect(floattof32( 0.000000f), floattof32( 0.850651f), floattof32( 0.525731f )),
vect(floattof32(-0.147621f), floattof32( 0.716567f), floattof32( 0.681718f )),
vect(floattof32( 0.147621f), floattof32( 0.716567f), floattof32( 0.681718f )),
vect(floattof32( 0.000000f), floattof32( 0.525731f), floattof32( 0.850651f )),
vect(floattof32( 0.309017f), floattof32( 0.500000f), floattof32( 0.809017f )),
vect(floattof32( 0.525731f), floattof32( 0.000000f), floattof32( 0.850651f )),
vect(floattof32( 0.295242f), floattof32( 0.000000f), floattof32( 0.955423f )),
vect(floattof32( 0.442863f), floattof32( 0.238856f), floattof32( 0.864188f )),
vect(floattof32( 0.162460f), floattof32( 0.262866f), floattof32( 0.951056f )),
vect(floattof32(-0.681718f), floattof32( 0.147621f), floattof32( 0.716567f )),
vect(floattof32(-0.809017f), floattof32( 0.309017f), floattof32( 0.500000f )),
vect(floattof32(-0.587785f), floattof32( 0.425325f), floattof32( 0.688191f )),
vect(floattof32(-0.850651f), floattof32( 0.525731f), floattof32( 0.000000f )),
vect(floattof32(-0.864188f), floattof32( 0.442863f), floattof32( 0.238856f )),
vect(floattof32(-0.716567f), floattof32( 0.681718f), floattof32( 0.147621f )),
vect(floattof32(-0.688191f), floattof32( 0.587785f), floattof32( 0.425325f )),
vect(floattof32(-0.500000f), floattof32( 0.809017f), floattof32( 0.309017f )),
vect(floattof32(-0.238856f), floattof32( 0.864188f), floattof32( 0.442863f )),
vect(floattof32(-0.425325f), floattof32( 0.688191f), floattof32( 0.587785f )),
vect(floattof32(-0.716567f), floattof32( 0.681718f), floattof32(-0.147621f )),
vect(floattof32(-0.500000f), floattof32( 0.809017f), floattof32(-0.309017f )),
vect(floattof32(-0.525731f), floattof32( 0.850651f), floattof32( 0.000000f )),
vect(floattof32( 0.000000f), floattof32( 0.850651f), floattof32(-0.525731f )),
vect(floattof32(-0.238856f), floattof32( 0.864188f), floattof32(-0.442863f )),
vect(floattof32( 0.000000f), floattof32( 0.955423f), floattof32(-0.295242f )),
vect(floattof32(-0.262866f), floattof32( 0.951056f), floattof32(-0.162460f )),
vect(floattof32( 0.000000f), floattof32( 1.000000f), floattof32( 0.000000f )),
vect(floattof32( 0.000000f), floattof32( 0.955423f), floattof32( 0.295242f )),
vect(floattof32(-0.262866f), floattof32( 0.951056f), floattof32( 0.162460f )),
vect(floattof32( 0.238856f), floattof32( 0.864188f), floattof32( 0.442863f )),
vect(floattof32( 0.262866f), floattof32( 0.951056f), floattof32( 0.162460f )),
vect(floattof32( 0.500000f), floattof32( 0.809017f), floattof32( 0.309017f )),
vect(floattof32( 0.238856f), floattof32( 0.864188f), floattof32(-0.442863f )),
vect(floattof32( 0.262866f), floattof32( 0.951056f), floattof32(-0.162460f )),
vect(floattof32( 0.500000f), floattof32( 0.809017f), floattof32(-0.309017f )),
vect(floattof32( 0.850651f), floattof32( 0.525731f), floattof32( 0.000000f )),
vect(floattof32( 0.716567f), floattof32( 0.681718f), floattof32( 0.147621f )),
vect(floattof32( 0.716567f), floattof32( 0.681718f), floattof32(-0.147621f )),
vect(floattof32( 0.525731f), floattof32( 0.850651f), floattof32( 0.000000f )),
vect(floattof32( 0.425325f), floattof32( 0.688191f), floattof32( 0.587785f )),
vect(floattof32( 0.864188f), floattof32( 0.442863f), floattof32( 0.238856f )),
vect(floattof32( 0.688191f), floattof32( 0.587785f), floattof32( 0.425325f )),
vect(floattof32( 0.809017f), floattof32( 0.309017f), floattof32( 0.500000f )),
vect(floattof32( 0.681718f), floattof32( 0.147621f), floattof32( 0.716567f )),
vect(floattof32( 0.587785f), floattof32( 0.425325f), floattof32( 0.688191f )),
vect(floattof32( 0.955423f), floattof32( 0.295242f), floattof32( 0.000000f )),
vect(floattof32( 1.000000f), floattof32( 0.000000f), floattof32( 0.000000f )),
vect(floattof32( 0.951056f), floattof32( 0.162460f), floattof32( 0.262866f )),
vect(floattof32( 0.850651f), floattof32(-0.525731f), floattof32( 0.000000f )),
vect(floattof32( 0.955423f), floattof32(-0.295242f), floattof32( 0.000000f )),
vect(floattof32( 0.864188f), floattof32(-0.442863f), floattof32( 0.238856f )),
vect(floattof32( 0.951056f), floattof32(-0.162460f), floattof32( 0.262866f )),
vect(floattof32( 0.809017f), floattof32(-0.309017f), floattof32( 0.500000f )),
vect(floattof32( 0.681718f), floattof32(-0.147621f), floattof32( 0.716567f )),
vect(floattof32( 0.850651f), floattof32( 0.000000f), floattof32( 0.525731f )),
vect(floattof32( 0.864188f), floattof32( 0.442863f), floattof32(-0.238856f )),
vect(floattof32( 0.809017f), floattof32( 0.309017f), floattof32(-0.500000f )),
vect(floattof32( 0.951056f), floattof32( 0.162460f), floattof32(-0.262866f )),
vect(floattof32( 0.525731f), floattof32( 0.000000f), floattof32(-0.850651f )),
vect(floattof32( 0.681718f), floattof32( 0.147621f), floattof32(-0.716567f )),
vect(floattof32( 0.681718f), floattof32(-0.147621f), floattof32(-0.716567f )),
vect(floattof32( 0.850651f), floattof32( 0.000000f), floattof32(-0.525731f )),
vect(floattof32( 0.809017f), floattof32(-0.309017f), floattof32(-0.500000f )),
vect(floattof32( 0.864188f), floattof32(-0.442863f), floattof32(-0.238856f )),
vect(floattof32( 0.951056f), floattof32(-0.162460f), floattof32(-0.262866f )),
vect(floattof32( 0.147621f), floattof32( 0.716567f), floattof32(-0.681718f )),
vect(floattof32( 0.309017f), floattof32( 0.500000f), floattof32(-0.809017f )),
vect(floattof32( 0.425325f), floattof32( 0.688191f), floattof32(-0.587785f )),
vect(floattof32( 0.442863f), floattof32( 0.238856f), floattof32(-0.864188f )),
vect(floattof32( 0.587785f), floattof32( 0.425325f), floattof32(-0.688191f )),
vect(floattof32( 0.688191f), floattof32( 0.587785f), floattof32(-0.425325f )),
vect(floattof32(-0.147621f), floattof32( 0.716567f), floattof32(-0.681718f )),
vect(floattof32(-0.309017f), floattof32( 0.500000f), floattof32(-0.809017f )),
vect(floattof32( 0.000000f), floattof32( 0.525731f), floattof32(-0.850651f )),
vect(floattof32(-0.525731f), floattof32( 0.000000f), floattof32(-0.850651f )),
vect(floattof32(-0.442863f), floattof32( 0.238856f), floattof32(-0.864188f )),
vect(floattof32(-0.295242f), floattof32( 0.000000f), floattof32(-0.955423f )),
vect(floattof32(-0.162460f), floattof32( 0.262866f), floattof32(-0.951056f )),
vect(floattof32( 0.000000f), floattof32( 0.000000f), floattof32(-1.000000f )),
vect(floattof32( 0.295242f), floattof32( 0.000000f), floattof32(-0.955423f )),
vect(floattof32( 0.162460f), floattof32( 0.262866f), floattof32(-0.951056f )),
vect(floattof32(-0.442863f), floattof32(-0.238856f), floattof32(-0.864188f )),
vect(floattof32(-0.309017f), floattof32(-0.500000f), floattof32(-0.809017f )),
vect(floattof32(-0.162460f), floattof32(-0.262866f), floattof32(-0.951056f )),
vect(floattof32( 0.000000f), floattof32(-0.850651f), floattof32(-0.525731f )),
vect(floattof32(-0.147621f), floattof32(-0.716567f), floattof32(-0.681718f )),
vect(floattof32( 0.147621f), floattof32(-0.716567f), floattof32(-0.681718f )),
vect(floattof32( 0.000000f), floattof32(-0.525731f), floattof32(-0.850651f )),
vect(floattof32( 0.309017f), floattof32(-0.500000f), floattof32(-0.809017f )),
vect(floattof32( 0.442863f), floattof32(-0.238856f), floattof32(-0.864188f )),
vect(floattof32( 0.162460f), floattof32(-0.262866f), floattof32(-0.951056f )),
vect(floattof32( 0.238856f), floattof32(-0.864188f), floattof32(-0.442863f )),
vect(floattof32( 0.500000f), floattof32(-0.809017f), floattof32(-0.309017f )),
vect(floattof32( 0.425325f), floattof32(-0.688191f), floattof32(-0.587785f )),
vect(floattof32( 0.716567f), floattof32(-0.681718f), floattof32(-0.147621f )),
vect(floattof32( 0.688191f), floattof32(-0.587785f), floattof32(-0.425325f )),
vect(floattof32( 0.587785f), floattof32(-0.425325f), floattof32(-0.688191f )),
vect(floattof32( 0.000000f), floattof32(-0.955423f), floattof32(-0.295242f )),
vect(floattof32( 0.000000f), floattof32(-1.000000f), floattof32( 0.000000f )),
vect(floattof32( 0.262866f), floattof32(-0.951056f), floattof32(-0.162460f )),
vect(floattof32( 0.000000f), floattof32(-0.850651f), floattof32( 0.525731f )),
vect(floattof32( 0.000000f), floattof32(-0.955423f), floattof32( 0.295242f )),
vect(floattof32( 0.238856f), floattof32(-0.864188f), floattof32( 0.442863f )),
vect(floattof32( 0.262866f), floattof32(-0.951056f), floattof32( 0.162460f )),
vect(floattof32( 0.500000f), floattof32(-0.809017f), floattof32( 0.309017f )),
vect(floattof32( 0.716567f), floattof32(-0.681718f), floattof32( 0.147621f )),
vect(floattof32( 0.525731f), floattof32(-0.850651f), floattof32( 0.000000f )),
vect(floattof32(-0.238856f), floattof32(-0.864188f), floattof32(-0.442863f )),
vect(floattof32(-0.500000f), floattof32(-0.809017f), floattof32(-0.309017f )),
vect(floattof32(-0.262866f), floattof32(-0.951056f), floattof32(-0.162460f )),
vect(floattof32(-0.850651f), floattof32(-0.525731f), floattof32( 0.000000f )),
vect(floattof32(-0.716567f), floattof32(-0.681718f), floattof32(-0.147621f )),
vect(floattof32(-0.716567f), floattof32(-0.681718f), floattof32( 0.147621f )),
vect(floattof32(-0.525731f), floattof32(-0.850651f), floattof32( 0.000000f )),
vect(floattof32(-0.500000f), floattof32(-0.809017f), floattof32( 0.309017f )),
vect(floattof32(-0.238856f), floattof32(-0.864188f), floattof32( 0.442863f )),
vect(floattof32(-0.262866f), floattof32(-0.951056f), floattof32( 0.162460f )),
vect(floattof32(-0.864188f), floattof32(-0.442863f), floattof32( 0.238856f )),
vect(floattof32(-0.809017f), floattof32(-0.309017f), floattof32( 0.500000f )),
vect(floattof32(-0.688191f), floattof32(-0.587785f), floattof32( 0.425325f )),
vect(floattof32(-0.681718f), floattof32(-0.147621f), floattof32( 0.716567f )),
vect(floattof32(-0.442863f), floattof32(-0.238856f), floattof32( 0.864188f )),
vect(floattof32(-0.587785f), floattof32(-0.425325f), floattof32( 0.688191f )),
vect(floattof32(-0.309017f), floattof32(-0.500000f), floattof32( 0.809017f )),
vect(floattof32(-0.147621f), floattof32(-0.716567f), floattof32( 0.681718f )),
vect(floattof32(-0.425325f), floattof32(-0.688191f), floattof32( 0.587785f )),
vect(floattof32(-0.162460f), floattof32(-0.262866f), floattof32( 0.951056f )),
vect(floattof32( 0.442863f), floattof32(-0.238856f), floattof32( 0.864188f )),
vect(floattof32( 0.162460f), floattof32(-0.262866f), floattof32( 0.951056f )),
vect(floattof32( 0.309017f), floattof32(-0.500000f), floattof32( 0.809017f )),
vect(floattof32( 0.147621f), floattof32(-0.716567f), floattof32( 0.681718f )),
vect(floattof32( 0.000000f), floattof32(-0.525731f), floattof32( 0.850651f )),
vect(floattof32( 0.425325f), floattof32(-0.688191f), floattof32( 0.587785f )),
vect(floattof32( 0.587785f), floattof32(-0.425325f), floattof32( 0.688191f )),
vect(floattof32( 0.688191f), floattof32(-0.587785f), floattof32( 0.425325f )),
vect(floattof32(-0.955423f), floattof32( 0.295242f), floattof32( 0.000000f )),
vect(floattof32(-0.951056f), floattof32( 0.162460f), floattof32( 0.262866f )),
vect(floattof32(-1.000000f), floattof32( 0.000000f), floattof32( 0.000000f )),
vect(floattof32(-0.850651f), floattof32( 0.000000f), floattof32( 0.525731f )),
vect(floattof32(-0.955423f), floattof32(-0.295242f), floattof32( 0.000000f )),
vect(floattof32(-0.951056f), floattof32(-0.162460f), floattof32( 0.262866f )),
vect(floattof32(-0.864188f), floattof32( 0.442863f), floattof32(-0.238856f )),
vect(floattof32(-0.951056f), floattof32( 0.162460f), floattof32(-0.262866f )),
vect(floattof32(-0.809017f), floattof32( 0.309017f), floattof32(-0.500000f )),
vect(floattof32(-0.864188f), floattof32(-0.442863f), floattof32(-0.238856f )),
vect(floattof32(-0.951056f), floattof32(-0.162460f), floattof32(-0.262866f )),
vect(floattof32(-0.809017f), floattof32(-0.309017f), floattof32(-0.500000f )),
vect(floattof32(-0.681718f), floattof32( 0.147621f), floattof32(-0.716567f )),
vect(floattof32(-0.681718f), floattof32(-0.147621f), floattof32(-0.716567f )),
vect(floattof32(-0.850651f), floattof32( 0.000000f), floattof32(-0.525731f )),
vect(floattof32(-0.688191f), floattof32( 0.587785f), floattof32(-0.425325f )),
vect(floattof32(-0.587785f), floattof32( 0.425325f), floattof32(-0.688191f )),
vect(floattof32(-0.425325f), floattof32( 0.688191f), floattof32(-0.587785f )),
vect(floattof32(-0.425325f), floattof32(-0.688191f), floattof32(-0.587785f )),
vect(floattof32(-0.587785f), floattof32(-0.425325f), floattof32(-0.688191f )),
vect(floattof32(-0.688191f), floattof32(-0.587785f), floattof32(-0.425325f))}

View File

@ -0,0 +1,10 @@
#ifndef __AUDIO9_H__
#define __AUDIO9_H__
// extern mm_sound_effect bossdies,clickbttn,enemyDead,enemyScream,gunShot,playerHit,scream;
void initAudio(void);
void loadSoundEffects(void);
#endif

View File

@ -0,0 +1,174 @@
/*-------------------------------------------------------------------------*/
/**
@file dictionary.h
@author N. Devillard
@date Sep 2007
@version $Revision: 1.12 $
@brief Implements a dictionary for string variables.
This module implements a simple dictionary object, i.e. a list
of string/string associations. This object is useful to store e.g.
informations retrieved from a configuration file (ini files).
*/
/*--------------------------------------------------------------------------*/
/*
$Id: dictionary.h,v 1.12 2007-11-23 21:37:00 ndevilla Exp $
$Author: ndevilla $
$Date: 2007-11-23 21:37:00 $
$Revision: 1.12 $
*/
#ifndef _DICTIONARY_H_
#define _DICTIONARY_H_
/*---------------------------------------------------------------------------
Includes
---------------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
/*---------------------------------------------------------------------------
New types
---------------------------------------------------------------------------*/
/*-------------------------------------------------------------------------*/
/**
@brief Dictionary object
This object contains a list of string/string associations. Each
association is identified by a unique string key. Looking up values
in the dictionary is speeded up by the use of a (hopefully collision-free)
hash function.
*/
/*-------------------------------------------------------------------------*/
typedef struct _dictionary_ {
int n ; /** Number of entries in dictionary */
int size ; /** Storage size */
char ** val ; /** List of string values */
char ** key ; /** List of string keys */
unsigned * hash ; /** List of hash values for keys */
} dictionary ;
/*---------------------------------------------------------------------------
Function prototypes
---------------------------------------------------------------------------*/
/*-------------------------------------------------------------------------*/
/**
@brief Compute the hash key for a string.
@param key Character string to use for key.
@return 1 unsigned int on at least 32 bits.
This hash function has been taken from an Article in Dr Dobbs Journal.
This is normally a collision-free function, distributing keys evenly.
The key is stored anyway in the struct so that collision can be avoided
by comparing the key itself in last resort.
*/
/*--------------------------------------------------------------------------*/
unsigned dictionary_hash(char * key);
/*-------------------------------------------------------------------------*/
/**
@brief Create a new dictionary object.
@param size Optional initial size of the dictionary.
@return 1 newly allocated dictionary objet.
This function allocates a new dictionary object of given size and returns
it. If you do not know in advance (roughly) the number of entries in the
dictionary, give size=0.
*/
/*--------------------------------------------------------------------------*/
dictionary * dictionary_new(int size);
/*-------------------------------------------------------------------------*/
/**
@brief Delete a dictionary object
@param d dictionary object to deallocate.
@return void
Deallocate a dictionary object and all memory associated to it.
*/
/*--------------------------------------------------------------------------*/
void dictionary_del(dictionary * vd);
/*-------------------------------------------------------------------------*/
/**
@brief Get a value from a dictionary.
@param d dictionary object to search.
@param key Key to look for in the dictionary.
@param def Default value to return if key not found.
@return 1 pointer to internally allocated character string.
This function locates a key in a dictionary and returns a pointer to its
value, or the passed 'def' pointer if no such key can be found in
dictionary. The returned character pointer points to data internal to the
dictionary object, you should not try to free it or modify it.
*/
/*--------------------------------------------------------------------------*/
char * dictionary_get(dictionary * d, char * key, char * def);
/*-------------------------------------------------------------------------*/
/**
@brief Set a value in a dictionary.
@param d dictionary object to modify.
@param key Key to modify or add.
@param val Value to add.
@return int 0 if Ok, anything else otherwise
If the given key is found in the dictionary, the associated value is
replaced by the provided one. If the key cannot be found in the
dictionary, it is added to it.
It is Ok to provide a NULL value for val, but NULL values for the dictionary
or the key are considered as errors: the function will return immediately
in such a case.
Notice that if you dictionary_set a variable to NULL, a call to
dictionary_get will return a NULL value: the variable will be found, and
its value (NULL) is returned. In other words, setting the variable
content to NULL is equivalent to deleting the variable from the
dictionary. It is not possible (in this implementation) to have a key in
the dictionary without value.
This function returns non-zero in case of failure.
*/
/*--------------------------------------------------------------------------*/
int dictionary_set(dictionary * vd, char * key, char * val);
/*-------------------------------------------------------------------------*/
/**
@brief Delete a key in a dictionary
@param d dictionary object to modify.
@param key Key to remove.
@return void
This function deletes a key in a dictionary. Nothing is done if the
key cannot be found.
*/
/*--------------------------------------------------------------------------*/
void dictionary_unset(dictionary * d, char * key);
/*-------------------------------------------------------------------------*/
/**
@brief Dump a dictionary to an opened file pointer.
@param d Dictionary to dump
@param f Opened file pointer.
@return void
Dumps a dictionary onto an opened file pointer. Key pairs are printed out
as @c [Key]=[Value], one per line. It is Ok to provide stdout or stderr as
output file pointers.
*/
/*--------------------------------------------------------------------------*/
void dictionary_dump(dictionary * d, FILE * out);
#endif

View File

@ -0,0 +1,15 @@
#ifndef __FILES9_H__
#define __FILES9_H__
#define ROOT "fpsm"
extern bool saveAvailable;
extern u8 fsMode;
int chdir (const char *path);
bool fileExists(char* filename, char* dir);
bool initFilesystem(int argc, char **argv);
void* bufferizeFile(char* filename, char* dir, bool binary);
#endif

View File

@ -0,0 +1,19 @@
#ifndef __FONT9__
#define __FONT9__
#define CHARSIZE 16
typedef struct
{
mtlImg_struct tex;
int32 charsizef32;
u8 charsize;
}font_struct;
void initText(void);
void setFont(font_struct* f);
void loadFont(font_struct* f, u8 charsize);
void drawChar(char c, u16 color, int32 x, int32 y);
void drawString(char* s, u16 color, int32 size, int32 x, int32 y);
#endif

View File

@ -0,0 +1,49 @@
#ifndef __GENERAL9__
#define __GENERAL9__
#define GAMEVERSION "0.01"
#include <nds.h>
#include <fat.h>
#include <filesystem.h>
#include <maxmod9.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <math.h>
#include <malloc.h>
#include <unistd.h>
// #define FATONLY
#include "soundbank.h"
#include "soundbank_bin.h"
#include "common/iniparser.h"
#include "common/math.h"
#include "common/files.h"
#include "common/audio.h"
#include "dual3D.h"
#include "common/pcx.h"
#include "common/textures.h"
#include "common/md2.h"
#include "common/font.h"
#include "common/GUI.h"
#include "common/keyboard.h"
#include "game/game_ex.h"
#include "editor/editor_ex.h"
#include "acotmenu/acotmenu_ex.h"
#include "debug/xmem.h"
#include "engine/state.h"
#include "engine/debug.h"
#include "engine/memory.h"
extern state_struct gameState;
extern state_struct editorState;
extern state_struct ACOTMenuState;
#endif

View File

@ -0,0 +1,281 @@
/*-------------------------------------------------------------------------*/
/**
@file iniparser.h
@author N. Devillard
@date Sep 2007
@version 3.0
@brief Parser for ini files.
*/
/*--------------------------------------------------------------------------*/
/*
$Id: iniparser.h,v 1.24 2007-11-23 21:38:19 ndevilla Exp $
$Revision: 1.24 $
*/
#ifndef _INIPARSER_H_
#define _INIPARSER_H_
/*---------------------------------------------------------------------------
Includes
---------------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
* The following #include is necessary on many Unixes but not Linux.
* It is not needed for Windows platforms.
* Uncomment it if needed.
*/
/* #include <unistd.h> */
#include "dictionary.h"
/*---------------------------------------------------------------------------
Macros
---------------------------------------------------------------------------*/
/** For backwards compatibility only */
#define iniparser_getstr(d, k) iniparser_getstring(d, k, NULL)
#define iniparser_setstr iniparser_setstring
/*-------------------------------------------------------------------------*/
/**
@brief Get number of sections in a dictionary
@param d Dictionary to examine
@return int Number of sections found in dictionary
This function returns the number of sections found in a dictionary.
The test to recognize sections is done on the string stored in the
dictionary: a section name is given as "section" whereas a key is
stored as "section:key", thus the test looks for entries that do not
contain a colon.
This clearly fails in the case a section name contains a colon, but
this should simply be avoided.
This function returns -1 in case of error.
*/
/*--------------------------------------------------------------------------*/
int iniparser_getnsec(dictionary * d);
/*-------------------------------------------------------------------------*/
/**
@brief Get name for section n in a dictionary.
@param d Dictionary to examine
@param n Section number (from 0 to nsec-1).
@return Pointer to char string
This function locates the n-th section in a dictionary and returns
its name as a pointer to a string statically allocated inside the
dictionary. Do not free or modify the returned string!
This function returns NULL in case of error.
*/
/*--------------------------------------------------------------------------*/
char * iniparser_getsecname(dictionary * d, int n);
/*-------------------------------------------------------------------------*/
/**
@brief Save a dictionary to a loadable ini file
@param d Dictionary to dump
@param f Opened file pointer to dump to
@return void
This function dumps a given dictionary into a loadable ini file.
It is Ok to specify @c stderr or @c stdout as output files.
*/
/*--------------------------------------------------------------------------*/
void iniparser_dump_ini(dictionary * d, FILE * f);
/*-------------------------------------------------------------------------*/
/**
@brief Dump a dictionary to an opened file pointer.
@param d Dictionary to dump.
@param f Opened file pointer to dump to.
@return void
This function prints out the contents of a dictionary, one element by
line, onto the provided file pointer. It is OK to specify @c stderr
or @c stdout as output files. This function is meant for debugging
purposes mostly.
*/
/*--------------------------------------------------------------------------*/
void iniparser_dump(dictionary * d, FILE * f);
/*-------------------------------------------------------------------------*/
/**
@brief Get the string associated to a key
@param d Dictionary to search
@param key Key string to look for
@param def Default value to return if key not found.
@return pointer to statically allocated character string
This function queries a dictionary for a key. A key as read from an
ini file is given as "section:key". If the key cannot be found,
the pointer passed as 'def' is returned.
The returned char pointer is pointing to a string allocated in
the dictionary, do not free or modify it.
*/
/*--------------------------------------------------------------------------*/
char * iniparser_getstring(dictionary * d, const char * key, char * def);
/*-------------------------------------------------------------------------*/
/**
@brief Get the string associated to a key, convert to an int
@param d Dictionary to search
@param key Key string to look for
@param notfound Value to return in case of error
@return integer
This function queries a dictionary for a key. A key as read from an
ini file is given as "section:key". If the key cannot be found,
the notfound value is returned.
Supported values for integers include the usual C notation
so decimal, octal (starting with 0) and hexadecimal (starting with 0x)
are supported. Examples:
- "42" -> 42
- "042" -> 34 (octal -> decimal)
- "0x42" -> 66 (hexa -> decimal)
Warning: the conversion may overflow in various ways. Conversion is
totally outsourced to strtol(), see the associated man page for overflow
handling.
Credits: Thanks to A. Becker for suggesting strtol()
*/
/*--------------------------------------------------------------------------*/
int iniparser_getint(dictionary * d, const char * key, int notfound);
/*-------------------------------------------------------------------------*/
/**
@brief Get the string associated to a key, convert to a double
@param d Dictionary to search
@param key Key string to look for
@param notfound Value to return in case of error
@return double
This function queries a dictionary for a key. A key as read from an
ini file is given as "section:key". If the key cannot be found,
the notfound value is returned.
*/
/*--------------------------------------------------------------------------*/
double iniparser_getdouble(dictionary * d, char * key, double notfound);
/*-------------------------------------------------------------------------*/
/**
@brief Get the string associated to a key, convert to a u8ean
@param d Dictionary to search
@param key Key string to look for
@param notfound Value to return in case of error
@return integer
This function queries a dictionary for a key. A key as read from an
ini file is given as "section:key". If the key cannot be found,
the notfound value is returned.
A true u8ean is found if one of the following is matched:
- A string starting with 'y'
- A string starting with 'Y'
- A string starting with 't'
- A string starting with 'T'
- A string starting with '1'
A false u8ean is found if one of the following is matched:
- A string starting with 'n'
- A string starting with 'N'
- A string starting with 'f'
- A string starting with 'F'
- A string starting with '0'
The notfound value returned if no u8ean is identified, does not
necessarily have to be 0 or 1.
*/
/*--------------------------------------------------------------------------*/
int iniparser_getu8ean(dictionary * d, const char * key, int notfound);
/*-------------------------------------------------------------------------*/
/**
@brief Set an entry in a dictionary.
@param ini Dictionary to modify.
@param entry Entry to modify (entry name)
@param val New value to associate to the entry.
@return int 0 if Ok, -1 otherwise.
If the given entry can be found in the dictionary, it is modified to
contain the provided value. If it cannot be found, -1 is returned.
It is Ok to set val to NULL.
*/
/*--------------------------------------------------------------------------*/
int iniparser_setstring(dictionary * ini, char * entry, char * val);
/*-------------------------------------------------------------------------*/
/**
@brief Delete an entry in a dictionary
@param ini Dictionary to modify
@param entry Entry to delete (entry name)
@return void
If the given entry can be found, it is deleted from the dictionary.
*/
/*--------------------------------------------------------------------------*/
void iniparser_unset(dictionary * ini, char * entry);
/*-------------------------------------------------------------------------*/
/**
@brief Finds out if a given entry exists in a dictionary
@param ini Dictionary to search
@param entry Name of the entry to look for
@return integer 1 if entry exists, 0 otherwise
Finds out if a given entry exists in the dictionary. Since sections
are stored as keys with NULL associated values, this is the only way
of querying for the presence of sections in a dictionary.
*/
/*--------------------------------------------------------------------------*/
int iniparser_find_entry(dictionary * ini, char * entry) ;
/*-------------------------------------------------------------------------*/
/**
@brief Parse an ini file and return an allocated dictionary object
@param ininame Name of the ini file to read.
@return Pointer to newly allocated dictionary
This is the parser for ini files. This function is called, providing
the name of the file to be read. It returns a dictionary object that
should not be accessed directly, but through accessor functions
instead.
The returned dictionary must be freed using iniparser_freedict().
*/
/*--------------------------------------------------------------------------*/
dictionary * iniparser_load(const char * ininame);
dictionary * iniparser_loadBUFF(char* buffer);
/*-------------------------------------------------------------------------*/
/**
@brief Free all memory associated to an ini dictionary
@param d Dictionary to free
@return void
Free all memory associated to an ini dictionary.
It is mandatory to call this function before the dictionary object
gets out of the current context.
*/
/*--------------------------------------------------------------------------*/
void iniparser_freedict(dictionary * d);
#endif

View File

@ -0,0 +1,30 @@
#ifndef __KEYBOARD9__
#define __KEYBOARD9__
#define KEYBOARDBUTTONS 39
guiEntity_struct* keyboardWindow;
guiEntity_struct* keyboardButton[KEYBOARDBUTTONS];
static const char keyboardButtons[] = { '1','2','3','4','5','6','7','8','9','0',
'q','w','e','r','t','y','u','i','o','p',
'a','s','d','f','g','h','j','k','l',
'z','x','c','v','b','n','m',' '};
static const u8 keyboardRows[] = {10,10,9,7};
char* keyboardString;
int keyboardCursor, keyboardStrlen;
guiDrawFunction keyboardReturn;
bool keyboardLock;
void setupKeyboard(char* string, u8 stringlen, guiDrawFunction r);
void keyboardButtonPressed(guiEntity_struct *e);
void showKeyboard();
void hideKeyboard();
void lockKeyboard();
void initKeyboard(u8 t);
void appearKeyboard(u8 t);
void disappearKeyboard(u8 t);
#endif

194
arm9/include/common/math.h Normal file
View File

@ -0,0 +1,194 @@
#ifndef __GENMATH9__
#define __GENMATH9__
#define EPSINT32 2 //check that
#define min(a,b) (((a)>(b))?(b):(a))
#define max(a,b) (((a)>(b))?(a):(b))
#define vect(x,y,z) ((vect3D){(x),(y),(z)})
#define vect2(x,y) ((vect2D){(x),(y)})
typedef struct
{
int32 x, y, z;
}vect3D;
typedef struct
{
int32 x, y;
}vect2D;
static inline void fadeIn(void)
{
int i;for(i=0;i<=16;i++){setBrightness(3,-16+i);swiWaitForVBlank();}
}
static inline void fadeOut(void)
{
int i;for(i=0;i<=16;i++){setBrightness(3,-i);swiWaitForVBlank();}
}
static inline vect3D addVect(vect3D p1, vect3D p2)
{
return vect(p1.x+p2.x,p1.y+p2.y,p1.z+p2.z);
}
static inline vect3D vectMult(vect3D v, int32 k)
{
return vect(mulf32(v.x,k), mulf32(v.y,k), mulf32(v.z,k));
}
static inline vect3D vectMultInt(vect3D v, int k)
{
return vect((v.x*k), (v.y*k), (v.z*k));
}
static inline vect3D vectDivInt(vect3D v, int k)
{
return vect((v.x/k), (v.y/k), (v.z/k));
}
static inline vect3D vectDifference(vect3D p1, vect3D p2)
{
return vect(p1.x-p2.x,p1.y-p2.y,p1.z-p2.z);
}
static inline int32 sqDistance(vect3D p1, vect3D p2)
{
return (mulf32((p1.x-p2.x),(p1.x-p2.x))+mulf32((p1.y-p2.y),(p1.y-p2.y))+mulf32((p1.z-p2.z),(p1.z-p2.z)));
}
static inline int32 distance(vect3D p1, vect3D p2)
{
return sqrtf32(mulf32((p1.x-p2.x),(p1.x-p2.x))+mulf32((p1.y-p2.y),(p1.y-p2.y))+mulf32((p1.z-p2.z),(p1.z-p2.z)));
}
static inline int32 magnitude(vect3D p1)
{
return sqrtf32(mulf32((p1.x),(p1.x))+mulf32((p1.y),(p1.y))+mulf32((p1.z),(p1.z)));
}
static inline int32 sqMagnitude(vect3D p1)
{
return (mulf32((p1.x),(p1.x))+mulf32((p1.y),(p1.y))+mulf32((p1.z),(p1.z)));
}
static inline vect3D divideVect(vect3D v, int32 d)
{
return vect(divf32(v.x,d),divf32(v.y,d),divf32(v.z,d));
}
static inline vect3D normalize(vect3D v)
{
return divideVect(v,sqrtf32(mulf32((v.x),(v.x))+mulf32((v.y),(v.y))+mulf32((v.z),(v.z))));
}
static inline int32 dotProduct(vect3D v1, vect3D v2)
{
return (mulf32(v1.x,v2.x)+mulf32(v1.y,v2.y)+mulf32(v1.z,v2.z));
}
static inline vect3D vectProduct(vect3D v1, vect3D v2)
{
return vect(mulf32(v1.y,v2.z)-mulf32(v1.z,v2.y),mulf32(v1.z,v2.x)-mulf32(v1.x,v2.z),mulf32(v1.x,v2.y)-mulf32(v1.y,v2.x));
}
static inline int32 fakeDotProduct(vect3D v1, vect3D v2)
{
return ((v1.x*v2.x)+(v1.y*v2.y)+(v1.z*v2.z));
}
static inline bool equals(int32 a, int32 b)
{
return abs(a-b)<=EPSINT32;
}
static inline void writeVect(vect3D* v, FILE* f)
{
fwrite(v,sizeof(vect3D),1,f);
}
static inline void readVect(vect3D* v, FILE* f)
{
fread(v,sizeof(vect3D),1,f);
}
//Original code by Mollusk (below this point)
int ArcTan2(int dx, int dy);
static const short TABLE_SIN[512] = {
0x0000,0x0003,0x0006,0x0009,0x000D,0x0010,0x0013,0x0016, 0x0019,0x001C,0x001F,0x0022,0x0026,0x0029,0x002C,0x002F,
0x0032,0x0035,0x0038,0x003B,0x003E,0x0041,0x0044,0x0047, 0x004A,0x004D,0x0050,0x0053,0x0056,0x0059,0x005C,0x005F,
0x0062,0x0065,0x0068,0x006B,0x006D,0x0070,0x0073,0x0076, 0x0079,0x007B,0x007E,0x0081,0x0084,0x0086,0x0089,0x008C,
0x008E,0x0091,0x0093,0x0096,0x0098,0x009B,0x009D,0x00A0, 0x00A2,0x00A5,0x00A7,0x00AA,0x00AC,0x00AE,0x00B1,0x00B3,
0x00B5,0x00B7,0x00B9,0x00BC,0x00BE,0x00C0,0x00C2,0x00C4, 0x00C6,0x00C8,0x00CA,0x00CC,0x00CE,0x00CF,0x00D1,0x00D3,
0x00D5,0x00D7,0x00D8,0x00DA,0x00DC,0x00DD,0x00DF,0x00E0, 0x00E2,0x00E3,0x00E5,0x00E6,0x00E7,0x00E9,0x00EA,0x00EB,
0x00ED,0x00EE,0x00EF,0x00F0,0x00F1,0x00F2,0x00F3,0x00F4, 0x00F5,0x00F6,0x00F7,0x00F8,0x00F8,0x00F9,0x00FA,0x00FA,
0x00FB,0x00FC,0x00FC,0x00FD,0x00FD,0x00FE,0x00FE,0x00FE, 0x00FF,0x00FF,0x00FF,0x0100,0x0100,0x0100,0x0100,0x0100,
0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x00FF,0x00FF, 0x00FF,0x00FE,0x00FE,0x00FE,0x00FD,0x00FD,0x00FC,0x00FC,
0x00FB,0x00FA,0x00FA,0x00F9,0x00F8,0x00F8,0x00F7,0x00F6, 0x00F5,0x00F4,0x00F3,0x00F2,0x00F1,0x00F0,0x00EF,0x00EE,
0x00ED,0x00EB,0x00EA,0x00E9,0x00E7,0x00E6,0x00E5,0x00E3, 0x00E2,0x00E0,0x00DF,0x00DD,0x00DC,0x00DA,0x00D8,0x00D7,
0x00D5,0x00D3,0x00D1,0x00CF,0x00CE,0x00CC,0x00CA,0x00C8, 0x00C6,0x00C4,0x00C2,0x00C0,0x00BE,0x00BC,0x00B9,0x00B7,
0x00B5,0x00B3,0x00B1,0x00AE,0x00AC,0x00AA,0x00A7,0x00A5, 0x00A2,0x00A0,0x009D,0x009B,0x0098,0x0096,0x0093,0x0091,
0x008E,0x008C,0x0089,0x0086,0x0084,0x0081,0x007E,0x007B, 0x0079,0x0076,0x0073,0x0070,0x006D,0x006B,0x0068,0x0065,
0x0062,0x005F,0x005C,0x0059,0x0056,0x0053,0x0050,0x004D, 0x004A,0x0047,0x0044,0x0041,0x003E,0x003B,0x0038,0x0035,
0x0032,0x002F,0x002C,0x0029,0x0026,0x0022,0x001F,0x001C, 0x0019,0x0016,0x0013,0x0010,0x000D,0x0009,0x0006,0x0003,
0x0000,0xFFFD,0xFFFA,0xFFF7,0xFFF3,0xFFF0,0xFFED,0xFFEA, 0xFFE7,0xFFE4,0xFFE1,0xFFDE,0xFFDA,0xFFD7,0xFFD4,0xFFD1,
0xFFCE,0xFFCB,0xFFC8,0xFFC5,0xFFC2,0xFFBF,0xFFBC,0xFFB9, 0xFFB6,0xFFB3,0xFFB0,0xFFAD,0xFFAA,0xFFA7,0xFFA4,0xFFA1,
0xFF9E,0xFF9B,0xFF98,0xFF95,0xFF93,0xFF90,0xFF8D,0xFF8A, 0xFF87,0xFF85,0xFF82,0xFF7F,0xFF7C,0xFF7A,0xFF77,0xFF74,
0xFF72,0xFF6F,0xFF6D,0xFF6A,0xFF68,0xFF65,0xFF63,0xFF60, 0xFF5E,0xFF5B,0xFF59,0xFF56,0xFF54,0xFF52,0xFF4F,0xFF4D,
0xFF4B,0xFF49,0xFF47,0xFF44,0xFF42,0xFF40,0xFF3E,0xFF3C, 0xFF3A,0xFF38,0xFF36,0xFF34,0xFF32,0xFF31,0xFF2F,0xFF2D,
0xFF2B,0xFF29,0xFF28,0xFF26,0xFF24,0xFF23,0xFF21,0xFF20, 0xFF1E,0xFF1D,0xFF1B,0xFF1A,0xFF19,0xFF17,0xFF16,0xFF15,
0xFF13,0xFF12,0xFF11,0xFF10,0xFF0F,0xFF0E,0xFF0D,0xFF0C, 0xFF0B,0xFF0A,0xFF09,0xFF08,0xFF08,0xFF07,0xFF06,0xFF06,
0xFF05,0xFF04,0xFF04,0xFF03,0xFF03,0xFF02,0xFF02,0xFF02, 0xFF01,0xFF01,0xFF01,0xFF00,0xFF00,0xFF00,0xFF00,0xFF00,
0xFF00,0xFF00,0xFF00,0xFF00,0xFF00,0xFF00,0xFF01,0xFF01, 0xFF01,0xFF02,0xFF02,0xFF02,0xFF03,0xFF03,0xFF04,0xFF04,
0xFF05,0xFF06,0xFF06,0xFF07,0xFF08,0xFF08,0xFF09,0xFF0A, 0xFF0B,0xFF0C,0xFF0D,0xFF0E,0xFF0F,0xFF10,0xFF11,0xFF12,
0xFF13,0xFF15,0xFF16,0xFF17,0xFF19,0xFF1A,0xFF1B,0xFF1D, 0xFF1E,0xFF20,0xFF21,0xFF23,0xFF24,0xFF26,0xFF28,0xFF29,
0xFF2B,0xFF2D,0xFF2F,0xFF31,0xFF32,0xFF34,0xFF36,0xFF38, 0xFF3A,0xFF3C,0xFF3E,0xFF40,0xFF42,0xFF44,0xFF47,0xFF49,
0xFF4B,0xFF4D,0xFF4F,0xFF52,0xFF54,0xFF56,0xFF59,0xFF5B, 0xFF5E,0xFF60,0xFF63,0xFF65,0xFF68,0xFF6A,0xFF6D,0xFF6F,
0xFF72,0xFF74,0xFF77,0xFF7A,0xFF7C,0xFF7F,0xFF82,0xFF85, 0xFF87,0xFF8A,0xFF8D,0xFF90,0xFF93,0xFF95,0xFF98,0xFF9B,
0xFF9E,0xFFA1,0xFFA4,0xFFA7,0xFFAA,0xFFAD,0xFFB0,0xFFB3, 0xFFB6,0xFFB9,0xFFBC,0xFFBF,0xFFC2,0xFFC5,0xFFC8,0xFFCB,
0xFFCE,0xFFD1,0xFFD4,0xFFD7,0xFFDA,0xFFDE,0xFFE1,0xFFE4, 0xFFE7,0xFFEA,0xFFED,0xFFF0,0xFFF3,0xFFF7,0xFFFA,0xFFFD};
#define Math_Cos(angle) TABLE_SIN[((angle) + 128)&511]
#define Math_Sin(angle) TABLE_SIN[((angle))&511]
extern inline u64 Math_FakeDistance(s32 x1, s32 y1, s32 x2, s32 y2) {
s64 h = x1 - x2;
s64 v = y1 - y2;
return(h*h + v*v);
}
u16 Math_AdjustAngle(u16 angle, s16 anglerot, s32 startx, s32 starty, s32 targetx, s32 targety);
extern inline u16 getAngle(s32 startx, s32 starty, s32 targetx, s32 targety) {
u16 angle = 0;
u16 anglerot = 180;
while(anglerot > 5) {
angle = Math_AdjustAngle(angle, anglerot, startx, starty, targetx, targety);
anglerot = (anglerot - ((3 * anglerot) >> 3)); // On diminue petit ? petit la rotation...
}
// Ajustement encore plus pr?cis...
anglerot = 4;
angle = Math_AdjustAngle(angle, anglerot, startx, starty, targetx, targety);
anglerot = 2;
angle = Math_AdjustAngle(angle, anglerot, startx, starty, targetx, targety);
anglerot = 1;
angle = Math_AdjustAngle(angle, anglerot, startx, starty, targetx, targety);
return angle;
}
#endif

112
arm9/include/common/md2.h Normal file
View File

@ -0,0 +1,112 @@
#ifndef __MD29__
#define __MD29__
/* Vector */
typedef float vec3_t[3];
/* MD2 header */
typedef struct
{
int ident;
int version;
int skinwidth;
int skinheight;
int framesize;
int num_skins;
int num_vertices;
int num_st;
int num_tris;
int num_glcmds;
int num_frames;
int offset_skins;
int offset_st;
int offset_tris;
int offset_frames;
int offset_glcmds;
int offset_end;
}md2_header_t;
/* Texture name */
typedef struct
{
char name[64];
}md2_skin_t;
/* Texture coords */
typedef struct
{
short s;
short t;
}md2_texCoord_t;
/* Triangle info */
typedef struct
{
unsigned short vertex[3];
unsigned short st[3];
}md2_triangle_t;
/* Compressed vertex */
typedef struct
{
unsigned char v[3];
unsigned char normalIndex;
}md2_vertex_t;
/* Model frame */
typedef struct
{
vect3D scale;
vect3D translate;
char name[16];
md2_vertex_t *verts;
vect3D *packedVerts;
u32 *packedv10;
vect3D* faceNormals;
}md2_frame_t;
typedef struct
{
u16 start, end;
}md2Anim_struct;
/* MD2 model structure */
typedef struct
{
md2_header_t header;
u8 numAnim;
md2Anim_struct* animations;
mtlImg_struct* texture;
md2_skin_t *skins;
md2_texCoord_t *texcoords;
u32 *packedTexcoords;
md2_triangle_t *triangles;
md2_frame_t *frames;
}md2Model_struct;
typedef struct
{
u16 currentFrame, nextFrame, interpCounter;
u8 currentAnim;
u8 oldAnim;
bool oneshot;
md2Model_struct* model;
}modelInstance_struct;
void freeMd2Model(md2Model_struct *mdl);
void renderModelFrame (int n, const md2Model_struct *mdl);
void renderModelFrameInterp(int n, int n2, int m, const md2Model_struct *mdl, u32 params);
int loadMd2Model (const char *filename, char *texname, md2Model_struct *mdl);
void initModelInstance(modelInstance_struct* mi, md2Model_struct* mdl);
void changeAnimation(modelInstance_struct* mi, u16 newAnim, bool oneshot);
void updateAnimation(modelInstance_struct* mi);
#endif

46
arm9/include/common/pcx.h Normal file
View File

@ -0,0 +1,46 @@
#ifndef __PCX9__
#define __PCX9__
/* OpenGL texture info */
struct gl_texture_t
{
u16 width;
u16 height;
int format;
int internalFormat;
u32 id;
u8 *texels;
u16 *palette;
};
#pragma pack(1)
/* PCX header */
struct pcx_header_t
{
u8 manufacturer;
u8 version;
u8 encoding;
u8 bitsPerPixel;
u16 xmin, ymin;
u16 xmax, ymax;
u16 horzRes, vertRes;
u8 palette[48];
u8 reserved;
u8 numColorPlanes;
u16 bytesPerScanLine;
u16 paletteType;
u16 horzSize, vertSize;
u8 padding[54];
};
#pragma pack(4)
struct gl_texture_t * ReadPCXFile (const char *filename, char* directory);
void freePCX(struct gl_texture_t * pcx);
#endif

View File

@ -0,0 +1,65 @@
#ifndef __TEXTURES9__
#define __TEXTURES9__
#define MAX_TEX 128
#define BANKS vramBanks
u8 vramBanks;
typedef struct
{
size_t s_total, s_used, s_free;
void* addr;
int num_t;
}vramBank_struct;
typedef struct
{
u16 width, height;
u16 rwidth, rheight;
int ID;
int bank;
size_t size;
u32 param;
char* name;
void *addr, *pal;
u32 palbind;
bool used;
}mtlImg_struct;
static inline void Game_FastBind(mtlImg_struct *mtl)
{
GFX_PAL_FORMAT = mtl->palbind;
GFX_TEX_FORMAT = mtl->param;
}
void initTextures();
mtlImg_struct* createTexture(char* filename, char* directory);
mtlImg_struct* createTextureBuffer16(u16* buffer, u16 x, u16 y, bool cpy);
mtlImg_struct* createTextureBuffer(u8* buffer, u16* buffer2, u16 x, u16 y);
mtlImg_struct* createTextureBufferA5I3(u8* buffer, u16* buffer2, u16 x, u16 y);
mtlImg_struct* createReservedTextureBufferA5I3(u8* buffer, u16* buffer2, u16 x, u16 y, void* addr);
void loadToBank(mtlImg_struct *mtl, u8* data);
void loadPaletteToBank(mtlImg_struct *mtl, u16* data, size_t size);
void loadTextureBuffer16(u16* buffer, u16 x, u16 y, mtlImg_struct *mtl, bool genaddr, bool cpy);
void loadTextureBuffer(u8* buffer, u16* buffer2, u16 x, u16 y, mtlImg_struct *mtl);
void loadTextureBufferA5I3(u8* buffer, u16* buffer2, u16 x, u16 y, mtlImg_struct *mtl);
void loadReservedTextureBufferA5I3(u8* buffer, u16* buffer2, u16 x, u16 y, mtlImg_struct *mtl, void* addr);
void loadPartToBank(mtlImg_struct *mtl, u8* data, u16 w, u16 h, u16 x, u16 y, bool rot);
void loadTexturePCX(char* filename, char* directory, mtlImg_struct* mtl);
void applyMTL(mtlImg_struct *mtl);
void initVramBanks(u8 banks);
void getVramStatus();
void unbindMtl();
void addToBank(mtlImg_struct *mtl, u8* data, int b);
void setTextureParameter(mtlImg_struct *mtl, uint8 sizeX, uint8 sizeY, const uint32* addr, GL_TEXTURE_TYPE_ENUM mode, uint32 param);
void* getTextureAddress(mtlImg_struct *mtl);
void addPaletteToBank(mtlImg_struct *mtl, u16* data, size_t size);
void bindPalette(mtlImg_struct *mtl);
void bindPalette4(mtlImg_struct *mtl);
void bindTexture(mtlImg_struct *mtl);
void getGlWL(u16 width, u16 height, u8* w, u8* l);
void changeTextureSizeA5I3(mtlImg_struct *mtl, u16 x, u16 y);
#endif

21
arm9/include/debug/xmem.h Normal file
View File

@ -0,0 +1,21 @@
/*
* xmem.h
* part of the xlibrary by SunDEV (http://sundev.890m.com)
*
* Changelog :
* 21-03-09 : First public release
*
*/
#ifndef _XMEM_H
#define _XMEM_H
size_t latestUsed, latestFree;
u8 *getHeapStart();
u8 *getHeapEnd();
u8 *getHeapLimit();
size_t getMemUsed();
size_t getMemFree();
#endif

9
arm9/include/dual3D.h Normal file
View File

@ -0,0 +1,9 @@
#ifndef __D3D9__
#define __D3D9__
extern bool d3dScreen;
void initD3D();
void updateD3D();
#endif

View File

@ -0,0 +1,9 @@
#ifndef __EDITOREX9__
#define __EDITOREX9__
void initEditor(void);
void editorFrame(void);
void killEditor(void);
void editorVBL(void);
#endif

View File

@ -0,0 +1,19 @@
#ifndef __EDITORMAIN9__
#define __EDITORMAIN9__
#include "common/general.h"
#include "editor/material.h"
#include "game/lightmaps.h"
#include "game/map.h"
#include "game/physics.h"
#include "game/camera.h"
#include "editor/grid.h"
#include "editor/entity.h"
#include "editor/room.h"
#include "game/pathfinding.h"
#include "game/enemy.h"
#include "game/doors.h"
#include "game/player.h"
#include "editor/rectangle.h"
#endif

View File

@ -0,0 +1,52 @@
#ifndef __ENTITY9__
#define __ENTITY9__
#define ENTITYCOLLECTIONNUM 128
typedef enum
{
lightEntity,
enemyEntity,
}entity_type;
typedef struct
{
int32 intensity;
}lightData_struct;
typedef struct
{
u8 type;
}enemyData_struct;
typedef struct
{
vect3D position, origin;
entity_type type;
mtlImg_struct* mtl;
bool selected;
void* data;
bool used;
}entity_struct;
typedef struct
{
entity_struct entity[ENTITYCOLLECTIONNUM];
u16 num;
}entityCollection_struct;
void initEntity(entity_struct* e);
void initEnemy(entity_struct* e, u8 type);
void initLight(entity_struct* e, int32 intensity);
void initEntityCollection(entityCollection_struct* ec);
void wipeEntityCollection(entityCollection_struct* ec);
entity_struct* createEntity(entityCollection_struct* ec, vect3D position);
entity_struct* createLight(entityCollection_struct* ec, vect3D position, int32 intensity);
entity_struct* createEnemy(entityCollection_struct* ec, vect3D position, u8 type);
void removeEntity(entityCollection_struct* ec, entity_struct* e);
void drawEntity(entity_struct* e);
void drawEntityCollection(entityCollection_struct* ec);
void renderEntityCollection(entityCollection_struct* ec);
entity_struct* collideEntityCollection(entityCollection_struct* ec, int px, int py);
#endif

View File

@ -0,0 +1,14 @@
#ifndef __GRID9__
#define __GRID9__
void initGrid(void);
void drawGrid(void);
void projectGrid(void);
void transformGrid(void);
void setGridScale(int32 s);
void setGridTranslation(vect3D v);
void translateGrid(vect3D v);
void scaleGrid(int32 s);
void getGridCell(int* x, int* y, int px, int py);
#endif

View File

@ -0,0 +1,39 @@
#ifndef __MATERIAL9__
#define __MATERIAL9__
#define NUMMATERIALS 256
#define NUMMATERIALSLICES 256
typedef struct
{
mtlImg_struct* img;
u16 id;
s16 factor;
bool align;
bool used;
}materialSlice_struct;
typedef struct
{
materialSlice_struct* top;
materialSlice_struct* side;
materialSlice_struct* bottom;
u16 id;
bool used;
}material_struct;
static inline u16 getMaterialID(material_struct* m){if(m)return m->id;return 0;}
void initMaterials(void);
material_struct* createMaterial();
materialSlice_struct* createMaterialSlice();
void loadMaterialSlice(materialSlice_struct* ms, char* filename);
void loadMaterialSlices(char* filename);
void loadMaterials(char* filename);
material_struct* getMaterial(u16 i);
char** getMaterialList(int* m, int** cl);
void freeMaterialList(char** l);
#endif

View File

@ -0,0 +1,61 @@
#ifndef __RECTANGLE9__
#define __RECTANGLE9__
typedef enum
{
EMPTY,
RECTANGLE,
HORIZONTAL,
VERTICAL
}treeNode_type;
typedef struct treeNode_struct
{
struct treeNode_struct* son[2];
treeNode_type type;
short data;
}treeNode_struct;
typedef struct
{
treeNode_struct* root;
short width, height;
}tree_struct;
typedef struct
{
vect2D position, size;
rectangle_struct* real;
bool rot;
}rectangle2D_struct;
typedef struct listCell2D_struct
{
rectangle2D_struct data;
struct listCell2D_struct* next;
}listCell2D_struct;
typedef struct
{
listCell2D_struct* first;
int surface;
int num;
}rectangle2DList_struct;
void initRectangle2DList(rectangle2DList_struct* l);
void insertRectangle2DList(rectangle2DList_struct* l, rectangle2D_struct rec);
void packRectangles(rectangle2DList_struct* l, short w, short h);
bool packRectanglesSize(rectangle2DList_struct* l, short* w, short* h);
void freeRectangle2DList(rectangle2DList_struct* l);
void fillRectangle(u8* data, int w, int h, vect2D* pos, vect2D* size);
void getMaxRectangle(u8* data, int w, int h, vect2D* pos, vect2D* size);
void scanEdge(roomEdit_struct* re, u8* data, int w, int h, vect2D* pos, vect2D* size, u8 edge, u8 reverse, bool ceil);
void scanEdgeWall(roomEdit_struct* re, u8* floor, u8* ceiling, int w, int h, vect2D* pos, vect2D* size, u8 edge);
void scanEdgeInnerWall(roomEdit_struct* re, u8* floor, u8* ceiling, int w, int h, vect2D* pos, vect2D* size, u8 edge);
bool collideLineRectangle(rectangle_struct* rec, vect3D o, vect3D v, int32 d, int32* kk, vect3D* ip);
vect3D getClosestPointRectangle(rectangle_struct* rec, vect3D o);
void bindMaterial(material_struct* m, rectangle_struct* rec, int32* t);
#endif

View File

@ -0,0 +1,74 @@
#ifndef __ROOMEDIT9__
#define __ROOMEDIT9__
#define NUMROOMEDITS 256
#define OUTLINEWIDTH (3<<6)
#define SELECTIONOUTLINEWIDTH (1<<7)
#define ROOMCREATION 0
#define ROOMSIZING 1
#define ROOMSELECTMOVE 2
#define ROOMMOVING 3
#define ROOMSELECTRESIZE 4
#define ROOMSELECTION 5
#define TILESELECTION 6
#define ENTITYSELECTION 7
#define LIGHTCREATION 8
#define ENTITYMOVING 9
#define ENEMYCREATION 10
#define DOORCREATION 11
#define DOORMOVING 12
typedef struct
{
entityCollection_struct entityCollection;
room_struct data;
vect3D position;
vect3D origin;
vect3D size;
bool selected;
bool floor;
bool quadsUpToDate;
bool lightUpToDate;
bool used;
s16 id;
}roomEdit_struct;
static inline void drawTile(u16 x, u16 y, u16 color)
{
GFX_COLOR=color;
glPushMatrix();
glTranslate3f32(x*(1<<9),y*(1<<9),16);
glScalef32(1*(1<<9),1*(1<<9),inttof32(1));
glBegin(GL_QUADS);
glVertex3v16(0, inttof32(1), 0);
glVertex3v16(inttof32(1), inttof32(1), 0);
glVertex3v16(inttof32(1), 0, 0);
glVertex3v16(0, 0, 0);
glPopMatrix(1);
}
void drawRoomEdits(void);
void initRoomEditor(void);
void drawRoomsGame(u8 mode);
void drawRoomsPreview(void);
void setRoomEditorMode(u8 mode);
void updateRoomEditor(int px, int py);
void initRoomEdit(roomEdit_struct* re);
void drawRoomEdit(roomEdit_struct* re);
void deleteRoomEdit(roomEdit_struct* re);
void moveData(s8 v, roomEdit_struct* re, vect3D* so, vect3D* ss);
void applyMaterial(material_struct* mat, roomEdit_struct* re, vect3D* so, vect3D* ss);
void makeWall(roomEdit_struct* re, vect3D* so, vect3D* ss);
void swapData(roomEdit_struct* re);
void addRoomRectangle(room_struct* r, entityCollection_struct* ec, rectangle_struct rec, material_struct* mat);
void generateLightmaps(roomEdit_struct* re, room_struct* r, entityCollection_struct* ec);
void optimizeRoom(roomEdit_struct* re);
void changeRoom(roomEdit_struct* re, bool both);
void wipeMapEdit(void);
void writeMap(char* filename);
void readMap(char* filename, bool game);
void getRoomDoorWays(void);
entityCollection_struct* getEntityCollection(room_struct* r);
#endif

View File

@ -0,0 +1,38 @@
#ifndef __DEBUG9__
#define __DEBUG9__
#define VERSIONMAGIC 45464873
int glob_time;
#define PROF_START() \
do { \
TIMER2_DATA = 0; TIMER3_DATA = 0; \
TIMER3_CR = TIMER_ENABLE | TIMER_CASCADE | TIMER_IRQ_REQ; \
TIMER2_CR = TIMER_ENABLE; \
} while(0)
#define PROF_GET(_time) _time = ( TIMER3_DATA << 16 ) | TIMER2_DATA;
#define PROF_END(_time) \
do { \
_time = ( TIMER3_DATA << 16 ) | TIMER2_DATA; \
TIMER2_CR = 0; TIMER3_CR = 0; \
} while(0)
#define PROF2_START()
#define PROF2_END(_time) _time=92431
#define NOGBA(_fmt, _args...) do { char nogba_buffer[256]; sprintf(nogba_buffer, _fmt, ##_args); N3DNoCashMsg(nogba_buffer); } while(0)
extern int N3DNoCashMsg(const char *pText);
int TESTANGLE2;
void DS_Debug(char* string, ...);
void DS_DebugPause(void);
size_t DS_UsedMem(void);
size_t DS_FreeMem(void);
#endif

View File

@ -0,0 +1,13 @@
#ifndef __MEMORY9__
#define __MEMORY9__
#define MAX_MALLOC 512
void *GetStackPointer();
void* alloc(size_t size, state_struct* state);
void* reAlloc(void* p, size_t size, state_struct* s);
void freeState(state_struct* state);
void initMalloc();
#endif

View File

@ -0,0 +1,20 @@
#ifndef __STATE9__
#define __STATE9__
typedef void(*function)();
typedef struct{
function init,frame,kill,vbl;
u16 mc_id;
u8 id;
bool used;
}state_struct;
void applyState(void);
void initHardware(void);
state_struct* getCurrentState(void);
void setState(state_struct* s);
void changeState(state_struct* s);
void createState(state_struct* s, function i, function f, function k, function vbl);
#endif

View File

@ -0,0 +1,52 @@
#ifndef __CAMERA9__
#define __CAMERA9__
typedef struct
{
int32 A, B, C, D;
vect3D point;
}plane_struct;
typedef struct
{
plane_struct plane[6];
}frustum_struct;
typedef struct
{
vect3D position, angle, angle2;
frustum_struct frustum;
vect3D space[3];
int32 transformationMatrix[3*3];
int32 projectionMatrix[4*4];
int32 viewMatrix[4*4];
bool lookAt;
physicsObject_struct object;
}camera_struct;
static inline int32 evaluatePlanePoint(plane_struct* p, vect3D v)
{
if(!p)return 0;
return mulf32(p->A,v.x)+mulf32(p->B,v.y)+mulf32(p->C,v.z)+p->D;
}
void initCamera(camera_struct* c);
void projectCamera(camera_struct* c);
void transformCamera(camera_struct* c);
void moveCamera(camera_struct* c, vect3D v);
void rotateCamera(camera_struct* c, vect3D a);
vect3D getCameraPosition(camera_struct* c);
void setCamera(camera_struct* c, vect3D v);
void updateCamera(camera_struct* c);
void updateCameraPreview(room_struct* r, camera_struct* c);
camera_struct* getPlayerCamera(void);
vect3D getUnitVector(camera_struct* c);
void changeBase(int32* tm, vect3D x, vect3D y, vect3D z, bool r);
void multMatrix33(int32* m1, int32* m2, int32* m);
void multMatrix44(int32* m1, int32* m2, int32* m);
void translateMatrix(int32* tm, int32 x, int32 y, int32 z);
vect3D clipPointFrustum(frustum_struct* f, vect3D* v, u8 vid, const u8 vn);
#endif

63
arm9/include/game/doors.h Normal file
View File

@ -0,0 +1,63 @@
#ifndef __DOORS9__
#define __DOORS9__
#define NUMDOORS (256)
#define DOORPERIOD 120
#define DOORSIZE 2
#define DOORHEIGHT 12
typedef enum
{
doorUp,
doorRight,
doorDown,
doorLeft,
}doorDirection;
typedef struct
{
room_struct *primaryRoom, *secondaryRoom;
rectangle_struct primaryRec, secondaryRec;
doorDirection direction;
u16 position, height;
s16 percentage;
u16 timer;
bool selected;
bool open;
bool used;
}door_struct;
typedef struct
{
door_struct door[NUMDOORS];
}doorCollection_struct;
void initDoor(door_struct* d);
void getSecondaryRooms(doorCollection_struct* dc);
void initDoorCollection(doorCollection_struct* dc);
void getDoorRectangle(door_struct* d, bool primary, rectangle_struct* rrrec);
void confirmDoors(doorCollection_struct* dc);
void confirmRoomDoors(doorCollection_struct* dc, room_struct* r);
bool collideSegmentDoors(doorCollection_struct* dc, room_struct* r, vect3D p1, vect3D p2);
door_struct* inDoorWay(doorCollection_struct* dc, room_struct* r, int x, int y, bool secondary, bool override);
door_struct* createDoor(doorCollection_struct* dc, room_struct* pr, u16 position, doorDirection dir, bool override);
void renderRoomDoors(doorCollection_struct* dc, room_struct* r);
void getRoomDoorRectangles(doorCollection_struct* dc, room_struct* r);
door_struct* getClosestDoorRoom(doorCollection_struct* dc, room_struct* r, vect2D p, int* distt);
void updateDoors(doorCollection_struct* dc);
bool toggleDoor(room_struct* r, door_struct* d);
void closeRoomDoors(doorCollection_struct* dc, room_struct* r, door_struct* d);
bool isDoorOpen(doorCollection_struct* dc, room_struct* r1, room_struct* r2);
void getDoorWayData(doorCollection_struct* dc, room_struct* r);
#ifdef __EDITORMAIN9__
void drawDoor(roomEdit_struct* re, door_struct* d);
void drawRoomDoors(doorCollection_struct* dc, roomEdit_struct* re);
door_struct* doorTouches(doorCollection_struct* dc, roomEdit_struct* re, int x, int y, bool secondary);
bool doorCollides(doorCollection_struct* dc, room_struct* r, doorDirection dd, u16 p, door_struct* d2);
#endif
#endif

48
arm9/include/game/enemy.h Normal file
View File

@ -0,0 +1,48 @@
#ifndef __ENEMY9__
#define __ENEMY9__
#define ANIMIDLE 0
#define ANIMWALK 1
#define ANIMRUN 3
#define ANIMATTACK 5
#define ANIMDEATH 7
#define ANIMPAIN 8
#define NUMENEMIES 256
#define ENEMYWALKINGSPEED 32
#define ENEMYRUNNINGSPEED 8
#define WALKTO 1
#define RUNTO 2
typedef struct
{
vect3D tilePosition;
vect3D targetPosition;
vect3D nextTilePosition;
physicsObject_struct object;
entityCollection_struct* ec;
modelInstance_struct modelInstance;
path_struct path;
room_struct* r;
u16 progress;
s16 angle;
u16 task;
s16 life;
bool used, detected, pathed;
}enemy_struct;
void initEnemies(void);
void createEn(room_struct* r, vect3D p);
void drawEnemy(enemy_struct* e);
void drawEnemies(void);
void freeEnemies(void);
void updateEnemies(void);
void moveRoomEnemiesTo(room_struct* r, int x, int y, u8 task);
bool collideLineEnemy(enemy_struct* e, vect3D l, vect3D u, int32 d, int32* k, vect3D* ip);
enemy_struct* collideLineRoomEnemies(room_struct* r, vect3D l, vect3D u, int32 d, int32* k, vect3D* ip);
void getClosestLights(entityCollection_struct* ec, enemy_struct* e, entity_struct** ll1, entity_struct** ll2, entity_struct** ll3, int32* dd1, int32* dd2, int32* dd3);
#endif

View File

@ -0,0 +1,9 @@
#ifndef __GAMEEX9__
#define __GAMEEX9__
void initGame(void);
void gameFrame(void);
void killGame(void);
void gameVBL(void);
#endif

View File

@ -0,0 +1,22 @@
#ifndef __GAMEMAIN9__
#define __GAMEMAIN9__
#include "common/general.h"
#include "editor/material.h"
#include "game/lightmaps.h"
#include "game/map.h"
#include "game/physics.h"
#include "game/camera.h"
#include "game/polygon.h"
#include "game/doors.h"
#include "game/player.h"
#include "editor/entity.h"
#include "game/pathfinding.h"
#include "game/enemy.h"
#include "game/particles.h"
#include "game/portals.h"
#include "editor/room.h"
#include "editor/rectangle.h"
#include "PI9.h"
#endif

View File

@ -0,0 +1,15 @@
#ifndef __LIGHTMAPS9__
#define __LIGHTMAPS9__
#define LIGHTMAPSLOTS 1
typedef struct
{
mtlImg_struct* mtl;
void* r;
bool used;
}lightMapSlots_struct;
void initLightMaps(void);
#endif

83
arm9/include/game/map.h Normal file
View File

@ -0,0 +1,83 @@
#ifndef __MAP9__
#define __MAP9__
#define TILESIZE (256)
#define HEIGHTUNIT (128)
#define SCALEFACT (inttof32(150))
// #define MAXHEIGHT 31
#define MAXHEIGHT 127
#define STARTHEIGHT 16 //TEMP
#define DEFAULTFLOOR 8
#define DEFAULTCEILING 24
#define LIGHTMAPRESOLUTION 5
#define LIGHTCONST (0)
typedef struct
{
vect3D position, size, lmSize, lmPos, normal;
material_struct* material;
bool rot, hide;
}rectangle_struct;
typedef struct listCell_struct
{
rectangle_struct data;
struct listCell_struct* next;
}listCell_struct;
typedef struct
{
listCell_struct* first;
int num;
}rectangleList_struct;
typedef struct
{
u8* floor;
u8* ceiling;
material_struct** materials;
vect3D position;
vect3D lmSize;
u16 width, height;
u8* lightMapBuffer;
u8* pathfindingData;
void** doorWay;
mtlImg_struct* lightMap;
lightMapSlots_struct* lmSlot;
rectangleList_struct rectangles;
}room_struct;
static inline vect3D convertVect(vect3D v)
{
return vect(v.x*TILESIZE*2-TILESIZE,v.y*HEIGHTUNIT,v.z*TILESIZE*2-TILESIZE);
}
static inline vect3D convertSize(vect3D v)
{
return vect(v.x*TILESIZE*2,v.y*HEIGHTUNIT,v.z*TILESIZE*2);
}
void initRoom(room_struct* r, u16 w, u16 h, vect3D p);
void resizeRoom(room_struct* r, u16 l, u16 w, vect3D p);
// void addRoomRectangle(room_struct* r, entityCollection_struct* ec, rectangle_struct rec);
void initRectangle(rectangle_struct* rec, vect3D pos, vect3D size);
void removeRectangles(room_struct* r);
void drawRoom(room_struct* r, u8 mode);
void freeRoom(room_struct* r);
void drawRect(rectangle_struct rec, vect3D pos, vect3D size, bool c);
bool collideLineMap(room_struct* r, rectangle_struct* rec, vect3D l, vect3D u, int32 d, vect3D* i);
rectangle_struct* collideLineMapClosest(room_struct* r, rectangle_struct* rec, vect3D l, vect3D u, int32 d, vect3D* i);
void getPathfindingData(room_struct* r);
//lightmaps.h
void loadLightMap(room_struct* r);
void unloadLightMap(room_struct* r);
void unloadAllLightMaps(room_struct* r);
void unloadLightMaps(room_struct* r, room_struct* r2);
#endif

View File

@ -0,0 +1,21 @@
#ifndef __PARTICLES9__
#define __PARTICLES9__
#define NUMPARTICLES 128
typedef struct
{
vect3D position, speed;
u16 life, timer, color;
u8 alpha;
bool used;
}particle_struct;
void initParticles(void);
void drawParticles(void);
void updateParticles(void);
void particleExplosion(vect3D p, int number, u16 color);
void particleExplosionDir(vect3D p, vect3D dir, int number, u16 color);
void createParticles(vect3D position, vect3D speed, u16 life, u16 color);
#endif

View File

@ -0,0 +1,62 @@
#ifndef __PATHFINDING9__
#define __PATHFINDING9__
#define DIRUP 1
#define DIRDOWN (1<<1)
#define DIRLEFT (1<<2)
#define DIRRIGHT (1<<3)
typedef enum
{
noList=0,
openList=1,
closedList=2,
}listType;
typedef struct
{
listType inList;
unsigned char X, Y;
unsigned char parentX, parentY;
unsigned short gCost;
unsigned short fCost;
}pathNode_struct;
typedef struct listNode_struct
{
pathNode_struct* data;
struct listNode_struct* next;
}listNode_struct;
typedef struct
{
listNode_struct* first;
}openList_struct;
typedef struct pathCell_struct
{
unsigned char X, Y;
struct pathCell_struct* next;
}pathCell_struct;
typedef struct
{
pathCell_struct* first;
}path_struct;
typedef struct
{
unsigned char* data;
pathNode_struct* nodes;
unsigned char width, height;
openList_struct openList;
vect2D origin, target;
path_struct path;
}pathfindingSystem_struct;
void initPathfindingGlobal(void);
pathCell_struct* getPath(room_struct* r, vect2D origin, vect2D target);
bool popPathCell(path_struct* p, int* x, int* y);
void freePath(path_struct* p);
#endif

View File

@ -0,0 +1,22 @@
#ifndef __PHYSICS9__
#define __PHYSICS9__
#define MAXSTEP 2
#define GRAVITY (inttof32(1)>>7)
#define MARGIN (1)
typedef struct
{
vect3D position, speed;
int32 radius, sqRadius;
}physicsObject_struct;
room_struct* getRoomPoint(vect3D p);
void updatePhysicsObject(physicsObject_struct* o);
void collideObjectRoom(physicsObject_struct* o, room_struct* r);
bool objectInRoom(room_struct* r, physicsObject_struct* o, vect3D* v);
s16 updateSimplePhysicsObjectRoom(room_struct* r, physicsObject_struct* o);
void updatePhysicsObjectRoom(room_struct* r, physicsObject_struct* o, bool both);
vect3D convertCoord(room_struct* r, vect3D p);
#endif

View File

@ -0,0 +1,24 @@
#ifndef __PLAYER9__
#define __PLAYER9__
typedef struct
{
vect3D relativePosition;
vect3D relativePositionReal;
room_struct* currentRoom;
physicsObject_struct* object;
modelInstance_struct modelInstance;
s8 life;
}player_struct;
room_struct* getCurrentRoom(void);
void initPlayer(player_struct* p);
void playerControls(player_struct* p);
void updatePlayer(player_struct* p);
void renderGun(player_struct*);
player_struct* getPlayer(void);
void freePlayer(void);
void drawCrosshair(void);
void damagePlayer(player_struct* p);
#endif

View File

@ -0,0 +1,27 @@
#ifndef __POLYGON9__
#define __POLYGON9__
#define POLYPOOLSIZE 512
typedef struct polygon_struct
{
vect3D v, t;
vect3D dir;
int32 val, dist;
struct polygon_struct* next;
}polygon_struct;
void initPolygonPool(void);
void drawPolygon(polygon_struct* p);
void freePolygon(polygon_struct** p);
polygon_struct* createPolygon(vect3D v);
vect3D projectPoint(camera_struct* c, vect3D p);
polygon_struct* createEllipse(vect3D po, vect3D v1, vect3D v2, int n);
polygon_struct* clipPolygonPlane(plane_struct* pl, polygon_struct* p);
polygon_struct* createQuad(vect3D v1, vect3D v2, vect3D v3, vect3D v4);
polygon_struct* clipPolygonFrustum(frustum_struct* f, polygon_struct* p);
vect3D intersectSegmentPlane(plane_struct* pl, vect3D o, vect3D v, int32 d);
void clipSegmentPlane(plane_struct* pl, polygon_struct** o, polygon_struct* pp1, polygon_struct* pp2);
void projectPolygon(camera_struct* c, polygon_struct** p, vect3D o, vect3D u1, vect3D u2, int32 d1, int32 d2);
#endif

View File

@ -0,0 +1,32 @@
#ifndef __PORTALS9__
#define __PORTALS9__
#define PORTALSIZEX (inttof32(1)/12)
#define PORTALSIZEY (inttof32(1)/6)
typedef struct portal_struct
{
camera_struct camera;
mtlImg_struct* texture;
vect3D position;
u16 viewPoint[256*192];
u16 color;
vect3D normal, plane[2];
int32 angle, oldZ;
polygon_struct *polygon, *unprojectedPolygon;
struct portal_struct* targetPortal;
}portal_struct;
extern portal_struct portal1, portal2;
extern portal_struct* currentPortal;
void initPortals(void);
void updatePortals(void);
void initPortal(portal_struct* p, vect3D pos, vect3D normal, bool color);
void drawPortal(portal_struct* p);
void movePortal(portal_struct* p, vect3D pos, vect3D normal, int32 angle);
void updatePortalCamera(portal_struct* p, camera_struct* c);
void collidePortal(room_struct* r, rectangle_struct* rec, portal_struct* p, vect3D* point);
#endif

Binary file not shown.

Binary file not shown.

BIN
arm9/maxmod_data/door.wav Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
arm9/maxmod_data/scream.wav Normal file

Binary file not shown.

1349
arm9/source/GUI.c Normal file

File diff suppressed because it is too large Load Diff

383
arm9/source/PI9.c Normal file
View File

@ -0,0 +1,383 @@
#include <nds.h>
#include "game/game_main.h"
#define NUMOBBFACES 6
const u8 OBBFaces[NUMOBBFACES][4]={{0,1,2,3},{4,5,6,7},{0,5,4,3},{0,1,6,5},{1,2,7,6},{2,3,4,7}};
OBB_struct objects[NUMOBJECTS];
AAR_struct aaRectangles[NUMAARS];
u8 selectID; //debug
mtlImg_struct* cube;
void initPI9(void)
{
int i;
for(i=0;i<NUMOBJECTS;i++)
{
objects[i].used=false;
objects[i].id=i;
}
for(i=0;i<NUMAARS;i++)
{
aaRectangles[i].used=false;
aaRectangles[i].id=i;
}
selectID=0;
cube=createTexture("companion.pcx","textures");
}
OBB_struct* newBox(void)
{
int i;
for(i=0;i<NUMOBJECTS;i++)
{
if(!objects[i].used)
{
objects[i].used=true;
return &objects[i];
}
}
return NULL;
}
AAR_struct* newAAR(void)
{
int i;
for(i=0;i<NUMAARS;i++)
{
if(!aaRectangles[i].used)
{
aaRectangles[i].used=true;
return &aaRectangles[i];
}
}
return NULL;
}
void startPI(void)
{
fifoSendValue32(FIFO_USER_08,PI_START);
}
void pausePI(void)
{
fifoSendValue32(FIFO_USER_08,PI_PAUSE);
}
void makeGrid(void)
{
fifoSendValue32(FIFO_USER_08,PI_MAKEGRID);
}
void resetPI(void)
{
int i;
for(i=0;i<NUMOBJECTS;i++)objects[i].used=false;
fifoSendValue32(FIFO_USER_08,PI_RESET);
}
void createBox(vect3D size, vect3D pos, int32 mass) //(id;[sizex|sizey][sizez|mass][posx][posy][posz])
{
OBB_struct* o=newBox();
if(!o)return;
o->size=size;
o->position=pos;
o->mass=mass>>3; //reduce precision to improve range
o->transformationMatrix[0]=inttof32(1);o->transformationMatrix[1]=0;o->transformationMatrix[2]=0;
o->transformationMatrix[3]=0;o->transformationMatrix[4]=inttof32(1);o->transformationMatrix[5]=0;
o->transformationMatrix[6]=0;o->transformationMatrix[7]=0;o->transformationMatrix[8]=inttof32(1);
fifoSendValue32(FIFO_USER_08,PI_ADDBOX|((o->id)<<PISIGNALDATA));
fifoSendValue32(FIFO_USER_08,(o->size.x&((1<<16)-1))|((o->size.y&((1<<16)-1))<<16));
fifoSendValue32(FIFO_USER_08,(o->size.z&((1<<16)-1))|((o->mass&((1<<16)-1))<<16));
fifoSendValue32(FIFO_USER_08,(o->position.x));
fifoSendValue32(FIFO_USER_08,(o->position.y));
fifoSendValue32(FIFO_USER_08,(o->position.z));
}
void createAAR(vect3D size, vect3D pos, vect3D normal) //(id;[sizex|sizey][sizez|normal][posx][posy][posz])
{
AAR_struct* a=newAAR();
if(!a)return;
a->size=size;
a->position=pos;
u16 n=((normal.x<0))|((normal.x>0)<<1)
|((normal.y<0)<<2)|((normal.y>0)<<3)
|((normal.z<0)<<4)|((normal.z>0)<<5);
fifoSendValue32(FIFO_USER_08,PI_ADDAAR|((a->id)<<PISIGNALDATA));
fifoSendValue32(FIFO_USER_08,(a->size.x&((1<<16)-1))|((a->size.y&((1<<16)-1))<<16));
fifoSendValue32(FIFO_USER_08,(a->size.z&((1<<16)-1))|((n)<<16));
fifoSendValue32(FIFO_USER_08,(a->position.x));
fifoSendValue32(FIFO_USER_08,(a->position.y));
fifoSendValue32(FIFO_USER_08,(a->position.z));
}
void applyForce(u8 id, vect3D pos, vect3D v) //(id;[posx|posy][posz][vx][vy][vz])
{
if(id>NUMOBJECTS || !objects[id].used)return;
fifoSendValue32(FIFO_USER_08,PI_APPLYFORCE|((id)<<PISIGNALDATA));
fifoSendValue32(FIFO_USER_08,(((s16)pos.x))|(((s16)pos.y)<<16));
fifoSendValue32(FIFO_USER_08,((s16)pos.z));
fifoSendValue32(FIFO_USER_08,(v.x));
fifoSendValue32(FIFO_USER_08,(v.y));
fifoSendValue32(FIFO_USER_08,(v.z));
}
void setVelocity(u8 id, vect3D v) //(id;[vx][vy][vz])
{
if(id>NUMOBJECTS || !objects[id].used)return;
fifoSendValue32(FIFO_USER_08,PI_SETVELOCITY|((id)<<PISIGNALDATA));
fifoSendValue32(FIFO_USER_08,(v.x));
fifoSendValue32(FIFO_USER_08,(v.y));
fifoSendValue32(FIFO_USER_08,(v.z));
}
void updatePlayerPI(player_struct* p) //([vx][vy][vz])
{
if(!p)p=getPlayer();
fifoSendValue32(FIFO_USER_08,PI_UPDATEPLAYER);
fifoSendValue32(FIFO_USER_08,(p->object->position.x));
fifoSendValue32(FIFO_USER_08,(p->object->position.y));
fifoSendValue32(FIFO_USER_08,(p->object->position.z));
}
void updatePortalPI(u8 id, vect3D pos, vect3D normal) //(id;[px][py][pz][n])
{
u16 n=((normal.x<0))|((normal.x>0)<<1)
|((normal.y<0)<<2)|((normal.y>0)<<3)
|((normal.z<0)<<4)|((normal.z>0)<<5);
fifoSendValue32(FIFO_USER_08,PI_UPDATEPORTAL|((id)<<PISIGNALDATA));
fifoSendValue32(FIFO_USER_08,(pos.x*4));
fifoSendValue32(FIFO_USER_08,(pos.y*4));
fifoSendValue32(FIFO_USER_08,(pos.z*4));
fifoSendValue32(FIFO_USER_08,(n));
}
void listenPI9(void)
{
while(fifoCheckValue32(FIFO_USER_01))
{
const int k=fifoGetValue32(FIFO_USER_01);
while(!fifoCheckValue32(FIFO_USER_02));
while(!fifoCheckValue32(FIFO_USER_03));
while(!fifoCheckValue32(FIFO_USER_04));
while(!fifoCheckValue32(FIFO_USER_05));
while(!fifoCheckValue32(FIFO_USER_06));
while(!fifoCheckValue32(FIFO_USER_07));
if(k<NUMOBJECTS)
{
OBB_struct* o=&objects[k];
// o->used=true;
o->position.x=fifoGetValue32(FIFO_USER_02);
o->position.y=fifoGetValue32(FIFO_USER_03);
o->position.z=fifoGetValue32(FIFO_USER_04);
int32 x=fifoGetValue32(FIFO_USER_05);
o->transformationMatrix[0]=(s16)x-4096;
o->transformationMatrix[3]=(s16)(x>>16)-4096;
x=fifoGetValue32(FIFO_USER_06);
o->transformationMatrix[6]=(s16)(x)-4096;
o->transformationMatrix[1]=(s16)(x>>16)-4096;
x=fifoGetValue32(FIFO_USER_07);
o->transformationMatrix[4]=(s16)x-4096;
o->transformationMatrix[7]=(s16)(x>>16)-4096;
const vect3D v1=vect(o->transformationMatrix[0],o->transformationMatrix[3],o->transformationMatrix[6]);
const vect3D v2=vect(o->transformationMatrix[1],o->transformationMatrix[4],o->transformationMatrix[7]);
const vect3D v=normalize(vectProduct(v1,v2));
NOGBA("0 : %d %d %d",v1.x,v1.y,v1.z);
NOGBA("1 : %d %d %d",v2.x,v2.y,v2.z);
NOGBA("2 : %d %d %d",v.x,v.y,v.z);
NOGBA("4 : %d %d %d",warpVector(&portal1,v1));
o->transformationMatrix[2]=v.x;
o->transformationMatrix[5]=v.y;
o->transformationMatrix[8]=v.z;
}
}
if(fifoCheckValue32(FIFO_USER_08))
{
NOGBA("fifo 8 : %d",fifoGetValue32(FIFO_USER_08));
}
}
//DEBUG stuff
#define NUMOBBSEGMENTS (12)
const u8 OBBSegments[NUMOBBSEGMENTS][2]={{0,1},{1,2},{3,2},{0,3},
{5,4},{5,6},{6,7},{4,7},
{3,4},{0,5},{1,6},{2,7}};
void getOBBVertices(OBB_struct* o, vect3D* v)
{
if(!o || !v)return;
int32 m2[9];
// int32* m=o->transformationMatrix;
// m2[0]=mulf32(m[0],o->size.x);m2[3]=mulf32(m[3],o->size.x);m2[6]=mulf32(m[6],o->size.x);
// m2[1]=mulf32(m[1],o->size.y);m2[4]=mulf32(m[4],o->size.y);m2[7]=mulf32(m[7],o->size.y);
// m2[2]=mulf32(m[2],o->size.z);m2[5]=mulf32(m[5],o->size.z);m2[8]=mulf32(m[8],o->size.z);
int32* m=o->transformationMatrix;
m2[0]=o->size.x;m2[3]=0;m2[6]=0;
m2[1]=0;m2[4]=o->size.y;m2[7]=0;
m2[2]=0;m2[5]=0;m2[8]=o->size.z;
v[0]=vect(-m2[0]-m2[1]-m2[2],-m2[3]-m2[4]-m2[5],-m2[6]-m2[7]-m2[8]);
v[1]=vect(m2[0]-m2[1]-m2[2],m2[3]-m2[4]-m2[5],m2[6]-m2[7]-m2[8]);
v[2]=vect(m2[0]-m2[1]+m2[2],m2[3]-m2[4]+m2[5],m2[6]-m2[7]+m2[8]);
v[3]=vect(-m2[0]-m2[1]+m2[2],-m2[3]-m2[4]+m2[5],-m2[6]-m2[7]+m2[8]);
v[4]=vect(-v[1].x,-v[1].y,-v[1].z);
v[5]=vect(-v[2].x,-v[2].y,-v[2].z);
v[6]=vect(-v[3].x,-v[3].y,-v[3].z);
v[7]=vect(-v[0].x,-v[0].y,-v[0].z);
// int i;
// for(i=0;i<8;i++)
// {
// v[i]=addVect(v[i],o->position);
// }
}
void multTMatrix(int32* m)
{
if(!m)return;
MATRIX_MULT3x3=m[0];
MATRIX_MULT3x3=m[3];
MATRIX_MULT3x3=m[6];
MATRIX_MULT3x3=m[1];
MATRIX_MULT3x3=m[4];
MATRIX_MULT3x3=m[7];
MATRIX_MULT3x3=m[2];
MATRIX_MULT3x3=m[5];
MATRIX_MULT3x3=m[8];
}
void drawOBB(OBB_struct* o)
{
if(!o)return;
if(!o->used)return;
vect3D v[8];
getOBBVertices(o,v);
glPolyFmt(POLY_ALPHA(31) | POLY_CULL_NONE);
applyMTL(cube);
glPushMatrix();
glTranslatef32(o->position.x,o->position.y,o->position.z);
multTMatrix(o->transformationMatrix);
if(selectID==o->id)GFX_COLOR=RGB15(31,0,0);
else GFX_COLOR=RGB15(31,31,31);
GFX_COLOR=RGB15(31,31,31);
int i;
glBegin(GL_QUADS);
for(i=0;i<NUMOBBFACES;i++)
{
GFX_TEX_COORD=TEXTURE_PACK(0, 0);
glVertex3v16((v[OBBFaces[i][0]].x),(v[OBBFaces[i][0]].y),(v[OBBFaces[i][0]].z));
GFX_TEX_COORD=TEXTURE_PACK(inttot16(64), 0);
glVertex3v16((v[OBBFaces[i][1]].x),(v[OBBFaces[i][1]].y),(v[OBBFaces[i][1]].z));
GFX_TEX_COORD=TEXTURE_PACK(inttot16(64), inttot16(64));
glVertex3v16((v[OBBFaces[i][2]].x),(v[OBBFaces[i][2]].y),(v[OBBFaces[i][2]].z));
GFX_TEX_COORD=TEXTURE_PACK(0, inttot16(64));
glVertex3v16((v[OBBFaces[i][3]].x),(v[OBBFaces[i][3]].y),(v[OBBFaces[i][3]].z));
}
// glBegin(GL_TRIANGLES);
// for(i=0;i<NUMOBBSEGMENTS;i++)
// {
// glVertex3v16((v[OBBSegments[i][0]].x),(v[OBBSegments[i][0]].y),(v[OBBSegments[i][0]].z));
// glVertex3v16((v[OBBSegments[i][1]].x),(v[OBBSegments[i][1]].y),(v[OBBSegments[i][1]].z));
// glVertex3v16((v[OBBSegments[i][1]].x),(v[OBBSegments[i][1]].y),(v[OBBSegments[i][1]].z));
// }
// glEnd();
glPopMatrix(1);
}
void drawOBBs(void)
{
int i;
for(i=0;i<NUMOBJECTS;i++)
{
if(objects[i].used)
{
drawOBB(&objects[i]);
}
}
}
void drawAAR(AAR_struct* a)
{
if(!a)return;
if(!a->used)return;
glPolyFmt(POLY_ALPHA(31) | POLY_CULL_NONE);
glPushMatrix();
GFX_COLOR=RGB15(0,0,31);
if(!a->size.x)
{
glBegin(GL_QUADS);
glVertex3v16((a->position.x),(a->position.y),(a->position.z));
GFX_COLOR=RGB15(31,0,31);
glVertex3v16((a->position.x),(a->position.y+a->size.y),(a->position.z));
GFX_COLOR=RGB15(31,0,0);
glVertex3v16((a->position.x),(a->position.y+a->size.y),(a->position.z+a->size.z));
GFX_COLOR=RGB15(31,31,0);
glVertex3v16((a->position.x),(a->position.y),(a->position.z+a->size.z));
glEnd();
}else if(!a->size.y)
{
glBegin(GL_QUADS);
glVertex3v16((a->position.x),(a->position.y),(a->position.z));
GFX_COLOR=RGB15(31,0,31);
glVertex3v16((a->position.x+a->size.x),(a->position.y),(a->position.z));
GFX_COLOR=RGB15(31,0,0);
glVertex3v16((a->position.x+a->size.x),(a->position.y),(a->position.z+a->size.z));
GFX_COLOR=RGB15(31,31,0);
glVertex3v16((a->position.x),(a->position.y),(a->position.z+a->size.z));
glEnd();
}else{
glBegin(GL_QUADS);
glVertex3v16((a->position.x),(a->position.y),(a->position.z));
GFX_COLOR=RGB15(31,0,31);
glVertex3v16((a->position.x+a->size.x),(a->position.y),(a->position.z));
GFX_COLOR=RGB15(31,0,0);
glVertex3v16((a->position.x+a->size.x),(a->position.y+a->size.y),(a->position.z));
GFX_COLOR=RGB15(31,31,0);
glVertex3v16((a->position.x),(a->position.y+a->size.y),(a->position.z));
glEnd();
}
glPopMatrix(1);
}
void drawAARs(void)
{
int i;
for(i=0;i<NUMAARS;i++)
{
if(aaRectangles[i].used)
{
drawAAR(&aaRectangles[i]);
}
}
}

View File

@ -0,0 +1,167 @@
#include "acotmenu/acotmenu_main.h"
#define NUMFRAMES 16
#define TOTALFRAMES 130
#define EMAILPERIOD 30
#define BUTTONLENGTH 30
struct gl_texture_t* videoFrames[NUMFRAMES];
struct gl_texture_t* bottom1;
struct gl_texture_t* bottom2;
struct gl_texture_t* message[3];
u16 messagePalette[256];
int emailCounter=0;
int currentFrame=0;
int bg3;
int bg3Sub, bg2Sub;
void copyImage(u16* dest, int h)
{
int offset=0;
if(h<256)
{
int size=max(min((256-h)*256,192*256),0);
memcpy(dest,&message[0]->texels[h*256],size);
offset+=size;
size=max((h+192-256)*256,0);
memcpy(&dest[offset/2],message[1]->texels,size);
offset+=size;
}else{
int size=max(min((512-h)*256,192*256),0);
memcpy(dest,&message[1]->texels[(h-256)*256],size);
offset+=size;
size=min(max((h+192-512)*256,0),192*256);
memcpy(&dest[offset/2],&message[2]->texels[max((h-512)*256,0)],size);
offset+=size;
}
}
int messageHeight=0;
int state=0;
void initACOTMenu(void)
{
NOGBA("mem free : %dko (%do)",getMemFree()/1024,getMemFree());
int i;
for(i=0;i<NUMFRAMES;i++)
{
char str[255];
sprintf(str,"video200%d.pcx",22+i*2);
NOGBA("str : %s",str);
videoFrames[i]=(struct gl_texture_t *)ReadPCXFile(str,"menu");
NOGBA("free : %dko",getMemFree()/1024);
}
bottom1=(struct gl_texture_t *)ReadPCXFile("bottom1.pcx","menu");
bottom2=(struct gl_texture_t *)ReadPCXFile("bottom2.pcx","menu");
message[0]=(struct gl_texture_t *)ReadPCXFile("message1.pcx","menu");
message[1]=(struct gl_texture_t *)ReadPCXFile("message2.pcx","menu");
message[2]=(struct gl_texture_t *)ReadPCXFile("message3.pcx","menu");
videoSetMode(MODE_5_2D);
videoSetModeSub(MODE_5_2D);
vramSetBankA(VRAM_A_MAIN_BG_0x06000000);
vramSetBankC(VRAM_C_SUB_BG);
bg3 = bgInit(3, BgType_Bmp8, BgSize_B8_256x256, 0,0);
bg3Sub = bgInitSub(3, BgType_Bmp8, BgSize_B8_256x256, 0,0);
bg2Sub = bgInitSub(2, BgType_Bmp8, BgSize_B8_256x256, 3,0);
dmaCopy(videoFrames[0]->texels, bgGetGfxPtr(bg3), 256*192);
dmaCopy(videoFrames[0]->palette, BG_PALETTE, 256*2);
dmaCopy(bottom1->texels, bgGetGfxPtr(bg3Sub), 256*192);
dmaCopy(bottom1->palette, BG_PALETTE_SUB, 256*2);
currentFrame=0;
emailCounter=0;
messageHeight=0;
state=0;
NOGBA("START mem free : %dko (%do)",getMemFree()/1024,getMemFree());
fadeIn();
}
touchPosition oldTouchPos;
void ACOTMenuFrame(void)
{
touchPosition touchPos;
touchRead(&touchPos);
scanKeys();
int realFrame=currentFrame;
if(currentFrame>=NUMFRAMES)realFrame=13+(currentFrame%2);
dmaCopy(videoFrames[realFrame]->texels, bgGetGfxPtr(bg3), 256*192);
dmaCopy(videoFrames[realFrame]->palette, BG_PALETTE, 256*2);
currentFrame++;
if(currentFrame>=TOTALFRAMES)currentFrame=0;
emailCounter++;
if(emailCounter>=EMAILPERIOD){if(emailCounter>=EMAILPERIOD+BUTTONLENGTH)emailCounter=0;BG_PALETTE_SUB[1]=RGB15(31,22,0);}
else BG_PALETTE_SUB[1]=RGB15(31,31,31);
if(keysDown()&(KEY_SELECT))changeState(&ACOTMenuState);
switch(state)
{
case 0:
if(oldTouchPos.px>23&&oldTouchPos.py>140&&oldTouchPos.px<240&&oldTouchPos.py<155)
{
if((keysHeld()&KEY_TOUCH))
{
BG_PALETTE_SUB[1]=RGB15(31,22,0);
emailCounter=0;
}else if(keysUp()&KEY_TOUCH)
{
emailCounter=0;
dmaCopy(bottom2->texels, bgGetGfxPtr(bg2Sub), 256*192);
dmaCopy(bottom2->palette, BG_PALETTE_SUB, 256*2);
state++;
}
}
break;
default:
if(oldTouchPos.px>50&&oldTouchPos.py>144&&oldTouchPos.px<222&&oldTouchPos.py<155)
{
if((keysHeld()&KEY_TOUCH))
{
BG_PALETTE_SUB[1]=RGB15(31,22,0);
emailCounter=0;
}else if(keysUp()&KEY_TOUCH)
{
//START GAME HERE
changeState(&gameState);
}
}else if((keysHeld()&KEY_TOUCH)&&!(keysDown()&KEY_TOUCH))messageHeight-=touchPos.py-oldTouchPos.py;
if(messageHeight<0)messageHeight=0;
if(messageHeight>=768-192)messageHeight=768-193;
copyImage(bgGetGfxPtr(bg3Sub), messageHeight);
break;
}
swiWaitForVBlank();
swiWaitForVBlank();
oldTouchPos=touchPos;
}
void killACOTMenu(void)
{
fadeOut();
int i;
for(i=0;i<NUMFRAMES;i++)
{
freePCX(videoFrames[i]);
}
freePCX(bottom1);
freePCX(bottom2);
freePCX(message[0]);
freePCX(message[1]);
freePCX(message[2]);
NOGBA("END mem free : %dko (%do)",getMemFree()/1024,getMemFree());
}
void ACOTMenuVBL(void)
{
}

21
arm9/source/audio.c Normal file
View File

@ -0,0 +1,21 @@
#include "common/general.h"
// mm_sound_effect bossdies,clickbttn,enemyDead,enemyScream,gunShot,playerHit,scream;
void initAudio(void)
{
// mmInitDefaultMem((mm_addr)soundbank_bin);
// loadSoundEffects();
}
void loadSoundEffects(void)
{
// mmLoadEffect( SFX_BOSSDIES );
// mmLoadEffect( SFX_CLICKBTTN );
// mmLoadEffect( SFX_ENEMY1DEAD );
// mmLoadEffect( SFX_ENEMYSCREAM1 );
// mmLoadEffect( SFX_GUNSHOT );
// mmLoadEffect( SFX_DOOR );
// mmLoadEffect( SFX_PLAYERHIT );
// mmLoadEffect( SFX_SCREAM );
}

25
arm9/source/debug.c Normal file
View File

@ -0,0 +1,25 @@
#include "common/general.h"
void DS_Debug(char* string, ...)
{
//va_list varg;
//NOGBA(string);
// iprintf(string);
}
void DS_DebugPause(void)
{
DS_Debug("\n..Touch the screen to continue..\n");
scanKeys();
while(!(keysDown() & KEY_TOUCH))scanKeys();
}
size_t DS_UsedMem(void)
{
return getMemUsed();
}
size_t DS_FreeMem(void)
{
return getMemFree();
}

View File

@ -0,0 +1,85 @@
@ ------------------------------------------------------------------------------
@
@ This function can be used to output No$gba debug messages.
@
@ Author: Peter Schraut (www.console-dev.de)
@ Date..: 2005-Jan-20
@
@ extern "C" int N3DNoCashMsg(const char *pText);
@
@ ------------------------------------------------------------------------------
@
@ Copyright 2005-2007 by Peter Schraut www.console-dev.de
@
@ This file is distributed as freeware.
@
@ You are free to use it as part of your program for any purpose including
@ freeware, shareware and commercial programs.
@
@ The origin of this software must not be misrepresented; you must not claim your
@ authorship. All redistributions must retain the original copyright notice and web
@ site addresses.
@
@ Commercial redistribution of this file is allowed only with an explicit written
@ permission from the author.
@
@ This software is provided 'as-is', without warranty of any kind, either expressed or
@ implied. In no event shall the author be held liable for any damages arising from the
@ use of this software.
@
@ ------------------------------------------------------------------------------
@.section .iwram,"ax",%progbits
.arm
.align 4
.global N3DNoCashMsg
.type N3DNoCashMsg, %function
@ r0 = Text
@ r1 = Address of target buffer
@ r2 = Maximum amount of characters, descrements each iteration
@ r3 = Current char of text
.equiv BUFFER_SIZE, 120
N3DNoCashMsg:
stmfd sp!, {r1-r3}
adr r1, .Buffer @ Get target buffer address
mov r2, #BUFFER_SIZE @ Maximum amount of supported characters
@ This loop copies the incoming data into the
@ Buffer below. If it encounters a NULL-terminator
@ or is beyond the 120th character, it will break.
.Loop:
ldrb r3, [r0], #1 @ Load current byte from text
strb r3, [r1], #1 @ Store currrent byte into Buffer
subs r2, r2, #1 @ One further byte added
cmpne r3, #0 @ Came across a NULL-terminator?
beq .MsgTag @ Last Char or NULL-terminator? Then branch to MsgTag
b .Loop @ Just loop
@ Here starts the actual no$gba Message Tag
.MsgTag:
mov r12, r12 @ First no$gba ID
b .Continue
.short 0x6464 @ Second no$gba ID
.short 0 @ Reserved for flags
.Buffer:
.space BUFFER_SIZE @ 120 bytes for the message
.byte 0 @ Trailing zero as NULL-Terminator
.align 4
.Continue:
ldr r0, =(BUFFER_SIZE-1) @ Return length of Text without NULL-terminator
sub r0, r0, r2
ldmfd sp!, {r1-r3}
bx lr
.align 4
.size N3DNoCashMsg, .-N3DNoCashMsg

37
arm9/source/debug/xmem.c Normal file
View File

@ -0,0 +1,37 @@
/*
* xmem.c
* part of the xlibrary by SunDEV (http://sundev.890m.com)
*
* Changelog :
* 21-03-09 : First public release
*
*/
#include "common/general.h"
extern u8 __end__[]; // end of static code and data
extern u8 __eheap_end[]; // farthest point to which the heap will grow
u8 *getHeapStart() {
return __end__;
}
u8 *getHeapEnd() {
return (u8 *)sbrk(0);
}
u8 *getHeapLimit() {
return __eheap_end;
}
size_t getMemUsed() {
struct mallinfo mi = mallinfo();
latestUsed=mi.uordblks;
return latestUsed;
}
size_t getMemFree() {
struct mallinfo mi = mallinfo();
latestFree=mi.fordblks + (getHeapLimit() - getHeapEnd());
return latestFree;
}

365
arm9/source/dictionary.c Normal file
View File

@ -0,0 +1,365 @@
/*-------------------------------------------------------------------------*/
/**
@file dictionary.c
@author N. Devillard
@date Sep 2007
@version $Revision: 1.27 $
@brief Implements a dictionary for string variables.
This module implements a simple dictionary object, i.e. a list
of string/string associations. This object is useful to store e.g.
informations retrieved from a configuration file (ini files).
*/
/*--------------------------------------------------------------------------*/
/*
$Id: dictionary.c,v 1.27 2007-11-23 21:39:18 ndevilla Exp $
$Revision: 1.27 $
*/
/*---------------------------------------------------------------------------
Includes
---------------------------------------------------------------------------*/
#include "common/general.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
/** Maximum value size for integers and doubles. */
#define MAXVALSZ 1024
/** Minimal allocated number of entries in a dictionary */
#define DICTMINSZ 256
/** Invalid key token */
#define DICT_INVALID_KEY ((char*)-1)
/*---------------------------------------------------------------------------
Private functions
---------------------------------------------------------------------------*/
/* Doubles the allocated size associated to a pointer */
/* 'size' is the current allocated size. */
static void * mem_double(void * ptr, int size)
{
void * newptr ;
newptr = calloc(2*size, 1);
if (newptr==NULL) {
return NULL ;
}
memcpy(newptr, ptr, size);
free(ptr);
return newptr ;
}
/*-------------------------------------------------------------------------*/
/**
@brief Duplicate a string
@param s String to duplicate
@return Pointer to a newly allocated string, to be freed with free()
This is a replacement for strdup(). This implementation is provided
for systems that do not have it.
*/
/*--------------------------------------------------------------------------*/
static char * xstrdup(char * s)
{
char * t ;
if (!s)
return NULL ;
t = (char*)malloc(strlen(s)+1) ;
if (t) {
strcpy(t,s);
}
return t ;
}
/*---------------------------------------------------------------------------
Function codes
---------------------------------------------------------------------------*/
/*-------------------------------------------------------------------------*/
/**
@brief Compute the hash key for a string.
@param key Character string to use for key.
@return 1 unsigned int on at least 32 bits.
This hash function has been taken from an Article in Dr Dobbs Journal.
This is normally a collision-free function, distributing keys evenly.
The key is stored anyway in the struct so that collision can be avoided
by comparing the key itself in last resort.
*/
/*--------------------------------------------------------------------------*/
unsigned dictionary_hash(char * key)
{
int len ;
unsigned hash ;
int i ;
len = strlen(key);
for (hash=0, i=0 ; i<len ; i++) {
hash += (unsigned)key[i] ;
hash += (hash<<10);
hash ^= (hash>>6) ;
}
hash += (hash <<3);
hash ^= (hash >>11);
hash += (hash <<15);
return hash ;
}
/*-------------------------------------------------------------------------*/
/**
@brief Create a new dictionary object.
@param size Optional initial size of the dictionary.
@return 1 newly allocated dictionary objet.
This function allocates a new dictionary object of given size and returns
it. If you do not know in advance (roughly) the number of entries in the
dictionary, give size=0.
*/
/*--------------------------------------------------------------------------*/
dictionary * dictionary_new(int size)
{
dictionary * d ;
/* If no size was specified, allocate space for DICTMINSZ */
if (size<DICTMINSZ) size=DICTMINSZ ;
if (!(d = (dictionary *)calloc(1, sizeof(dictionary)))) {
return NULL;
}
d->size = size ;
d->val = (char **)calloc(size, sizeof(char*));
d->key = (char **)calloc(size, sizeof(char*));
d->hash = (unsigned int *)calloc(size, sizeof(unsigned));
return d ;
}
/*-------------------------------------------------------------------------*/
/**
@brief Delete a dictionary object
@param d dictionary object to deallocate.
@return void
Deallocate a dictionary object and all memory associated to it.
*/
/*--------------------------------------------------------------------------*/
void dictionary_del(dictionary * d)
{
int i ;
if (d==NULL) return ;
for (i=0 ; i<d->size ; i++) {
if (d->key[i]!=NULL)
free(d->key[i]);
if (d->val[i]!=NULL)
free(d->val[i]);
}
free(d->val);
free(d->key);
free(d->hash);
free(d);
return ;
}
/*-------------------------------------------------------------------------*/
/**
@brief Get a value from a dictionary.
@param d dictionary object to search.
@param key Key to look for in the dictionary.
@param def Default value to return if key not found.
@return 1 pointer to internally allocated character string.
This function locates a key in a dictionary and returns a pointer to its
value, or the passed 'def' pointer if no such key can be found in
dictionary. The returned character pointer points to data internal to the
dictionary object, you should not try to free it or modify it.
*/
/*--------------------------------------------------------------------------*/
char * dictionary_get(dictionary * d, char * key, char * def)
{
unsigned hash ;
int i ;
if(d==NULL)return def;
hash = dictionary_hash(key);
for (i=0 ; i<d->size ; i++) {
if (d->key[i]==NULL)
continue ;
/* Compare hash */
if (hash==d->hash[i]) {
/* Compare string, to avoid hash collisions */
if (!strcmp(key, d->key[i])) {
return d->val[i] ;
}
}
}
return def ;
}
/*-------------------------------------------------------------------------*/
/**
@brief Set a value in a dictionary.
@param d dictionary object to modify.
@param key Key to modify or add.
@param val Value to add.
@return int 0 if Ok, anything else otherwise
If the given key is found in the dictionary, the associated value is
replaced by the provided one. If the key cannot be found in the
dictionary, it is added to it.
It is Ok to provide a NULL value for val, but NULL values for the dictionary
or the key are considered as errors: the function will return immediately
in such a case.
Notice that if you dictionary_set a variable to NULL, a call to
dictionary_get will return a NULL value: the variable will be found, and
its value (NULL) is returned. In other words, setting the variable
content to NULL is equivalent to deleting the variable from the
dictionary. It is not possible (in this implementation) to have a key in
the dictionary without value.
This function returns non-zero in case of failure.
*/
/*--------------------------------------------------------------------------*/
int dictionary_set(dictionary * d, char * key, char * val)
{
int i ;
unsigned hash ;
if (d==NULL || key==NULL) return -1 ;
/* Compute hash for this key */
hash = dictionary_hash(key) ;
/* Find if value is already in dictionary */
if (d->n>0) {
for (i=0 ; i<d->size ; i++) {
if (d->key[i]==NULL)
continue ;
if (hash==d->hash[i]) { /* Same hash value */
if (!strcmp(key, d->key[i])) { /* Same key */
/* Found a value: modify and return */
if (d->val[i]!=NULL)
free(d->val[i]);
d->val[i] = val ? xstrdup(val) : NULL ;
/* Value has been modified: return */
return 0 ;
}
}
}
}
/* Add a new value */
/* See if dictionary needs to grow */
if (d->n==d->size) {
/* Reached maximum size: reallocate dictionary */
d->val = (char **)mem_double(d->val, d->size * sizeof(char*)) ;
d->key = (char **)mem_double(d->key, d->size * sizeof(char*)) ;
d->hash = (unsigned int *)mem_double(d->hash, d->size * sizeof(unsigned)) ;
if ((d->val==NULL) || (d->key==NULL) || (d->hash==NULL)) {
/* Cannot grow dictionary */
return -1 ;
}
/* Double size */
d->size *= 2 ;
}
/* Insert key in the first empty slot */
for (i=0 ; i<d->size ; i++) {
if (d->key[i]==NULL) {
/* Add key here */
break ;
}
}
/* Copy key */
d->key[i] = xstrdup(key);
d->val[i] = val ? xstrdup(val) : NULL ;
d->hash[i] = hash;
d->n ++ ;
return 0 ;
}
/*-------------------------------------------------------------------------*/
/**
@brief Delete a key in a dictionary
@param d dictionary object to modify.
@param key Key to remove.
@return void
This function deletes a key in a dictionary. Nothing is done if the
key cannot be found.
*/
/*--------------------------------------------------------------------------*/
void dictionary_unset(dictionary * d, char * key)
{
unsigned hash ;
int i ;
if (key == NULL) {
return;
}
hash = dictionary_hash(key);
for (i=0 ; i<d->size ; i++) {
if (d->key[i]==NULL)
continue ;
/* Compare hash */
if (hash==d->hash[i]) {
/* Compare string, to avoid hash collisions */
if (!strcmp(key, d->key[i])) {
/* Found key */
break ;
}
}
}
if (i>=d->size)
/* Key not found */
return ;
free(d->key[i]);
d->key[i] = NULL ;
if (d->val[i]!=NULL) {
free(d->val[i]);
d->val[i] = NULL ;
}
d->hash[i] = 0 ;
d->n -- ;
return ;
}
/*-------------------------------------------------------------------------*/
/**
@brief Dump a dictionary to an opened file pointer.
@param d Dictionary to dump
@param f Opened file pointer.
@return void
Dumps a dictionary onto an opened file pointer. Key pairs are printed out
as @c [Key]=[Value], one per line. It is Ok to provide stdout or stderr as
output file pointers.
*/
/*--------------------------------------------------------------------------*/
void dictionary_dump(dictionary * d, FILE * out)
{
int i ;
if (d==NULL || out==NULL) return ;
if (d->n<1) {
fprintf(out, "empty dictionary\n");
return ;
}
for (i=0 ; i<d->size ; i++) {
if (d->key[i]) {
fprintf(out, "%20s\t[%s]\n",
d->key[i],
d->val[i] ? d->val[i] : "UNDEF");
}
}
return ;
}
/* vim: set ts=4 et sw=4 tw=75 */

98
arm9/source/dual3D.c Normal file
View File

@ -0,0 +1,98 @@
#include "common/general.h"
SpriteEntry d3dSprites[128];
bool d3dScreen;
pSpriteRotation d3dSpriteRotations = (pSpriteRotation)d3dSprites;
void initSprites(void)
{
int i;
for(i = 0; i < 128; i++)
{
d3dSprites[i].attribute[0] = ATTR0_DISABLED;
d3dSprites[i].attribute[1] = 0;
d3dSprites[i].attribute[2] = 0;
}
}
void updateOAM(void)
{
DC_FlushRange(d3dSprites, 128 * sizeof(SpriteEntry));
memcpy(OAM_SUB, d3dSprites, 128 * sizeof(SpriteEntry));
}
void initD3D()
{
int x,y,i;
videoSetMode(MODE_3_3D);
videoSetModeSub(MODE_5_2D | DISPLAY_BG2_ACTIVE | DISPLAY_SPR_ACTIVE | DISPLAY_SPR_2D_BMP_256);
vramSetPrimaryBanks(VRAM_A_TEXTURE,VRAM_B_TEXTURE,VRAM_C_SUB_BG,VRAM_D_SUB_SPRITE);
REG_BG0CNT = BG_PRIORITY(1);
REG_BG2CNT_SUB = BG_BMP16_256x256 | BG_BMP_BASE(0) | BG_PRIORITY(1);
REG_BG2PA_SUB = 1 << 8;
REG_BG2PB_SUB = 0;
REG_BG2PC_SUB = 0;
REG_BG2PD_SUB = 1 << 8;
REG_BG2X_SUB = 0;
REG_BG2Y_SUB = 0;
initSprites();
d3dSpriteRotations[0].hdx=256;
d3dSpriteRotations[0].hdy=0;
d3dSpriteRotations[0].vdx=0;
d3dSpriteRotations[0].vdy=256;
i=0;
for (y = 0; y < 3; y++)
{
for (x = 0; x < 4; x++) {
d3dSprites[i].attribute[0] = ATTR0_BMP | ATTR0_SQUARE | (64 * y);
d3dSprites[i].attribute[1] = ATTR1_SIZE_64 | (64 * x);
d3dSprites[i].attribute[2] = ATTR2_ALPHA(1) | (8 * 32 * y) | (8 * x);
i++;
}
}
updateOAM();
d3dScreen=true;
}
void setRegCapture(bool enable, uint8 srcBlend, uint8 destBlend, uint8 bank, uint8 offset, uint8 size, uint8 source, uint8 srcOffset)
{
uint32 value=0;
if(enable)value|=1 << 31; // 31 is enable
value|=0 << 29; // 29-30 seems to have something to do with the blending
value|=(srcOffset & 0x3) << 26; // capture source offset is 26-27
value|=(source & 0x3) << 24; // capture source is 24-25
value|=(size & 0x3) << 20; // capture data write size is 20-21
value|=(offset & 0x3) << 18; // write offset is 18-19
value|=(bank & 0x3) << 16; // vram bank select is 16-17
value|=(srcBlend & 0xF) << 8; // graphics blend evb is 8..12
value|=(destBlend & 0xF) << 0; // ram blend EVA is bits 0..4
REG_DISPCAPCNT=value;
}
void updateD3D()
{
if (d3dScreen) {
vramSetBankC(VRAM_C_SUB_BG);
vramSetBankD(VRAM_D_LCD);
setRegCapture(true, 0, 15, 3, 0, 3, 0, 0);
d3dScreen=false;
}else{
vramSetBankC(VRAM_C_LCD);
vramSetBankD(VRAM_D_SUB_SPRITE);
setRegCapture(true, 0, 15, 2, 0, 3, 0, 0);
d3dScreen=true;
}
lcdSwap();
}

720
arm9/source/editor/editor.c Normal file
View File

@ -0,0 +1,720 @@
#include "editor/editor_main.h"
#include <dirent.h>
#define TOOLBUTTONS 9
#define ACTIONBUTTONS 16
#define MAXLISTBUTTONS 8
extern char* basePath;
typedef struct
{
vect2D size;
guiEntity_struct* window;
guiEntity_struct* label;
guiEntity_struct* slider;
guiEntity_struct* button[MAXLISTBUTTONS];
guiFunction function;
char** nameList;
u16 numElements;
u8 numButtons;
u16 cursor;
}listWindow_struct;
listWindow_struct listWindow;
guiEntity_struct* newLevelWindow;
guiEntity_struct* fileToolWindow;
guiEntity_struct* roomToolWindow;
guiEntity_struct* selectedRoomToolWindow;
guiEntity_struct* entityToolWindow;
guiEntity_struct* entityPropertyWindow;
guiEntity_struct* tileToolWindow;
guiEntity_struct* materialToolWindow;
guiEntity_struct* materialWindowLabel;
guiEntity_struct* toolButtons[TOOLBUTTONS];
guiEntity_struct* actionButtons[ACTIONBUTTONS];
extern roomEdit_struct *selectedRoom;
extern roomEdit_struct *oldSelectedRoom;
extern entity_struct *currentEntity;
extern u8 roomEditorMode;
int* correspondanceList=NULL;
int selectedMaterial=0;
void updateListWindowButtons(listWindow_struct* lw);
void listWindowSlider(guiEntity_struct* e)
{
listWindow_struct* lw=NULL;
if(!lw)lw=&listWindow;
guiSliderData_struct* d=(guiSliderData_struct*)e->data;
lw->cursor=(d->position*(lw->numElements-lw->numButtons))/d->size;
if(d->position!=d->oldpos)updateListWindowButtons(lw);
}
int getListWindowButtonPosition(listWindow_struct* lw, char* text)
{
if(!lw)lw=&listWindow;
int w=strlen(text)*8;
return (lw->size.x-w)/2;
}
void initListWindow(listWindow_struct* lw)
{
if(!lw)lw=&listWindow;
int i;
lw->size=vect2(180,120);
lw->window=createWindow(200,8,lw->size.x,lw->size.y,31,RGB15(31,31,31),1,RGB15(0,0,0),"");
lw->window->prio=512;
lw->label=createLabelFather(60, 6, RGB15(31,31,31), lw->window, "filler", false);
lw->slider=createVSliderFather(lw->size.x-20, 10, 100, listWindowSlider, lw->window, "", false);
for(i=0;i<MAXLISTBUTTONS;i++)
{
lw->button[i]=createButtonFather(3, 20+20*i, RGB15(31,31,31), NULL, lw->window, "filler", "", false);
lw->button[i]->outline=1;
}
lw->nameList=NULL;
lw->numElements=0;
lw->cursor=0;
lw->numButtons=MAXLISTBUTTONS;
}
void openListWindow(listWindow_struct* lw, char* t, char** nl, u16 ne, u8 nb, guiFunction f)
{
if(!lw)lw=&listWindow;
lw->cursor=0;
updateLabelText(lw->label,t);
setPositionX(lw->label,getListWindowButtonPosition(lw,t));
lw->function=f;
lw->nameList=nl;
lw->numButtons=nb;
lw->numElements=ne;
setPositionX(lw->window,-lw->size.x/2);
lw->size.y=20+20*lw->numButtons;
setSizeA(lw->window,lw->size.x,lw->size.y);
if(lw->numElements<lw->numButtons)lw->numButtons=lw->numElements;
updateListWindowButtons(lw);
}
void closeListWindow(listWindow_struct* lw)
{
if(!lw)lw=&listWindow;
setPositionX(lw->window,200);
}
void updateListWindowButtons(listWindow_struct* lw)
{
if(!lw)lw=&listWindow;
if(lw->cursor+lw->numButtons>lw->numElements)lw->cursor=lw->numElements-lw->numButtons;
if(lw->cursor<0)lw->cursor=0;
int i;
for(i=0;i<lw->numButtons;i++)
{
updateButtonText(lw->button[i],lw->nameList[lw->cursor+i]);
((guiButtonData_struct*)(lw->button[i]->data))->function=lw->function;
setPositionX(lw->button[i],getListWindowButtonPosition(lw,lw->nameList[lw->cursor+i]));
}
for(;i<MAXLISTBUTTONS;i++)setPositionX(lw->button[i],300);
}
char** listFiles(char* directory, int *k)
{
DIR *dir;
NOGBA("%s ?", directory);
struct dirent *ent;
dir=opendir(directory);
int n=0;
if(dir)
{
while((ent=readdir(dir)))if(ent->d_name[0]!='.')n++;
closedir(dir);
}else return NULL;
NOGBA("%d",n);
NOGBA("1");
u8* strLengths=malloc(n);
if(!strLengths)return NULL;
n=0;
dir=opendir(directory);
if(dir)
{
while((ent=readdir(dir)))
{
if(ent->d_name[0]!='.')
{
strLengths[n]=strlen(ent->d_name);
n++;
}
}
closedir(dir);
}else {free(strLengths);return NULL;}
NOGBA("%d",n);
NOGBA("1");
int i;
char** list=malloc(sizeof(char*)*(n+1));
if(!list){free(strLengths);return NULL;}
for(i=0;i<n;i++){list[i]=malloc(strLengths[i]+1);}
free(strLengths);
n=0;
dir=opendir(directory);
if(dir)
{
while((ent=readdir(dir)))
{
if(ent->d_name[0]!='.')
{
strcpy(list[n],ent->d_name);
NOGBA("%s",list[n]);
n++;
}
}
closedir(dir);
}else {free(list);return NULL;}
NOGBA("%d",n);
*k=n;
list[n]=NULL;
return list;
}
void freeLevelList(char** l)
{
char** ll=l;
while(*ll){free(*(ll));ll++;}
free(l);
}
void callNewLevelWindow(guiEntity_struct* e)
{
setPositionX(newLevelWindow, -90);
}
void hideNewLevelWindow(void)
{
setPositionX(newLevelWindow, -400);
}
void newLevelYesButton(guiEntity_struct* e)
{
selectedRoom=NULL;
currentEntity=NULL;
wipeMapEdit();
hideNewLevelWindow();
}
void newLevelNoButton(guiEntity_struct* e)
{
hideNewLevelWindow();
}
void initNewLevelWindow(void)
{
u16 w=180;
// newLevelWindow=createWindow(-w/2,16,w,78,31,RGB15(31,31,31),1,RGB15(0,0,0),"");
newLevelWindow=createWindow(-400,16,w,78,31,RGB15(31,31,31),1,RGB15(0,0,0),"");
newLevelWindow->prio+=64;
u16 k=w/2-strlen("Unsaved data will be")*4;
createLabelFather(w/2-3*8-4, 8, RGB15(31,31,31), newLevelWindow, "New Map", false);
createLabelFather(k, 24, RGB15(31,31,31), newLevelWindow, "Unsaved data will be", false);
createLabelFather(k, 24+12, RGB15(31,31,31), newLevelWindow, "lost. Are you sure ?", false);
createButtonFather(w/2-38, 24*2+4, RGB15(31,31,31), newLevelYesButton, newLevelWindow, "Yes", "", false)->outline=1;
createButtonFather(w/2+38-16-8, 24*2+4, RGB15(31,31,31), newLevelNoButton, newLevelWindow, "No", "", false)->outline=1;
}
void resetRoomButtons(void)
{
int i;
for(i=0;i<TOOLBUTTONS;i++)if(toolButtons[i])((guiButtonData_struct*)toolButtons[i]->data)->colorTakeover=false;
}
void commonToolButton(guiEntity_struct* e)
{
guiButtonData_struct* data=(guiButtonData_struct*)e->data;
resetRoomButtons();
data->colorTakeover=true;
e->outline_color=RGB15(31,0,0);
e->color=RGB15(31,20,27);
NOGBA("LALALA");
}
void buttonCreateRoom(guiEntity_struct* e)
{
commonToolButton(e);
setRoomEditorMode(ROOMCREATION);
}
void buttonSelectRoom(guiEntity_struct* e)
{
commonToolButton(e);
setRoomEditorMode(ROOMSELECTION);
}
void buttonResizeRoom(guiEntity_struct* e)
{
commonToolButton(e);
setRoomEditorMode(ROOMSELECTRESIZE);
}
void buttonMoveRoom(guiEntity_struct* e)
{
commonToolButton(e);
setRoomEditorMode(ROOMSELECTMOVE);
}
void buttonSelectMaterialFunction(guiEntity_struct* e)
{
closeListWindow(NULL);
if(!correspondanceList)return;
int i;
for(i=0;i<listWindow.numButtons;i++)
{
if(e==listWindow.button[i])break;
}
if(i<listWindow.numButtons)
{
selectedMaterial=correspondanceList[i+listWindow.cursor];
updateLabelText(materialWindowLabel,listWindow.nameList[i+listWindow.cursor]);
}else {selectedMaterial=0;updateLabelText(materialWindowLabel,listWindow.nameList[0]);}
freeMaterialList(listWindow.nameList);
free(correspondanceList);
correspondanceList=NULL;
}
void buttonSelectMaterial(guiEntity_struct* e)
{
int n;
char** l=getMaterialList(&n, &correspondanceList);
openListWindow(NULL,"Select material", l,n,6,&buttonSelectMaterialFunction);
}
void buttonApplyMaterial(guiEntity_struct* e)
{
applyMaterial(getMaterial(selectedMaterial), NULL, NULL, NULL);
}
extern u8 selectionMode;
extern u8 oldSelectionMode;
void buttonSelectTiles(guiEntity_struct* e)
{
commonToolButton(e);
setRoomEditorMode(TILESELECTION);
selectionMode=1;
}
void buttonUpTiles(guiEntity_struct* e)
{
moveData(1, NULL, NULL, NULL);
}
void buttonDownTiles(guiEntity_struct* e)
{
moveData(-1, NULL, NULL, NULL);
}
void buttonSwapData(guiEntity_struct* e)
{
swapData(NULL);
}
void buttonDeleteRoom(guiEntity_struct* e)
{
deleteRoomEdit(NULL);
selectionMode=0;
}
void buttonRenderRoom(guiEntity_struct* e)
{
optimizeRoom(selectedRoom);
}
void buttonMakeWall(guiEntity_struct* e)
{
makeWall(NULL, NULL, NULL);
}
void buttonSelectEntityTool(guiEntity_struct* e)
{
commonToolButton(e);
setRoomEditorMode(ENTITYSELECTION);
selectionMode=0;
}
void buttonCreateLightTool(guiEntity_struct* e)
{
commonToolButton(e);
setRoomEditorMode(LIGHTCREATION);
}
void buttonCreateEnemyTool(guiEntity_struct* e)
{
commonToolButton(e);
setRoomEditorMode(ENEMYCREATION);
}
void buttonCreateDoorTool(guiEntity_struct* e)
{
commonToolButton(e);
setRoomEditorMode(DOORCREATION);
}
void buttonUpEntity(guiEntity_struct* e)
{
if(currentEntity)
{
currentEntity->position.z++;
changeRoom(selectedRoom,false);
}
}
void buttonDownEntity(guiEntity_struct* e)
{
if(currentEntity)
{
currentEntity->position.z--;
changeRoom(selectedRoom,false);
}
}
void buttonUpLight(guiEntity_struct* e)
{
if(currentEntity)
{
if(currentEntity->type==lightEntity)
{
lightData_struct* d=currentEntity->data;
d->intensity=min(d->intensity+TILESIZE,TILESIZE*2*60);
changeRoom(selectedRoom,false);
}
}
}
void buttonDownLight(guiEntity_struct* e)
{
if(currentEntity)
{
if(currentEntity->type==lightEntity)
{
lightData_struct* d=currentEntity->data;
d->intensity=max(d->intensity-TILESIZE,128);
changeRoom(selectedRoom,false);
}
}
}
void buttonDeleteEntity(guiEntity_struct* e)
{
if(selectedRoom && currentEntity)
{
if(currentEntity->type==lightEntity)changeRoom(selectedRoom,false);
removeEntity(&selectedRoom->entityCollection,currentEntity);
currentEntity=NULL;
}
}
char** levelList=NULL;
void actuallyLoadLevelButton(guiEntity_struct* e)
{
int i;
for(i=0;i<listWindow.numButtons;i++)
{
if(e==listWindow.button[i])break;
}
if(i<listWindow.numButtons)
{
i+=listWindow.cursor;
}
wipeMapEdit();
readMap(levelList[i], false);
freeLevelList(levelList);
levelList=NULL;
closeListWindow(NULL);
NOGBA("mem free : %dko (%do)",getMemFree()/1024,getMemFree());
}
void loadLevelButton(guiEntity_struct* e)
{
int k=0;
char str[255];
sprintf(str,"%sfpsm/maps/",basePath);
NOGBA("mem free : %dko (%do)",getMemFree()/1024,getMemFree());
levelList=listFiles(str, &k);
openListWindow(NULL, "Load Map", levelList, k, 6, actuallyLoadLevelButton);
}
void saveLevelButton(guiEntity_struct* e)
{
writeMap("lalala.map");
}
void updateSelectedRoomToolWindow(void)
{
if(!selectedRoom)
{
if(oldSelectedRoom)
{
setPosition(selectedRoomToolWindow, -200, f32toint(selectedRoomToolWindow->Position.y));
if(roomEditorMode>ROOMSELECTION)buttonCreateRoom(toolButtons[0]);
}
}else{
if(!oldSelectedRoom)setPosition(selectedRoomToolWindow, -120, f32toint(selectedRoomToolWindow->Position.y));
}
}
void updateEntityToolWindow(void)
{
if(!selectedRoom)
{
if(oldSelectedRoom)
{
setPosition(entityToolWindow, -260, f32toint(entityToolWindow->Position.y));
if(roomEditorMode>ROOMSELECTION)buttonCreateRoom(toolButtons[0]);
}
}else{
if(!oldSelectedRoom)setPosition(entityToolWindow, -120+24+8+8+64, f32toint(entityToolWindow->Position.y));
}
}
void updateTileToolWindow(void)
{
if(!selectionMode)
{
if(oldSelectionMode)setPosition(tileToolWindow, 200, f32toint(tileToolWindow->Position.y));
}else if(selectionMode==2){
if(oldSelectionMode<=1)setPosition(tileToolWindow, 96, f32toint(tileToolWindow->Position.y));
}
}
void updateEntityPropertyWindow(void)
{
if(!selectionMode)
{
if(oldSelectionMode)setPosition(entityPropertyWindow, 200, f32toint(entityPropertyWindow->Position.y));
}else if(selectionMode==3){
if(oldSelectionMode<=1)setPosition(entityPropertyWindow, 96, f32toint(entityPropertyWindow->Position.y));
}
}
void initEditor(void)
{
NOGBA("initializing...");
videoSetMode(MODE_0_3D);
glInit();
initD3D();
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glClearColor(0,0,0,31);
glClearPolyID(63);
glClearDepth(0x7FFF);
glViewport(0,0,255,191);
// initVramBanks(2);
initVramBanks(1);
initTextures();
initCamera(NULL);
initText();
initGrid();
initRoomEditor();
initGui();
initMaterials();
initDoorCollection(NULL);
fileToolWindow=createWindow(-120+24+8,8,64,24,31,RGB15(31,31,31),1,RGB15(0,0,0),"");
actionButtons[13]=createButtonFather(4, 3, RGB15(31,31,31), callNewLevelWindow, fileToolWindow, "", "icon21.pcx", false);
actionButtons[14]=createButtonFather(4+(16+4), 3, RGB15(31,31,31), loadLevelButton, fileToolWindow, "", "icon22.pcx", false);
actionButtons[15]=createButtonFather(4+(16+4)*2, 3, RGB15(31,31,31), saveLevelButton, fileToolWindow, "", "icon23.pcx", false);
roomToolWindow=createWindow(-120,8,24,88,31,RGB15(31,31,31),1,RGB15(0,0,0),"");
toolButtons[0]=createButtonFather(3, 4, RGB15(31,31,31), buttonCreateRoom, roomToolWindow, "", "icon1.pcx", false);
toolButtons[1]=createButtonFather(3, 4+(16+4), RGB15(31,31,31), buttonSelectRoom, roomToolWindow, "", "icon2.pcx", false);
toolButtons[2]=createButtonFather(3, 4+(16+4)*2, RGB15(31,31,31), buttonResizeRoom, roomToolWindow, "", "icon3.pcx", false);
toolButtons[3]=createButtonFather(3, 4+(16+4)*3, RGB15(31,31,31), buttonMoveRoom, roomToolWindow, "", "icon4.pcx", false);
resetRoomButtons();
buttonCreateRoom(toolButtons[0]);
selectedRoomToolWindow=createWindow(-200,f32toint(roomToolWindow->Position.y+roomToolWindow->Size.y)+8,24,88,31,RGB15(31,31,31),1,RGB15(0,0,0),"");
toolButtons[4]=createButtonFather(3, 4, RGB15(31,31,31), buttonSelectTiles, selectedRoomToolWindow, "", "icon5.pcx", false);
actionButtons[0]=createButtonFather(3, 4+(16+4), RGB15(31,31,31), buttonDeleteRoom, selectedRoomToolWindow, "", "icon6.pcx", false);
actionButtons[1]=createButtonFather(3, 4+(16+4)*2, RGB15(31,31,31), buttonSwapData, selectedRoomToolWindow, "", "icon7.pcx", false);
actionButtons[8]=createButtonFather(3, 4+(16+4)*3, RGB15(31,31,31), buttonRenderRoom, selectedRoomToolWindow, "", "icon14.pcx", false);
tileToolWindow=createWindow(200,8,24,64,31,RGB15(31,31,31),1,RGB15(0,0,0),"");
actionButtons[2]=createButtonFather(3, 4, RGB15(31,31,31), buttonUpTiles, tileToolWindow, "", "icon8.pcx", false);
actionButtons[3]=createButtonFather(3, 4+(16+4), RGB15(31,31,31), buttonDownTiles, tileToolWindow, "", "icon9.pcx", false);
actionButtons[4]=createButtonFather(3, 4+(16+4)*2, RGB15(31,31,31), buttonMakeWall, tileToolWindow, "", "icon10.pcx", false);
entityToolWindow=createWindow(-260,8,86,24,31,RGB15(31,31,31),1,RGB15(0,0,0),"");
toolButtons[5]=createButtonFather(4, 3, RGB15(31,31,31), buttonSelectEntityTool, entityToolWindow, "", "icon13.pcx", false);
toolButtons[6]=createButtonFather(4+(16+4), 3, RGB15(31,31,31), buttonCreateLightTool, entityToolWindow, "", "icon11.pcx", false);
toolButtons[7]=createButtonFather(4+(16+4)*2, 3, RGB15(31,31,31), buttonCreateEnemyTool, entityToolWindow, "", "icon12.pcx", false);
toolButtons[8]=createButtonFather(4+(16+4)*3, 3, RGB15(31,31,31), buttonCreateDoorTool, entityToolWindow, "", "icon20.pcx", false);
entityPropertyWindow=createWindow(200,8,24,104,31,RGB15(31,31,31),1,RGB15(0,0,0),"");
actionButtons[5]=createButtonFather(3, 4, RGB15(31,31,31), buttonUpEntity, entityPropertyWindow, "", "icon8.pcx", false);
actionButtons[6]=createButtonFather(3, 4+(16+4), RGB15(31,31,31), buttonDownEntity, entityPropertyWindow, "", "icon9.pcx", false);
actionButtons[7]=createButtonFather(3, 4+(16+4)*2, RGB15(31,31,31), buttonUpLight, entityPropertyWindow, "", "icon17.pcx", false);
actionButtons[9]=createButtonFather(3, 4+(16+4)*3, RGB15(31,31,31), buttonDownLight, entityPropertyWindow, "", "icon18.pcx", false);
actionButtons[10]=createButtonFather(3, 4+(16+4)*4, RGB15(31,31,31), buttonDeleteEntity, entityPropertyWindow, "", "icon19.pcx", false);
materialToolWindow=createWindow(-120+24+8,191-24,140,24,31,RGB15(31,31,31),1,RGB15(0,0,0),"");
actionButtons[11]=createButtonFather(4, 3, RGB15(31,31,31), buttonSelectMaterial, materialToolWindow, "", "icon15.pcx", false);
actionButtons[12]=createButtonFather(4+(16+4), 3, RGB15(31,31,31), buttonApplyMaterial, materialToolWindow, "", "icon16.pcx", false);
createLabelFather(4+(16+4)*2, 2, RGB15(31,31,31), materialToolWindow, "selected :", false);
materialWindowLabel=createLabelFather(4+(16+4)*2+4, 2+12, RGB15(31,31,31), materialToolWindow, "material0", false);
initListWindow(NULL);
initNewLevelWindow();
loadMaterialSlices("slices.ini");
loadMaterials("materials.ini");
getVramStatus();
NOGBA("START mem free : %dko (%do)",getMemFree()/1024,getMemFree());
fadeIn();
}
int frm=0;
int frm2=0;
int testTime=0;
void editorFrame(void)
{
touchPosition touchPos;
switch(d3dScreen)
{
case true:
projectGrid();
glPushMatrix();
scanKeys();
touchRead(&touchPos);
if(keysHeld()&(KEY_RIGHT))translateGrid(vect(-(1<<7),0,0));
if(keysHeld()&(KEY_LEFT))translateGrid(vect((1<<7),0,0));
if(keysHeld()&(KEY_DOWN))translateGrid(vect(0,-(1<<7),0));
if(keysHeld()&(KEY_UP))translateGrid(vect(0,(1<<7),0));
if(keysHeld()&(KEY_R))scaleGrid(1<<6);
if(keysHeld()&(KEY_L))scaleGrid(-(1<<6));
transformGrid();
updateRoomEditor(touchPos.px,touchPos.py);
char testStr[32];
sprintf(testStr,"%d",testTime);
// drawString("lalala",RGB15(31,31,31),inttof32(1)/32,0,0);
drawString(testStr,RGB15(31,31,31),inttof32(1)/32,0,0);
drawGrid();
drawRoomEdits();
glPopMatrix(1);
guiCall();
projectGui();
updateTileToolWindow();
updateEntityPropertyWindow();
updateSelectedRoomToolWindow();
updateEntityToolWindow();
glPushMatrix();
updateGui(NULL,&touchPos);
glPopMatrix(1);
glFlush(0);
// glFlush(GL_TRANS_MANUALSORT|GL_WBUFFERING);
// glFlush(GL_WBUFFERING);
break;
default:
projectCamera(NULL);
if(keysHeld()&(KEY_A))rotateCamera(NULL, vect(0,-(1<<8),0));
if(keysHeld()&(KEY_Y))rotateCamera(NULL, vect(0,1<<8,0));
if(keysHeld()&(KEY_B))moveCamera(NULL, vect(0,0,inttof32(1)>>6));
if(keysHeld()&(KEY_X))moveCamera(NULL, vect(0,0,-(inttof32(1)>>6)));
// if(keysHeld()&(KEY_SELECT))moveCamera(NULL, vect(0,-(inttof32(1)>>6),0));
// if(keysHeld()&(KEY_START))moveCamera(NULL, vect(0,inttof32(1)>>6,0));
// if(keysDown()&(KEY_SELECT))writeMap("lalala.map");
// if(keysDown()&(KEY_SELECT))changeState(&editorState);
// if(keysDown()&(KEY_START))readMap("lalala.map", false);
// if(selectedRoom)updateCameraPreview(&selectedRoom->data, NULL);
// else
updateCameraPreview(NULL, NULL);
glPushMatrix();
glScalef32(SCALEFACT,SCALEFACT,SCALEFACT);
transformCamera(NULL);
/*
glPushMatrix();
// TEST
glLight(0, RGB15(16,16,16), 0, 0, floattov10(-1)+1);
glMaterialf(GL_AMBIENT, RGB15(2,2,2));
glMaterialf(GL_DIFFUSE, RGB15(31,31,31));
glMaterialf(GL_SPECULAR, RGB15(0,0,0));
glMaterialf(GL_EMISSION, RGB15(0,0,0));
// TEST
PROF_START();
renderModelFrameInterp(frm,frm2,&testModel);
// renderModelFrame(frm,&testModel);
glTranslate3f32(floattof32(20.0f),0,0);
renderModelFrameInterp(frm,frm2,&testModel);
// renderModelFrame(frm,&testModel);
glTranslate3f32(floattof32(20.0f),0,0);
renderModelFrameInterp(frm,frm2,&testModel);
// renderModelFrame(frm,&testModel);
glTranslate3f32(floattof32(20.0f),0,0);
renderModelFrameInterp(frm,frm2,&testModel);
// renderModelFrame(frm,&testModel);
PROF_END(testTime);
testTime/=4;
glPopMatrix(1);*/
frm2++;
if(frm2>=4){frm++;frm2=0;}
drawRoomsPreview();
glPopMatrix(1);
glFlush(0);
// glFlush(GL_TRANS_MANUALSORT|GL_WBUFFERING);
// glFlush(GL_WBUFFERING);
break;
}
swiWaitForVBlank();
updateD3D();
}
void killEditor(void)
{
fadeOut();
NOGBA("KILLING IT");
cleanUpGui();
wipeMapEdit();
freeState(NULL);
NOGBA("END mem free : %dko (%do)",getMemFree()/1024,getMemFree());
}
void editorVBL(void)
{
}

306
arm9/source/editor/entity.c Normal file
View File

@ -0,0 +1,306 @@
#include "editor/editor_main.h"
mtlImg_struct *lightMtl, *enemyMtl;
void initEntity(entity_struct* e)
{
if(e)
{
e->position=vect(0,0,0);
e->type=0;
e->data=NULL;
e->selected=false;
e->used=false;
}
}
void initLight(entity_struct* e, int32 intensity)
{
if(e)
{
e->type=lightEntity;
e->mtl=lightMtl;
lightData_struct* d=e->data=malloc(sizeof(lightData_struct));
if(d)
{
d->intensity=intensity;
}
}
}
void initEnemy(entity_struct* e, u8 type)
{
if(e)
{
e->type=enemyEntity;
e->mtl=enemyMtl;
enemyData_struct* d=e->data=malloc(sizeof(enemyData_struct));
if(d)
{
d->type=type;
}
}
}
void initEntityCollection(entityCollection_struct* ec)
{
if(ec)
{
int i;
for(i=0;i<ENTITYCOLLECTIONNUM;i++)
{
initEntity(&ec->entity[i]);
}
ec->num=0;
lightMtl=createTexture("light.pcx", "gui");
enemyMtl=createTexture("enemy.pcx", "gui");
}
}
void drawCircle(vect3D p, int32 r, u8 precision)
{
glPushMatrix();
glTranslate3f32(p.x,p.y,p.z);
glScalef32(r,r,r);
int i;
glBegin(GL_TRIANGLES);
for(i=0;i<precision;i++)
{
u16 a=(i*(1<<15))/precision;
u16 a2=((i+1)*(1<<15))/precision;
glVertex3v16(cosLerp(a),sinLerp(a),0);
glVertex3v16(cosLerp(a2),sinLerp(a2),0);
glVertex3v16(cosLerp(a2),sinLerp(a2),0);
}
glPopMatrix(1);
}
entity_struct* createEntity(entityCollection_struct* ec, vect3D position)
{
if(ec)
{
int i;
for(i=0;i<ENTITYCOLLECTIONNUM;i++)
{
if(!ec->entity[i].used)
{
entity_struct* e=&ec->entity[i];
e->used=true;
e->data=NULL;
e->selected=false;
e->position=position;
ec->num++;
return e;
}
}
}
return NULL;
}
void removeEntity(entityCollection_struct* ec, entity_struct* e)
{
if(ec&&e&&e->used)
{
int i;
for(i=0;i<ENTITYCOLLECTIONNUM;i++)
{
if(&ec->entity[i]==e)
{
e->used=false;
if(e->data)free(e->data);
e->data=false;
ec->num--;
return;
}
}
}
}
entity_struct* createLight(entityCollection_struct* ec, vect3D position, int32 intensity)
{
entity_struct* e=createEntity(ec,position);
initLight(e,intensity);
return e;
}
entity_struct* createEnemy(entityCollection_struct* ec, vect3D position, u8 type)
{
entity_struct* e=createEntity(ec,position);
initEnemy(e,type);
return e;
}
static inline bool collideEntity(entity_struct* e, int px, int py)
{
return e->position.x==px&&e->position.y==py;
}
entity_struct* collideEntityCollection(entityCollection_struct* ec, int px, int py)
{
if(ec)
{
int i;
for(i=0;i<ENTITYCOLLECTIONNUM;i++)
{
if(ec->entity[i].used)
{
if(collideEntity(&ec->entity[i],px,py))return &ec->entity[i];
}
}
}
return NULL;
}
void drawEntity(entity_struct* e)
{
if(e)
{
glPushMatrix();
if(e->selected)
{
u8 v=e->position.z;
u16 c=RGB15(v,v,v);
glTranslate3f32(0,0,16);
unbindMtl();
drawTile(e->position.x-1,e->position.y-1,c);
drawTile(e->position.x-1,e->position.y,c);
drawTile(e->position.x-1,e->position.y+1,c);
drawTile(e->position.x,e->position.y-1,c);
drawTile(e->position.x+1,e->position.y-1,c);
drawTile(e->position.x,e->position.y,c);
drawTile(e->position.x,e->position.y+1,c);
drawTile(e->position.x+1,e->position.y,c);
drawTile(e->position.x+1,e->position.y+1,c);
glColor3b(255,255,255);
lightData_struct* d=e->data;
drawCircle(vect(e->position.x*(1<<9)+(1<<8),e->position.y*(1<<9)+(1<<8),64),sqrtf32(sqrtf32((d->intensity*(1<<9))/(TILESIZE*2))),32);
}
glTranslate3f32(0,0,64);
applyMTL(e->mtl);
glTranslate3f32(e->position.x*(1<<9)-(1<<8),e->position.y*(1<<9)-(1<<8),0);
glScalef32(2*(1<<9),2*(1<<9),inttof32(1));
glBegin(GL_QUADS);
if(e->selected)glColor3b(255,0,0);
else glColor3b(255,255,255);
GFX_TEX_COORD=TEXTURE_PACK(0,16*16);
glVertex3v16(0, inttof32(1), 0);
GFX_TEX_COORD=TEXTURE_PACK(16*16,16*16);
glVertex3v16(inttof32(1), inttof32(1), 0);
GFX_TEX_COORD=TEXTURE_PACK(16*16,0);
glVertex3v16(inttof32(1), 0, 0);
GFX_TEX_COORD=TEXTURE_PACK(0,0);
glVertex3v16(0, 0, 0);
glPopMatrix(1);
}
}
void drawEntityCollection(entityCollection_struct* ec)
{
if(ec)
{
int i;
for(i=0;i<ENTITYCOLLECTIONNUM;i++)
{
if(ec->entity[i].used)
{
drawEntity(&ec->entity[i]);
}
}
}
}
void renderEntity(entity_struct* e)
{
if(e)
{
glPushMatrix();
applyMTL(e->mtl);
glTranslate3f32(e->position.x*(TILESIZE*2),e->position.z*HEIGHTUNIT,e->position.y*(TILESIZE*2));
glScalef32((1<<8),(1<<8),(1<<8));
glBegin(GL_QUADS);
if(e->selected)glColor3b(255,0,0);
else glColor3b(255,255,255);
GFX_TEX_COORD=TEXTURE_PACK(0,0);
glVertex3v16(-inttof32(1), inttof32(1), 0);
GFX_TEX_COORD=TEXTURE_PACK(16*16,0*16);
glVertex3v16(inttof32(1), inttof32(1), 0);
GFX_TEX_COORD=TEXTURE_PACK(16*16,16*16);
glVertex3v16(inttof32(1), -inttof32(1), 0);
GFX_TEX_COORD=TEXTURE_PACK(0,16*16);
glVertex3v16(-inttof32(1), -inttof32(1), 0);
GFX_TEX_COORD=TEXTURE_PACK(0,0);
glVertex3v16(0, inttof32(1), -inttof32(1));
GFX_TEX_COORD=TEXTURE_PACK(16*16,0*16);
glVertex3v16(0, inttof32(1), inttof32(1));
GFX_TEX_COORD=TEXTURE_PACK(16*16,16*16);
glVertex3v16(0, -inttof32(1), inttof32(1));
GFX_TEX_COORD=TEXTURE_PACK(0,16*16);
glVertex3v16(0, -inttof32(1), -inttof32(1));
glPopMatrix(1);
}
}
void renderEntityCollection(entityCollection_struct* ec)
{
if(ec)
{
int i;
glPolyFmt(POLY_ALPHA(31) | POLY_CULL_NONE);
for(i=0;i<ENTITYCOLLECTIONNUM;i++)
{
if(ec->entity[i].used)
{
renderEntity(&ec->entity[i]);
}
}
}
}
void wipeEntityCollection(entityCollection_struct* ec)
{
if(ec)
{
int i;
for(i=0;i<ENTITYCOLLECTIONNUM;i++)
{
if(ec->entity[i].used)removeEntity(ec, &ec->entity[i]);
}
}
}
void getClosestLights(entityCollection_struct* ec, enemy_struct* e, entity_struct** ll1, entity_struct** ll2, entity_struct** ll3, int32* dd1, int32* dd2, int32* dd3)
{
if(!ec)return;
entity_struct *l1, *l2, *l3;
int32 d1, d2, d3;
d1=d2=d3=inttof32(300);
l1=l2=l3=NULL;
int i;
for(i=0;i<ENTITYCOLLECTIONNUM;i++)
{
if(ec->entity[i].used && ec->entity[i].type==lightEntity)
{
entity_struct* ent=&ec->entity[i];
int32 d=(e->tilePosition.x-ent->position.x)*(e->tilePosition.x-ent->position.x)+((e->tilePosition.y-ent->position.y)*(e->tilePosition.y-ent->position.y))/16+(e->tilePosition.z-ent->position.z)*(e->tilePosition.z-ent->position.z);
if(d<d1){d3=d2;d2=d1;d1=d;
l3=l2;l2=l1;l1=ent;}
else if(d<d2){d3=d2;d2=d;
l3=l2;l2=ent;}
else if(d<d3){d3=d;
l3=ent;}
}
}
*ll1=l1;
*ll2=l2;
*ll3=l3;
*dd1=d1;
*dd2=d2;
*dd3=d3;
}

96
arm9/source/editor/grid.c Normal file
View File

@ -0,0 +1,96 @@
#include "editor/editor_main.h"
#define MINSCALE (inttof32(1)/2)
#define MAXSCALE (inttof32(3)/2)
#define NUMLINESX 9
#define NUMLINESY 8
vect3D gridTranslation;
int32 gridScale;
void projectGrid(void)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrthof32(0, inttof32(255)>>6, inttof32(191)>>6, 0, -1000, 1000);
glMatrixMode(GL_MODELVIEW);
}
void initGrid(void)
{
gridScale=inttof32(1);
gridTranslation.x=0;
gridTranslation.y=0;
gridTranslation.z=0;
}
void transformGrid(void)
{
glTranslate3f32(inttof32(4)/2,inttof32(3)/2,0);
glScalef32(gridScale,gridScale,gridScale);
glTranslate3f32(gridTranslation.x,gridTranslation.y,gridTranslation.z);
}
void setGridScale(int32 s){gridScale=s;if(gridScale<MINSCALE)gridScale=MINSCALE;else if(gridScale>MAXSCALE)gridScale=MAXSCALE;}
void setGridTranslation(vect3D v){gridTranslation=v;}
void scaleGrid(int32 s){setGridScale(gridScale+s);}
void translateGrid(vect3D v){setGridTranslation(vect(gridTranslation.x+v.x,gridTranslation.y+v.y,gridTranslation.z+v.z));}
void getGridCell(int* x, int* y, int px, int py)
{
*x=(divf32((px-128)*(1<<6),gridScale)-gridTranslation.x)/64;
if(*x>=0)*x/=8;
else{*x/=8;(*x)--;}
*y=(divf32((py-96)*(1<<6),gridScale)-gridTranslation.y)/64;
if(*y>=0)*y/=8;
else{*y/=8;(*y)--;}
}
void drawGrid(void)
{
int i;
glPolyFmt(POLY_ALPHA(31) | POLY_CULL_BACK);
glPushMatrix();
glTranslate3f32(-(gridTranslation.x-gridTranslation.x%(16<<6)),-(gridTranslation.y-gridTranslation.y%(16<<6)),0);
glBegin(GL_TRIANGLES);
glColor3b(200,200,200);
for(i=8-NUMLINESX*2;i<8+NUMLINESX*2;i++)
{
int k=(i-8)*16;
glVertex3v16((k)<<6, -(112<<7), 0);
glVertex3v16((k)<<6, (112<<7), 0);
glVertex3v16((k)<<6, (112<<7), 0);
}
for(i=6-NUMLINESY*2;i<6+NUMLINESY*2;i++)
{
int k=(i-8)*16;
glVertex3v16(-(144)<<7, (k)<<6, 0);
glVertex3v16((144)<<7, (k)<<6, 0);
glVertex3v16((144)<<7, (k)<<6, 0);
}
glColor3b(100,100,100);
for(i=8-NUMLINESX*2;i<8+NUMLINESX*2;i++)
{
int k=(i-8)*16+8;
glVertex3v16((k)<<6, -(112<<7), 0);
glVertex3v16((k)<<6, (112<<7), 0);
glVertex3v16((k)<<6, (112<<7), 0);
}
for(i=6-NUMLINESY*2;i<6+NUMLINESY*2;i++)
{
int k=(i-8)*16+8;
glVertex3v16(-(144)<<7, (k)<<6, 0);
glVertex3v16((144)<<7, (k)<<6, 0);
glVertex3v16((144)<<7, (k)<<6, 0);
}
glEnd();
glPopMatrix(1);
}

View File

@ -0,0 +1,226 @@
#include "editor/editor_main.h"
material_struct materials[NUMMATERIALS];
material_struct* defaultMaterial;
materialSlice_struct materialSlices[NUMMATERIALSLICES];
materialSlice_struct* defaultMaterialSlice;
void initMaterials(void)
{
int i;
for(i=0;i<NUMMATERIALS;i++)
{
material_struct* m=&materials[i];
m->used=false;
m->id=i;
m->top=m->bottom=m->side=NULL;
}
for(i=0;i<NUMMATERIALSLICES;i++)
{
materialSlice_struct* ms=&materialSlices[i];
ms->used=false;
ms->id=i;
ms->img=NULL;
}
defaultMaterial=createMaterial();
defaultMaterialSlice=createMaterialSlice();
loadMaterialSlice(defaultMaterialSlice,"default.pcx");
}
materialSlice_struct* createMaterialSlice()
{
int i;
for(i=0;i<NUMMATERIALSLICES;i++)
{
if(!materialSlices[i].used)
{
materialSlice_struct* ms=&materialSlices[i];
ms->used=true;
ms->img=NULL;
return ms;
}
}
return NULL;
}
material_struct* createMaterial()
{
int i;
for(i=0;i<NUMMATERIALS;i++)
{
if(!materials[i].used)
{
material_struct* m=&materials[i];
m->used=true;
m->top=m->bottom=m->side=NULL;
return m;
}
}
return NULL;
}
void loadMaterialSlice(materialSlice_struct* ms, char* filename)
{
if(ms)
{
ms->img=createTexture(filename,"textures");
ms->align=false;
ms->factor=1;
}
}
void loadMaterialSlices(char* filename)
{
dictionary* dic=iniparser_load(filename);
int i=0;
char* r;
char key[255];
sprintf(key,"slice%d:texture",i);
while((r=dictionary_get(dic, key, NULL)))
{
materialSlice_struct* ms=createMaterialSlice();
loadMaterialSlice(ms,r);
NOGBA("loaded %d : %s",i,r);
int k=0;
sprintf(key,"slice%d:align",i);
sscanf(dictionary_get(dic, key, "0"),"%d",&k);
ms->align=(k!=0);
sprintf(key,"slice%d:factor",i);
sscanf(dictionary_get(dic, key, "1"),"%d",&k);
ms->factor=k;
// if(!ms->img){break;}
i++;
sprintf(key,"slice%d:texture",i);
}
iniparser_freedict(dic);
}
void loadMaterials(char* filename)
{
dictionary* dic=iniparser_load(filename);
int i=0;
char *r1, *r2, *r3;
char key1[255],key2[255],key3[255];
sprintf(key1,"material%d:top",i);
sprintf(key2,"material%d:side",i);
sprintf(key3,"material%d:bottom",i);
(r1=dictionary_get(dic, key1, NULL));(r2=dictionary_get(dic, key2, NULL));(r3=dictionary_get(dic, key3, NULL));
while(r1||r2||r3)
{
material_struct* m=createMaterial();
if(!m){break;}
if(r1)
{
int k;
sscanf(r1,"%d",&k);
m->top=&materialSlices[k+1];
}
if(r2)
{
int k;
sscanf(r2,"%d",&k);
m->side=&materialSlices[k+1];
}
if(r3)
{
int k;
sscanf(r3,"%d",&k);
m->bottom=&materialSlices[k+1];
}
i++;
sprintf(key1,"material%d:top",i);
sprintf(key2,"material%d:side",i);
sprintf(key3,"material%d:bottom",i);
r1=dictionary_get(dic, key1, NULL);r2=dictionary_get(dic, key2, NULL);r3=dictionary_get(dic, key3, NULL);
}
iniparser_freedict(dic);
}
void bindMaterialSlice(materialSlice_struct* ms)
{
if(!ms)ms=defaultMaterialSlice;
applyMTL(ms->img);
}
void getTextureCoordSlice(materialSlice_struct* ms, rectangle_struct* rec, int32* t)
{
if(!ms)ms=defaultMaterialSlice;
if(!ms->img)return;
vect3D p1=vect(0,0,0), p2;
if(!rec->size.x)
{
if(ms->align)p1=vect(inttot16(ms->img->height*rec->position.z-1),inttot16(((ms->img->height*rec->position.y)*HEIGHTUNIT)/(TILESIZE*2)-1),0);
p2=vect(inttot16(ms->img->height*rec->size.z-1),inttot16(((ms->img->height*rec->size.y)*HEIGHTUNIT)/(TILESIZE*2)-1),0);
p2=addVect(p1,p2);
p1=vectDivInt(p1,ms->factor);
p2=vectDivInt(p2,ms->factor);
t[3]=TEXTURE_PACK(p1.x, p1.y);
t[0]=TEXTURE_PACK(p1.x, p2.y);
t[1]=TEXTURE_PACK(p2.x, p2.y);
t[2]=TEXTURE_PACK(p2.x, p1.y);
}else if(!rec->size.y)
{
if(ms->align)p1=vect(inttot16(ms->img->width*rec->position.x-1),inttot16(ms->img->height*rec->position.z-1),0);
p2=vect(inttot16(ms->img->width*rec->size.x-1),inttot16(ms->img->height*rec->size.z-1),0);
p2=addVect(p1,p2);
p1=vectDivInt(p1,ms->factor);
p2=vectDivInt(p2,ms->factor);
t[0]=TEXTURE_PACK(p1.x, p1.y);
t[1]=TEXTURE_PACK(p1.x, p2.y);
t[2]=TEXTURE_PACK(p2.x, p2.y);
t[3]=TEXTURE_PACK(p2.x, p1.y);
}else
{
if(ms->align)p1=vect(inttot16(ms->img->width*rec->size.x-1),inttot16(((ms->img->height*rec->size.y)*HEIGHTUNIT)/(TILESIZE*2)-1),0);
p2=vect(inttot16(ms->img->width*rec->size.x-1),inttot16(((ms->img->height*rec->size.y)*HEIGHTUNIT)/(TILESIZE*2)-1),0);
p2=addVect(p1,p2);
p1=vectDivInt(p1,ms->factor);
p2=vectDivInt(p2,ms->factor);
t[1]=TEXTURE_PACK(p1.x, p1.y);
t[0]=TEXTURE_PACK(p1.x, p2.y);
t[3]=TEXTURE_PACK(p2.x, p2.y);
t[2]=TEXTURE_PACK(p2.x, p1.y);
}
}
char** getMaterialList(int* m, int** cl)
{
int i, n;
n=0;
for(i=0;i<NUMMATERIALS;i++)if(materials[i].used)n++;
char** l=malloc(sizeof(char*)*(n+1));
*cl=malloc(sizeof(int)*(n));
n=0;
for(i=0;i<NUMMATERIALS;i++)if(materials[i].used){l[n]=malloc(sizeof(char)*(32));(*cl)[n]=i;sprintf(l[n],"material%d",i);n++;}
l[n]=NULL;
*m=n;
return l;
}
material_struct* getMaterial(u16 i){if(i<0||i>NUMMATERIALS)i=0;return &materials[i];}
void freeMaterialList(char** l)
{
if(!l)return;
char** l2=l;
while(*l2){free(*l2);l2++;}
free(l);
}
void bindMaterial(material_struct* m, rectangle_struct* rec, int32* t)
{
if(!m)m=defaultMaterial;
if(!m->used)return;
materialSlice_struct* ms=m->side;
if(!rec->size.y)
{
if(rec->normal.y>0)ms=m->top;
else ms=m->bottom;
}
unbindMtl();
bindMaterialSlice(ms);
getTextureCoordSlice(ms,rec,t);
}

365
arm9/source/editor/md2.c Normal file
View File

@ -0,0 +1,365 @@
/*
* md2.c -- md2 model loader
* last modification: aug. 14, 2007
*
* Copyright (c) 2005-2007 David HENRY
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* gcc -Wall -ansi -lGL -lGLU -lglut md2.c -o md2
(modified for fixed point and probably other stuff by smealum, 2012)
*/
#include "common/general.h"
#define getInterpData(i,j,n) interpTable[(i)+(((j)+((n)<<2))<<8)]
/* Table of precalculated normals */
u32 anorms_table[162] =
#include "common/anorms.h"
;
vect3D anorms_table2[162] =
#include "common/anorms2.h"
;
void packFrameData(md2Model_struct *mdl, md2_frame_t* f)
{
int i;
for(i=0;i<mdl->header.num_vertices;i++)
{
md2_vertex_t* pvert = &f->verts[i];
// vect3D scale=f->scale;
// f->packedVerts[i]=vect(((scale.x*pvert->v[0])/8),((scale.y*pvert->v[1])/8),((scale.z*pvert->v[2])/8));
f->packedv10[i]=NORMAL_PACK(pvert->v[0],pvert->v[1],pvert->v[2]);
}
/*for(i=0;i<mdl->header.num_tris;i++)
{
int j;
vect3D n=vect(0,0,0);
for (j = 0; j < 3; ++j)
{
// md2_vertex_t* pvert = &f->verts[mdl->triangles[i].vertex[j]];
n=addVect(n,anorms_table2[f->verts[mdl->triangles[i].vertex[j]].normalIndex]);
}
n=vectDivInt(n,3);
f->faceNormals[i]=n;
}*/
}
void packTexcoordData(md2Model_struct *mdl)
{
int i;
for(i=0;i<mdl->header.num_st;i++)
{
mdl->packedTexcoords[i]=TEXTURE_PACK(inttot16(mdl->texcoords[i].s),inttot16(mdl->texcoords[i].t));
}
}
void trimName(char* name) //destructive
{
int i=0;
while(name[i]){if(name[i]>='0' && name[i]<='9'){name[i]=0;return;}i++;}
}
void getAnimations(md2Model_struct *mdl)
{
if(!mdl || !mdl->frames)return;
int i;
char* oldstr=NULL;
int n=0;
for(i=0;i<mdl->header.num_frames;i++)
{
md2_frame_t *pframe=&mdl->frames[i];
trimName(pframe->name);
if(strcmp(pframe->name,oldstr))n++;
oldstr=pframe->name;
}
mdl->numAnim=n;
mdl->animations=malloc(sizeof(md2Anim_struct)*mdl->numAnim);
n=0;
mdl->animations[0].start=0;
oldstr=mdl->frames[0].name;
for(i=0;i<mdl->header.num_frames;i++)
{
md2_frame_t *pframe=&mdl->frames[i];
if(strcmp(pframe->name,oldstr))
{
mdl->animations[n++].end=i-1;
mdl->animations[n].start=i;
}
oldstr=pframe->name;
}
mdl->animations[n].end=i-1;
}
int loadMd2Model(const char *filename, char *texname, md2Model_struct *mdl)
{
FILE *fp;
int i;
mdl->texture=createTexture(texname,"textures");
fp = fopen (filename, "rb");
if (!fp)
{
fprintf (stderr, "Error: couldn't open \"%s\"!\n", filename);
return 0;
}
/* Read header */
fread (&mdl->header, 1, sizeof (md2_header_t), fp);
if ((mdl->header.ident != 844121161) || (mdl->header.version != 8))
{
/* Error! */
fprintf (stderr, "Error: bad version or identifier\n");
fclose (fp);
return 0;
}
/* Memory allocations */
mdl->skins = (md2_skin_t *)malloc (sizeof (md2_skin_t) * mdl->header.num_skins);
mdl->texcoords = (md2_texCoord_t *)malloc (sizeof (md2_texCoord_t) * mdl->header.num_st);
mdl->triangles = (md2_triangle_t *)malloc (sizeof (md2_triangle_t) * mdl->header.num_tris);
mdl->frames = (md2_frame_t *)malloc (sizeof (md2_frame_t) * mdl->header.num_frames);
/* Read model data */
fseek (fp, mdl->header.offset_skins, SEEK_SET);
fread (mdl->skins, sizeof (md2_skin_t), mdl->header.num_skins, fp);
fseek (fp, mdl->header.offset_st, SEEK_SET);
fread (mdl->texcoords, sizeof (md2_texCoord_t), mdl->header.num_st, fp);
mdl->packedTexcoords=malloc(sizeof(u32)*mdl->header.num_st);
packTexcoordData(mdl);
fseek (fp, mdl->header.offset_tris, SEEK_SET);
fread (mdl->triangles, sizeof (md2_triangle_t), mdl->header.num_tris, fp);
/* Read frames */
fseek (fp, mdl->header.offset_frames, SEEK_SET);
for (i = 0; i < mdl->header.num_frames; ++i)
{
/* Memory allocation for vertices of this frame */
mdl->frames[i].verts = (md2_vertex_t *) malloc (sizeof (md2_vertex_t) * mdl->header.num_vertices);
mdl->frames[i].packedv10 = (u32 *) malloc (sizeof (u32) * mdl->header.num_vertices);
// mdl->frames[i].faceNormals = (vect3D *) malloc (sizeof (vect3D) * mdl->header.num_tris);
vec3_t scale,trans;
fread (scale, sizeof (vec3_t), 1, fp);
fread (trans, sizeof (vec3_t), 1, fp);
mdl->frames[i].scale=vect(floattof32(scale[0]),floattof32(scale[1]),floattof32(scale[2]));
mdl->frames[i].translate=vect(floattof32(trans[0]),floattof32(trans[1]),floattof32(trans[2]));
fread (mdl->frames[i].name, sizeof (char), 16, fp);
fread (mdl->frames[i].verts, sizeof (md2_vertex_t), mdl->header.num_vertices, fp);
packFrameData(mdl,&mdl->frames[i]);
}
getAnimations(mdl);
fclose(fp);
return 1;
}
void freeMd2Model(md2Model_struct *mdl)
{
int i;
if (mdl->skins)
{
free (mdl->skins);
mdl->skins = NULL;
}
if (mdl->texcoords)
{
free (mdl->texcoords);
free (mdl->packedTexcoords);
mdl->texcoords = NULL;
mdl->packedTexcoords = NULL;
}
if (mdl->triangles)
{
free (mdl->triangles);
mdl->triangles = NULL;
}
if (mdl->frames)
{
for (i = 0; i < mdl->header.num_frames; ++i)
{
free (mdl->frames[i].verts);
// free (mdl->frames[i].packedVerts);
free (mdl->frames[i].packedv10);
mdl->frames[i].verts = NULL;
mdl->frames[i].packedVerts = NULL;
mdl->frames[i].packedv10 = NULL;
}
free (mdl->frames);
mdl->frames = NULL;
}
if(mdl->animations)free(mdl->animations);
mdl->animations=NULL;
}
void renderModelFrame(int n, const md2Model_struct *mdl)
{
int i, j;
glPolyFmt(POLY_ALPHA(31) | POLY_FORMAT_LIGHT0 | POLY_CULL_FRONT);
n%=mdl->header.num_frames;
if ((n < 0) || (n > mdl->header.num_frames - 1))return;
md2_frame_t *pframe=&mdl->frames[n];
applyMTL(mdl->texture);
glPushMatrix();
glRotateXi(-(1<<13));
// vect3D u=vect(inttof32(1),0,0);
glTranslate3f32(pframe->translate.x,pframe->translate.y,pframe->translate.z);
glScalef32((pframe->scale.x),(pframe->scale.y),(pframe->scale.z));
glScalef32(inttof32(64),inttof32(64),inttof32(64)); // necessary for v10
glBegin (GL_TRIANGLES);
GFX_COLOR=RGB15(31,31,31);
for (i = 0; i < mdl->header.num_tris; ++i)
{
// if(fakeDotProduct(anorms_table2[pframe->verts[mdl->triangles[i].vertex[0]].normalIndex],u)>0)
{
for (j = 0; j < 3; ++j)
{
GFX_TEX_COORD=mdl->packedTexcoords[mdl->triangles[i].st[j]];
GFX_NORMAL=anorms_table[pframe->verts[mdl->triangles[i].vertex[j]].normalIndex];
//v16
// vect3D v=pframe->packedVerts[mdl->triangles[i].vertex[j]];
// glVertex3v16(v.x,v.y,v.z);
//v10
GFX_VERTEX10=pframe->packedv10[mdl->triangles[i].vertex[j]];
}
}
}
glEnd();
glPopMatrix(1);
}
void renderModelFrameInterp(int n, int n2, int m, const md2Model_struct *mdl, u32 params)
{
int i, j;
// glPolyFmt(POLY_ALPHA(31) | POLY_FORMAT_LIGHT0 | POLY_CULL_FRONT);
glPolyFmt(params);
n%=mdl->header.num_frames;
n2%=mdl->header.num_frames;
if ((n < 0) || (n > mdl->header.num_frames - 1))return;
md2_frame_t *pframe=&mdl->frames[n];
md2_frame_t *pframe2=&mdl->frames[n2];
applyMTL(mdl->texture);
glPushMatrix();
glRotateXi(-(1<<13));
glScalef32(1<<5,1<<5,1<<5);
glTranslate3f32(pframe->translate.x+((pframe2->translate.x-pframe->translate.x)*m)/4,pframe->translate.y+((pframe2->translate.y-pframe->translate.y)*m)/4,pframe->translate.z+((pframe2->translate.z-pframe->translate.z)*m)/4);
glScalef32((pframe->scale.x+((pframe2->scale.x-pframe->scale.x)*m)/4),(pframe->scale.y+((pframe2->scale.y-pframe->scale.y)*m)/4),(pframe->scale.z+((pframe2->scale.z-pframe->scale.z)*m)/4));
glScalef32(inttof32(32),inttof32(32),inttof32(32)); // necessary for v10
glBegin (GL_TRIANGLES);
GFX_COLOR=RGB15(31,31,31);
for (i = 0; i < mdl->header.num_tris; ++i)
{
// if(fakeDotProduct(pframe->faceNormals[i],u)>0)
{
for (j = 0; j < 3; ++j)
{
md2_vertex_t* pvert = &pframe->verts[mdl->triangles[i].vertex[j]];
md2_vertex_t* pvert2 = &pframe2->verts[mdl->triangles[i].vertex[j]];
GFX_TEX_COORD=mdl->packedTexcoords[mdl->triangles[i].st[j]];
// GFX_NORMAL=anorms_table[pframe->verts[mdl->triangles[i].vertex[j]].normalIndex];
vect3D v=vect((pvert->v[0]*2+((pvert2->v[0]-pvert->v[0])*m)/2),(pvert->v[1]*2+((pvert2->v[1]-pvert->v[1])*m)/2),(pvert->v[2]*2+((pvert2->v[2]-pvert->v[2])*m)/2));
GFX_VERTEX10=NORMAL_PACK(v.x,v.y,v.z);
}
}
}
glEnd();
glPopMatrix(1);
}
void initModelInstance(modelInstance_struct* mi, md2Model_struct* mdl)
{
if(!mi || !mdl)return;
mi->currentAnim=0;
mi->interpCounter=0;
mi->currentFrame=0;
mi->nextFrame=0;
mi->model=mdl;
}
void changeAnimation(modelInstance_struct* mi, u16 newAnim, bool oneshot)
{
if(!mi || mi->currentAnim==newAnim)return;
if(!oneshot && mi->oneshot){mi->oldAnim=newAnim;return;}
mi->oneshot=oneshot;
mi->oldAnim=mi->currentAnim;
mi->currentAnim=newAnim;
mi->nextFrame=mi->model->animations[mi->currentAnim].start;
}
void updateAnimation(modelInstance_struct* mi)
{
if(!mi)return;
mi->interpCounter++;
if(mi->interpCounter>=4)
{
mi->interpCounter=0;
mi->currentFrame=mi->nextFrame;
if(mi->currentFrame>=mi->model->animations[mi->currentAnim].end)
{
if(mi->oneshot){mi->currentAnim=mi->oldAnim;mi->oneshot=false;}
mi->nextFrame=mi->model->animations[mi->currentAnim].start;
}else mi->nextFrame++;
}
}

View File

@ -0,0 +1,872 @@
#include "editor/editor_main.h"
//implementation of http://www.drdobbs.com/database/the-maximal-rectangle-problem/184410529
typedef struct pileCell_struct
{
vect2D data;
struct pileCell_struct* next;
}pileCell_struct;
typedef struct
{
pileCell_struct* first;
int num;
}pile_struct;
void initPile(pile_struct* p)
{
p->first=NULL;
p->num=0;
}
void pushPile(vect2D v, pile_struct* p)
{
pileCell_struct* pc=(pileCell_struct*)malloc(sizeof(pileCell_struct));
pc->next=p->first;
pc->data=v;
p->first=pc;
p->num++;
}
vect2D popPile(pile_struct* p)
{
p->num--;
if(p->first)
{
pileCell_struct* pc=p->first;
vect2D v=pc->data;
p->first=pc->next;
free(pc);
return v;
}
return vect2(0,0); //not cool
}
int area(vect2D origin, vect2D corner)
{
if(corner.x<origin.x || corner.y<origin.y)return 0;
return (corner.x-origin.x+1)*(corner.y-origin.y+1);
}
void fillCache(int* c, u8* d, int w, int h, int x)
{
int y;
for(y=0;y<h;y++)
{
if(d[x+y*w])c[y]++;
else c[y]=0;
}
}
int* initCache(int h)
{
int* c=(int*)malloc(sizeof(int)*(h+1));
int i;
for(i=0;i<=h;i++)c[i]=0;
return c;
}
void getMaxRectangle(u8* data, int w, int h, vect2D* pos, vect2D* size)
{
int x;
vect2D originb=vect2(0,0),cornerb=vect2(-1,-1);
pile_struct p;
initPile(&p);
int* c=initCache(h);
for(x=w-1;x>=0;x--)
{
int y, width=0;
fillCache(c,data,w,h,x);
for(y=0;y<=h;y++)
{
if(c[y]>width)
{
pushPile(vect2(y,width),&p);
width=c[y];
}else if(c[y]<width)
{
int y0, w0;
while(1)
{
vect2D v=popPile(&p);
y0=v.x;w0=v.y;
if(width*(y-y0)>area(originb,cornerb))
{
originb=vect2(x,y0);
cornerb=vect2(x+width-1,y-1);
}
width=w0;
if(c[y]>=width)break;
}
width=c[y];
if(width)pushPile(vect2(y0,w0),&p);
}
}
}
if(c)free(c);
*pos=originb;
*size=vect2(cornerb.x-originb.x+1,cornerb.y-originb.y+1);
}
void addEdgeRectangle(roomEdit_struct* re, vect2D* pos, vect2D* size, u8 edge, u8 reverse, int i, int k, int l, int old, material_struct* mat)
{
switch(edge)
{
case 0:
if(reverse)addRoomRectangle(&re->data,&re->entityCollection,(rectangle_struct){vect(i-l,k,pos->y),vect(l,old-k,0)},mat);
else addRoomRectangle(&re->data,&re->entityCollection,(rectangle_struct){vect(i,k,pos->y),vect(-l,old-k,0)},mat);
break;
case 1:
if(reverse)addRoomRectangle(&re->data,&re->entityCollection,(rectangle_struct){vect(i,k,pos->y+size->y),vect(-l,old-k,0)},mat);
else addRoomRectangle(&re->data,&re->entityCollection,(rectangle_struct){vect(i-l,k,pos->y+size->y),vect(l,old-k,0)},mat);
break;
case 2:
if(!reverse)addRoomRectangle(&re->data,&re->entityCollection,(rectangle_struct){vect(pos->x,k,i),vect(0,old-k,-l)},mat);
else addRoomRectangle(&re->data,&re->entityCollection,(rectangle_struct){vect(pos->x,k,i-l),vect(0,old-k,l)},mat);
break;
case 3:
if(!reverse)addRoomRectangle(&re->data,&re->entityCollection,(rectangle_struct){vect(pos->x+size->x,k,i-l),vect(0,old-k,l)},mat);
else addRoomRectangle(&re->data,&re->entityCollection,(rectangle_struct){vect(pos->x+size->x,k,i),vect(0,old-k,-l)},mat);
break;
case 4:
addRoomRectangle(&re->data,&re->entityCollection,(rectangle_struct){vect(i,k,pos->y),vect(-l,old-k,0)},mat);
break;
case 5:
addRoomRectangle(&re->data,&re->entityCollection,(rectangle_struct){vect(i-l,k,pos->y+size->y),vect(l,old-k,0)},mat);
break;
case 6:
addRoomRectangle(&re->data,&re->entityCollection,(rectangle_struct){vect(pos->x,k,i),vect(0,old-k,-l)},mat);
break;
case 7:
addRoomRectangle(&re->data,&re->entityCollection,(rectangle_struct){vect(pos->x+size->x,k,i-l),vect(0,old-k,l)},mat);
break;
}
}
void scanEdge(roomEdit_struct* re, u8* data, int w, int h, vect2D* pos, vect2D* size, u8 edge, u8 reverse, bool ceil)
{
material_struct* mat=re->data.materials[pos->x+pos->y*re->data.width];
switch(edge)
{
case 0: //top
if(pos->y>0)
{
int i;
int l=0;
u8 k=data[pos->x+(pos->y)*w];
u8 old=data[pos->x+(pos->y-1)*w];
for(i=pos->x;i<pos->x+size->x;i++)
{
u8 v=data[i+(pos->y-1)*w];
if(v!=old)
{
//create rectangle
if(l){addEdgeRectangle(re, pos, size, edge, reverse, i, k, l, old, mat);}
l=0;
}
if(ceil){if(v>k)l++;}
else if(v<k)l++;
old=v;
}
if(l){addEdgeRectangle(re, pos, size, edge, reverse, i, k, l, old, mat);}
}
break;
case 1: //bottom
if(pos->y+size->y<h)
{
int i;
int l=0;
u8 k=data[pos->x+(pos->y)*w];
u8 old=data[pos->x+(pos->y+size->y)*w];
for(i=pos->x;i<pos->x+size->x;i++)
{
u8 v=data[i+(pos->y+size->y)*w];
if(v!=old)
{
//create rectangle
if(l){addEdgeRectangle(re, pos, size, edge, reverse, i, k, l, old, mat);}
l=0;
}
if(ceil){if(v>k)l++;}
else if(v<k)l++;
old=v;
}
if(l){addEdgeRectangle(re, pos, size, edge, reverse, i, k, l, old, mat);}
}
break;
case 2: //left
if(pos->x>0)
{
int i;
int l=0;
u8 k=data[(pos->x)+(pos->y)*w];
u8 old=data[pos->x-1+(pos->y)*w];
for(i=pos->y;i<pos->y+size->y;i++)
{
u8 v=data[(pos->x-1)+(i)*w];
if(v!=old)
{
//create rectangle
if(l){addEdgeRectangle(re, pos, size, edge, reverse, i, k, l, old, mat);}
l=0;
}
if(ceil){if(v>k)l++;}
else if(v<k)l++;
old=v;
}
if(l){addEdgeRectangle(re, pos, size, edge, reverse, i, k, l, old, mat);}
}
break;
case 3: //right
if(pos->x+size->x<w)
{
int i;
int l=0;
u8 k=data[(pos->x)+(pos->y)*w];
u8 old=data[pos->x+size->x+(pos->y)*w];
for(i=pos->y;i<pos->y+size->y;i++)
{
u8 v=data[(pos->x+size->x)+(i)*w];
if(v!=old)
{
//create rectangle
if(l){addEdgeRectangle(re, pos, size, edge, reverse, i, k, l, old, mat);}
l=0;
}
if(ceil){if(v>k)l++;}
else if(v<k)l++;
old=v;
}
if(l){addEdgeRectangle(re, pos, size, edge, reverse, i, k, l, old, mat);}
}
break;
}
}
static inline u8 getVEdgeWall(roomEdit_struct* re, int w, u8* ceiling, int i, int j, u8* hh)
{
u8 v=ceiling[i+j*w];
door_struct* d;
if((d=doorTouches(NULL, re, i, j, false))){v+=MAXHEIGHT;(*hh)=d->height;}
else if((d=doorTouches(NULL, re, i, j, true))){v+=MAXHEIGHT;(*hh)=d->height;}
return v;
}
// static inline void addEdgeRectangleWall(re, pos, size, edge, hh, old, l, i, k)
static inline void addEdgeRectangleWall(roomEdit_struct* re, vect2D* pos, vect2D* size, u8 edge, u8 hh, u8 old, int l, int i, u8 k)
{
if(old>MAXHEIGHT){addEdgeRectangle(re, pos, size, edge+4, 0, i, 12+hh, l, old-MAXHEIGHT, NULL);addEdgeRectangle(re, pos, size, edge+4, 0, i, k, l, hh, NULL);}
else addEdgeRectangle(re, pos, size, edge+4, 0, i, k, l, old, NULL);
}
void scanEdgeWall(roomEdit_struct* re, u8* floor, u8* ceiling, int w, int h, vect2D* pos, vect2D* size, u8 edge)
{
u8 hh=0;
switch(edge)
{
case 0: //top
{
if(pos->y==0)
{
int i;
int l=0;
u8 k=floor[pos->x+(pos->y)*w];
u8 old=getVEdgeWall(re, w, ceiling, pos->x, pos->y, &hh);
for(i=pos->x;i<pos->x+size->x;i++)
{
u8 v=getVEdgeWall(re, w, ceiling, i, pos->y, &hh);
if(v!=old)
{
//create rectangle
if(l)addEdgeRectangleWall(re, pos, size, edge, hh, old, l, i, k);
l=0;
}
l++;
old=v;
NOGBA("%d,%d,%d,%d",l,v,k,old);
}
if(l)addEdgeRectangleWall(re, pos, size, edge, hh, old, l, i, k);
}
}
break;
case 1: //top
{
if(pos->y+size->y==h)
{
int i;
int l=0;
u8 k=floor[pos->x+(pos->y+size->y-1)*w];
u8 old=getVEdgeWall(re, w, ceiling, pos->x, pos->y+size->y-1, &hh);
for(i=pos->x;i<pos->x+size->x;i++)
{
u8 v=getVEdgeWall(re, w, ceiling, i, (pos->y+size->y-1), &hh);
if(v!=old)
{
//create rectangle
if(l)addEdgeRectangleWall(re, pos, size, edge, hh, old, l, i, k);
l=0;
}
l++;
old=v;
}
if(l)addEdgeRectangleWall(re, pos, size, edge, hh, old, l, i, k);
}
}
break;
case 2: //left
{
if(pos->x==0)
{
int i;
int l=0;
u8 k=floor[pos->x+(pos->y)*w];
u8 old=getVEdgeWall(re, w, ceiling, pos->x, pos->y, &hh);
for(i=pos->y;i<pos->y+size->y;i++)
{
u8 v=getVEdgeWall(re, w, ceiling, pos->x, i, &hh);
if(v!=old)
{
//create rectangle
if(l)addEdgeRectangleWall(re, pos, size, edge, hh, old, l, i, k);
l=0;
}
l++;
old=v;
}
if(l)addEdgeRectangleWall(re, pos, size, edge, hh, old, l, i, k);
}
}
break;
case 3: //right
{
if(pos->x+size->x==w)
{
int i;
int l=0;
u8 k=floor[pos->x+size->x-1+(pos->y)*w];
u8 old=getVEdgeWall(re, w, ceiling, pos->x+size->x-1, pos->y, &hh);
for(i=pos->y;i<pos->y+size->y;i++)
{
u8 v=getVEdgeWall(re, w, ceiling, pos->x+size->x-1, i, &hh);
if(v!=old)
{
//create rectangle
if(l)addEdgeRectangleWall(re, pos, size, edge, hh, old, l, i, k);
l=0;
}
l++;
old=v;
}
if(l)addEdgeRectangleWall(re, pos, size, edge, hh, old, l, i, k);
}
}
break;
}
}
void scanEdgeInnerWall(roomEdit_struct* re, u8* floor, u8* ceiling, int w, int h, vect2D* pos, vect2D* size, u8 edge)
{
switch(edge)
{
case 0: //top
if(pos->y>0)
{
int i;
int l=0;
u8 k=floor[pos->x+(pos->y)*w];
u8 old=ceiling[pos->x+(pos->y)*w];
for(i=pos->x;i<pos->x+size->x;i++)
{
u8 v=ceiling[i+(pos->y)*w];
if(floor[i+(pos->y-1)*w]>=ceiling[i+(pos->y-1)*w])
{
if(v!=old)
{
//create rectangle
if(l){addEdgeRectangle(re, pos, size, edge+4, 0, i, k, l, old, NULL);}
l=0;
}
l++;
}else if(l){addEdgeRectangle(re, pos, size, edge+4, 0, i, k, l, old, NULL);l=0;}
old=v;
}
if(l){addEdgeRectangle(re, pos, size, edge+4, 0, i, k, l, old, NULL);}
}
break;
case 1: //bottom
if(pos->y+size->y<h)
{
int i;
int l=0;
u8 k=floor[pos->x+(pos->y+size->y-1)*w];
u8 old=ceiling[pos->x+(pos->y+size->y-1)*w];
for(i=pos->x;i<pos->x+size->x;i++)
{
u8 v=ceiling[i+(pos->y+size->y-1)*w];
if(floor[i+(pos->y+size->y)*w]>=ceiling[i+(pos->y+size->y)*w])
{
if(v!=old)
{
//create rectangle
if(l){addEdgeRectangle(re, pos, size, edge+4, 0, i, k, l, old, NULL);}
l=0;
}
l++;
}else if(l){addEdgeRectangle(re, pos, size, edge+4, 0, i, k, l, old, NULL);l=0;}
old=v;
}
if(l){addEdgeRectangle(re, pos, size, edge+4, 0, i, k, l, old, NULL);}
}
break;
case 2: //left
if(pos->x>0)
{
int i;
int l=0;
u8 k=floor[pos->x+(pos->y)*w];
u8 old=ceiling[pos->x+(pos->y)*w];
for(i=pos->y;i<pos->y+size->y;i++)
{
u8 v=ceiling[pos->x+(i)*w];
if(floor[pos->x-1+(i)*w]>=ceiling[pos->x-1+(i)*w])
{
if(v!=old)
{
//create rectangle
if(l){addEdgeRectangle(re, pos, size, edge+4, 0, i, k, l, old, NULL);}
l=0;
}
l++;
}else if(l){addEdgeRectangle(re, pos, size, edge+4, 0, i, k, l, old, NULL);l=0;}
old=v;
}
if(l){addEdgeRectangle(re, pos, size, edge+4, 0, i, k, l, old, NULL);}
}
break;
case 3: //bottom
if(pos->x+size->x<w)
{
int i;
int l=0;
u8 k=floor[(pos->x+size->x-1)+pos->x*w];
u8 old=ceiling[(pos->x+size->x-1)+pos->x*w];
for(i=pos->y;i<pos->y+size->y;i++)
{
u8 v=ceiling[(pos->x+size->x-1)+i*w];
if(floor[(pos->x+size->x)+i*w]>=ceiling[(pos->x+size->x)+i*w])
{
if(v!=old)
{
//create rectangle
if(l){addEdgeRectangle(re, pos, size, edge+4, 0, i, k, l, old, NULL);}
l=0;
}
l++;
}else if(l){addEdgeRectangle(re, pos, size, edge+4, 0, i, k, l, old, NULL);l=0;}
old=v;
}
if(l){addEdgeRectangle(re, pos, size, edge+4, 0, i, k, l, old, NULL);}
}
break;
}
}
void fillRectangle(u8* data, int w, int h, vect2D* pos, vect2D* size)
{
int i;
for(i=pos->x;i<pos->x+size->x;i++)
{
int j;
for(j=pos->y;j<pos->y+size->y;j++)
{
data[i+j*w]=0;
}
}
}
bool collideLineRectangle(rectangle_struct* rec, vect3D o, vect3D v, int32 d, int32* kk, vect3D* ip)
{
int32 p1=dotProduct(v,rec->normal);
if(!equals(p1,0))
{
vect3D p=convertVect(rec->position); //CHECK lightmap generation ?
vect3D s=vect(rec->size.x*TILESIZE*2,rec->size.y*HEIGHTUNIT,rec->size.z*TILESIZE*2);
int32 p2=dotProduct(vectDifference(p,o),rec->normal);
int32 k=divf32(p2,p1);
if(kk)*kk=k;
if(k<0 || k>d){return false;}
vect3D i=addVect(o,vectMult(v,k));
if(ip)*ip=i;
// NOGBA("ip : %d %d %d",i.x,i.y,i.z);
i=vectDifference(i,p);
bool r=true;
if(s.x)
{
if(s.x>0)r=r&&i.x<s.x&&i.x>=0;
else r=r&&i.x>s.x&&i.x<=0;
}
if(s.y)
{
if(s.y>0)r=r&&i.y<s.y&&i.y>=0;
else r=r&&i.y>s.y&&i.y<=0;
}
if(s.z)
{
if(s.z>0)r=r&&i.z<s.z&&i.z>=0;
else r=r&&i.z>s.z&&i.z<=0;
}
return r;
}
return false;
}
vect3D getClosestPointRectangle(rectangle_struct* rec, vect3D o)
{
vect3D p=vect(rec->position.x*TILESIZE*2,rec->position.y*HEIGHTUNIT,rec->position.z*TILESIZE*2);
vect3D s=vect(rec->size.x*TILESIZE*2,rec->size.y*HEIGHTUNIT,rec->size.z*TILESIZE*2);
vect3D u1, u2;
int32 x,y,sx,sy;
// NOGBA("p: %d %d %d",p.x,p.y,p.z);
// NOGBA("o: %d %d %d",o.x,o.y,o.z);
if(s.x){sx=abs(s.x);u1=vect((s.x>0)?inttof32(1):(-inttof32(1)),0,0);}
else{sx=abs(s.y);u1=vect(0,(s.y>0)?inttof32(1):(-inttof32(1)),0);}
if(s.z){sy=abs(s.z);u2=vect(0,0,(s.z>0)?inttof32(1):(-inttof32(1)));}
else{sy=abs(s.y);u2=vect(0,(s.y>0)?inttof32(1):(-inttof32(1)),0);}
o=vectDifference(o,p);
x=dotProduct(o,u1);y=dotProduct(o,u2);
// NOGBA("x, y: %d %d",x,y);
// NOGBA("sx, sy: %d %d",sx,sy);
bool r=true;
r=r&&x<sx&&x>=0;
r=r&&y<sy&&y>=0;
if(r)return addVect(p,vect(mulf32(x,u1.x)+mulf32(y,u2.x), mulf32(x,u1.y)+mulf32(y,u2.y), mulf32(x,u1.z)+mulf32(y,u2.z)));
if(x<0)
{
x=0;
if(y<0)y=0;
else if(y>sy)y=sy;
}else if(x>sx)
{
x=sx;
if(y<0)y=0;
else if(y>sy)y=sy;
}else if(y<0)
{
y=0;
if(x<0)x=0;
else if(x>sx)y=sx;
}else if(y>sy)
{
y=sy;
if(x<0)x=0;
else if(x>sx)x=sx;
}
return addVect(p,vect(mulf32(x,u1.x)+mulf32(y,u2.x), mulf32(x,u1.y)+mulf32(y,u2.y), mulf32(x,u1.z)+mulf32(y,u2.z)));
}
int area2D(rectangle2D_struct rec)
{
return (rec.size.x*rec.size.y);
}
void initRectangle2DList(rectangle2DList_struct* l)
{
l->first=NULL;
l->surface=0;
l->num=0;
}
listCell2D_struct* createListCell()
{
listCell2D_struct* lc=(listCell2D_struct*)malloc(sizeof(listCell2D_struct));
lc->next=NULL;
return lc;
}
void insertRectangle2DList(rectangle2DList_struct* l, rectangle2D_struct rec)
{
int a=rec.size.x*rec.size.y;
listCell2D_struct* n=createListCell();
n->data=rec;
listCell2D_struct** plcn=&l->first;
listCell2D_struct* lc=l->first;
l->num++;
l->surface+=a;
while(lc)
{
int a2=lc->data.size.x*lc->data.size.y;
if(a>a2)
{
*plcn=n;
n->next=lc;
return;
}
plcn=&lc->next;
lc=lc->next;
}
*plcn=n;
n->next=NULL;
}
void freeRectangle2DList(rectangle2DList_struct* l)
{
listCell2D_struct* lc=l->first;
listCell2D_struct* lcn=lc->next;
while(lc)
{
lcn=lc->next;
free(lc);
lc=lcn;
}
l->first=NULL;
}
void initTreeNode(treeNode_struct* tn)
{
tn->son[0]=tn->son[1]=NULL;
tn->type=EMPTY;
tn->data=0;
}
treeNode_struct* createNode()
{
treeNode_struct* tn=(treeNode_struct*)malloc(sizeof(treeNode_struct));
initTreeNode(tn);
return tn;
}
void initTree(tree_struct* t, short w, short h)
{
t->root=createNode();
t->width=w;
t->height=h;
}
void freeTreeBranch(treeNode_struct* tn)
{
if(tn)
{
freeTreeBranch(tn->son[0]);
freeTreeBranch(tn->son[1]);
free(tn);
}
}
void freeTree(tree_struct* t)
{
if(t)
{
freeTreeBranch(t->root);
}
t->root=NULL;
}
bool insertRectangle(treeNode_struct* tn, rectangle2D_struct* rec, short w, short h, short x, short y, int a)
{
bool r;
if(a>w*h)return false;
// NOGBA("%d %d %d %d",x,y,w,h);
switch(tn->type)
{
case EMPTY:
if((rec->size.x<=w && rec->size.y<=h) || (rec->size.y<=w && rec->size.x<=h))
{
// NOGBA("empty");
if(!(rec->size.x<=w && rec->size.y<=h))
{
//SUPERROTATIOOOON
int z=rec->size.x;
rec->size.x=rec->size.y;
rec->size.y=z;
rec->rot=true;
}else rec->rot=false;
if(rec->size.x>=rec->size.y)
{
tn->type=VERTICAL;
tn->data=rec->size.x;
tn->son[0]=createNode();
tn->son[0]->type=HORIZONTAL;
tn->son[0]->data=rec->size.y;
tn->son[0]->son[0]=createNode();
tn->son[0]->son[0]->type=RECTANGLE;
tn->son[0]->son[1]=createNode();
tn->son[1]=createNode();
}else{
tn->type=HORIZONTAL;
tn->data=rec->size.y;
tn->son[0]=createNode();
tn->son[0]->type=VERTICAL;
tn->son[0]->data=rec->size.x;
tn->son[0]->son[0]=createNode();
tn->son[0]->son[0]->type=RECTANGLE;
tn->son[0]->son[1]=createNode();
tn->son[1]=createNode();
}
rec->position.x=x;
rec->position.y=y;
return true;
}
break;
case VERTICAL:
// NOGBA("vertical %d", tn->data);
r=insertRectangle(tn->son[0], rec, tn->data, h, x, y, a);
if(!r)r=insertRectangle(tn->son[1], rec, w-tn->data, h, x+tn->data, y, a);
return r;
break;
case HORIZONTAL:
// NOGBA("horizontal %d", tn->data);
r=insertRectangle(tn->son[0], rec, w, tn->data, x, y, a);
if(!r)r=insertRectangle(tn->son[1], rec, w, h-tn->data, x, y+tn->data, a);
return r;
break;
case RECTANGLE:
// NOGBA("rectangle");
return false;
break;
}
return false;
}
bool insertRectangles(tree_struct* t, rectangle2DList_struct* l)
{
listCell2D_struct*lc=l->first;
bool rr=true;
while(lc)
{
bool r=insertRectangle(t->root, &lc->data, t->width, t->height, 0, 0, area2D(lc->data));
NOGBA("r : %d",(int)r);
if(r)
{
lc->data.real->lmPos.x=lc->data.position.x;
lc->data.real->lmPos.y=lc->data.position.y;
lc->data.real->rot=lc->data.rot;
NOGBA("pos %p %d %d %d %d (%d)",lc->data.real,lc->data.real->lmPos.x,lc->data.real->lmPos.y,lc->data.size.x,lc->data.size.y,lc->data.rot);
}else rr=false;
lc=lc->next;
}
return rr;
}
void unrotateRectangles(rectangle2DList_struct* l)
{
if(!l)return;
listCell2D_struct*lc=l->first;
while(lc)
{
rectangle2D_struct* rec=&lc->data;
if(rec->rot)
{
int z=rec->size.x;
rec->size.x=rec->size.y;
rec->size.y=z;
rec->rot=false;
rec->real->rot=false;
}
lc=lc->next;
}
}
void packRectangles(rectangle2DList_struct* l, short w, short h)
{
tree_struct t;
initTree(&t,w,h);
insertRectangles(&t,l);
freeTree(&t);
}
bool packRectanglesSize(rectangle2DList_struct* l, short* w, short* h)
{
tree_struct t;
bool tr=true;
bool rr=true;
*w=32;
*h=32;
while(rr && *w<=512 && *h<=256)
{
if(l->surface<=(*w)*(*h))
{
NOGBA("doing : %d %d",(*w),(*h));
initTree(&t,*w,*h);
bool r=insertRectangles(&t,l);
freeTree(&t);
if(r){rr=false;break;}
unrotateRectangles(l);
}
if(tr)(*w)*=2;
else (*h)*=2;
tr^=1;
}
NOGBA("surface : %d <= %d",l->surface,(*w)*(*h));
return !rr;
}
int32 pointSegmentDistanceAbs(vect3D o, vect3D p, vect3D v)
{
if(v.x)
{
int32 k=o.x-p.x;
if(k<0)k=p.x;
else if(k>v.x)k=p.x+v.x;
else k=o.x;
return ((k-o.x)*(k-o.x)+(o.y-p.y)*(o.y-p.y)+(o.z-p.z)*(o.z-p.z));
}else if(v.y)
{
int32 k=o.y-p.y;
if(k<0)k=p.y;
else if(k>v.y)k=p.y+v.y;
else k=o.y;
return ((k-o.y)*(k-o.y)+(o.x-p.x)*(o.x-p.x)+(o.z-p.z)*(o.z-p.z));
}else if(v.z)
{
int32 k=o.z-p.z;
if(k<0)k=p.z;
else if(k>v.z)k=p.z+v.z;
else k=o.z;
return ((k-o.z)*(k-o.z)+(o.y-p.y)*(o.y-p.y)+(o.x-p.x)*(o.x-p.x));
}
return 0;
}
int32 pointSegmentDistance(vect3D o, vect3D p, vect3D v)
{
if(v.x>=0 && v.y>=0 && v.z>=0)return pointSegmentDistanceAbs(o, p, v);
else return pointSegmentDistanceAbs(o, addVect(p,v), vectMultInt(v,-1));
}
int32 pointRectangleDistance(vect3D o, rectangle_struct* rec)
{
if(!rec->size.x)
{
int32 d1=pointSegmentDistance(o, rec->position, vect(0,rec->size.y,0));
int32 d2=pointSegmentDistance(o, rec->position, vect(0,0,rec->size.z));
int32 d3=pointSegmentDistance(o, addVect(rec->position,vect(0,0,rec->size.z)), vect(0,rec->size.y,0));
int32 d4=pointSegmentDistance(o, addVect(rec->position,vect(0,rec->size.y,0)), vect(0,0,rec->size.z));
return min(d1,min(d2,min(d3,d4)));
}else if(!rec->size.y)
{
int32 d1=pointSegmentDistance(o, rec->position, vect(rec->size.x,0,0));
int32 d2=pointSegmentDistance(o, rec->position, vect(0,0,rec->size.z));
int32 d3=pointSegmentDistance(o, addVect(rec->position,vect(0,0,rec->size.z)), vect(rec->size.x,0,0));
int32 d4=pointSegmentDistance(o, addVect(rec->position,vect(rec->size.x,0,0)), vect(0,0,rec->size.z));
return min(d1,min(d2,min(d3,d4)));
}else{
int32 d1=pointSegmentDistance(o, rec->position, vect(rec->size.x,0,0));
int32 d2=pointSegmentDistance(o, rec->position, vect(0,rec->size.y,0));
int32 d3=pointSegmentDistance(o, addVect(rec->position,vect(0,rec->size.y,0)), vect(rec->size.x,0,0));
int32 d4=pointSegmentDistance(o, addVect(rec->position,vect(rec->size.x,0,0)), vect(0,rec->size.y,0));
return min(d1,min(d2,min(d3,d4)));
}
}

1235
arm9/source/editor/room.c Normal file

File diff suppressed because it is too large Load Diff

99
arm9/source/files.c Normal file
View File

@ -0,0 +1,99 @@
#include "common/general.h"
#include <errno.h>
bool saveAvailable;
char* basePath;
int lastSize;
u8 fsMode;
u32 getFileSize(FILE *file) {
fseek(file, 0, SEEK_END);
return ftell(file);
}
bool initFilesystem(int argc, char **argv)
{
#ifndef FATONLY
if(nitroFSInit(&basePath))
{
printf("init : done");
chdir("nitro:/");
chdir(ROOT);
if(!argv){saveAvailable=false;fsMode=1;} // no fat but nitro (gba slot)
else{
fsMode=2; // nitro and fat
saveAvailable=true;
chdir(basePath);
int r=mkdir("fpsm", S_IRWXU|S_IRGRP|S_IXGRP);//!ROOT!
if(r!=0 && errno!=EEXIST)saveAvailable=false;
r=mkdir("fpsm/maps", S_IRWXU|S_IRGRP|S_IXGRP);
if(r!=0 && errno!=EEXIST)saveAvailable=false;
r=mkdir("fpsm/screens", S_IRWXU|S_IRGRP|S_IXGRP);
if(r!=0 && errno!=EEXIST)saveAvailable=false;
NOGBA("can save : %d",saveAvailable);
chdir("nitro:/");
chdir(ROOT);
}
return true;
}
#endif
fsMode=3; // fat only ?
saveAvailable=false;
if(!fatInitDefault())return false;
saveAvailable=true;
int r=mkdir("fpsm", S_IRWXU|S_IRGRP|S_IXGRP);//!ROOT!
if(r!=0 && errno!=EEXIST)saveAvailable=false;
r=mkdir("fpsm/maps", S_IRWXU|S_IRGRP|S_IXGRP);
if(r!=0 && errno!=EEXIST)saveAvailable=false;
r=mkdir("fpsm/screens", S_IRWXU|S_IRGRP|S_IXGRP);
if(r!=0 && errno!=EEXIST)saveAvailable=false;
// chdir("sd:/");
basePath=malloc(255);
getcwd(basePath,255);
chdir(ROOT);
return true;
}
void* bufferizeFile(char* filename, char* dir, bool binary)
{
char path[255];getcwd(path,255);
/*int r=*/chdir(dir);
//if(strlen(dir)<=0)r=-1;
FILE* file;
NOGBA("opening %s...",filename);
if(!binary)file = fopen(filename, "r+");
else file = fopen(filename, "rb+");
NOGBA("done.");
if(!file){chdir(path);return NULL;}
u8* buffer;
long lsize;
fseek (file, 0 , SEEK_END);
lsize = ftell (file);
rewind (file);
buffer=(u8*)malloc(lsize);
lastSize=lsize;
if(!buffer){fclose(file);chdir(path);return NULL;}
fread(buffer, 1, lsize, file);
fclose(file);
chdir(path);
return buffer;
}
bool fileExists(char* filename, char* dir)
{
char path[255];getcwd(path,255);
NOGBA(path);
chdir(dir);
FILE* file;
file=fopen(filename, "r+");
if(!file){chdir(path);return false;}
chdir(path);
fclose (file);
return true;
}

125
arm9/source/font.c Normal file
View File

@ -0,0 +1,125 @@
#include "common/general.h"
#define t1 NORMAL_PACK(-32,-32,0)
#define t2 NORMAL_PACK(-32,32,0)
#define t3 NORMAL_PACK(32,32,0)
#define t4 NORMAL_PACK(32,-32,0)
font_struct hudFont;
font_struct* currentFont;
void initText(void)
{
loadFont(&hudFont,16);
}
void setFont(font_struct* f)
{
currentFont=f;
}
void loadFont(font_struct* f, u8 charsize)
{
int i, j;
int param;
uint8 texX, texy;
u8 buffer[512*64/4];
sImage pcx;
u8 *buffer2;
u16 palette[4];
buffer2=bufferizeFile("HUD.pcx", "font", true);
if(!buffer2)return;
loadPCX((u8*)buffer2, &pcx);
palette[0]=RGB15(31,0,31);
palette[1]=RGB15(31,31,31);
palette[2]=RGB15(0,0,0);
palette[3]=RGB15(0,0,0);
for(j=0;j<64;j++)
{
for(i=0;i<512/4;i++)
{
buffer[i+j*512/4]=(pcx.image.data8[i*4+j*512])|((pcx.image.data8[i*4+1+j*512])<<2)|((pcx.image.data8[i*4+2+j*512])<<4)|((pcx.image.data8[i*4+3+j*512])<<6);
}
}
imageDestroy(&pcx);
free(buffer2);
f->tex.used=true;
f->tex.width=512;
f->tex.height=64;
f->tex.size=f->tex.width*f->tex.height/4;
addPaletteToBank(&f->tex, palette, 8*2);
param = TEXGEN_TEXCOORD | GL_TEXTURE_WRAP_S | GL_TEXTURE_WRAP_T | (1<<29);
getTextureAddress(&f->tex);
getGlWL(f->tex.width, f->tex.height, &texX, &texy);
setTextureParameter(&f->tex, texX, texy, f->tex.addr, GL_RGB4, param);
addToBank(&f->tex, buffer, f->tex.bank);
f->charsize=charsize;
f->charsizef32=inttof32(charsize);
setFont(f);
}
void drawChar(char c, u16 color, int32 x, int32 y)
{
c-=32;
int tx=(c*16)%512;
int ty=16*(c*16-tx)/512;
glPushMatrix();
glColor(color);
bindTexture(&currentFont->tex);
bindPalette4(&currentFont->tex);
glPolyFmt(POLY_ALPHA(31) | POLY_CULL_BACK | POLY_ID(63));
glTranslatef32(x, y, 0);
glScalef32((currentFont->charsizef32),(currentFont->charsizef32),inttof32(1));
glBegin(GL_QUADS);
GFX_TEX_COORD = TEXTURE_PACK(inttot16(tx), inttot16(ty));
GFX_VERTEX10 = t1;
GFX_TEX_COORD = TEXTURE_PACK(inttot16(tx), inttot16(ty+16));
GFX_VERTEX10 = t2;
GFX_TEX_COORD = TEXTURE_PACK(inttot16(tx+16), inttot16(ty+16));
GFX_VERTEX10 = t3;
GFX_TEX_COORD = TEXTURE_PACK(inttot16(tx+16), inttot16(ty));
GFX_VERTEX10 = t4;
glEnd();
glPolyFmt(POLY_ALPHA(31) | POLY_CULL_BACK);
glPopMatrix(1);
}
void drawString(char* s, u16 color, int32 size, int32 x, int32 y)
{
int n=strlen(s);
int i;
glPushMatrix();
glTranslatef32(x, y, 0);
glScalef32(size, size,inttof32(1));
for(i=0;i<n;i++)
{
drawChar(s[i], color, i*inttof32(8), 0);
}
glPopMatrix(1);
unbindMtl();
}

465
arm9/source/game/camera.c Normal file
View File

@ -0,0 +1,465 @@
#include "game/game_main.h"
#define mcoord(i,j) ((i)+(j)*4)
camera_struct playerCamera;
//repurposed from libnds
void initProjectionMatrix(camera_struct* c, int fovy, int32 aspect, int32 near, int32 far)
{
if(!c)c=&playerCamera;
int32* m=c->projectionMatrix;
int32 right, left, top, bottom;
top = mulf32(near, tanLerp(fovy>>1));
bottom = -top;
left = mulf32(bottom, aspect);
right = mulf32(top, aspect);
*(m++) = divf32(2*near, right - left);
*(m++) = 0;
*(m++) = 0;
*(m++) = 0;
*(m++) = 0;
*(m++) = divf32(2*near, top - bottom);
*(m++) = 0;
*(m++) = 0;
*(m++) = divf32(right + left, right - left);
*(m++) = divf32(top + bottom, top - bottom);
*(m++) = -divf32(far + near, far - near);
*(m++) = inttof32(-1);
*(m++) = 0;
*(m++) = 0;
*(m++) = -divf32(2 * mulf32(far, near), far - near);
*(m++) = 0;
// m[0] = divf32(2*near, right - left);
// m[4] = 0;
// m[8] = 0;
// m[12] = 0;
// m[1] = 0;
// m[5] = divf32(2*near, top - bottom);
// m[9] = 0;
// m[13] = 0;
// m[2] = divf32(right + left, right - left);
// m[6] = divf32(top + bottom, top - bottom);
// m[10] = -divf32(far + near, far - near);
// m[14] = inttof32(-1);
// m[3] = 0;
// m[7] = 0;
// m[11] = -divf32(2 * mulf32(far, near), far - near);
// m[15] = 0;
}
void initTransformationMatrix(camera_struct* c)
{
if(!c)c=&playerCamera;
int32* m=c->transformationMatrix;
*(m++)=inttof32(1);
*(m++)=0;
*(m++)=0;
*(m++)=0;
*(m++)=inttof32(1);
*(m++)=0;
*(m++)=0;
*(m++)=0;
*(m)=inttof32(1);
}
void updateViewMatrix(camera_struct* c)
{
int i, j;
if(!c)c=&playerCamera;
int32* m1=c->projectionMatrix;
int32 m2[4*4];
const int fact=f32toint(SCALEFACT);
for(i=0;i<3;i++)for(j=0;j<3;j++)m2[i+j*4]=c->transformationMatrix[i+j*3]*fact;
m2[3+0*4]=0;
m2[3+1*4]=0;
m2[3+2*4]=0;
// m2[0+3*4]=-c->position.x*fact;
// m2[1+3*4]=-c->position.y*fact;
// m2[2+3*4]=-c->position.z*fact;
m2[0+3*4]=0;
m2[1+3*4]=0;
m2[2+3*4]=0;
m2[3+3*4]=inttof32(1);
translateMatrix(m2,-c->position.x,-c->position.y,-c->position.z);
multMatrix44(m2,m1,c->viewMatrix);
}
void multTransformationMatrix(camera_struct* c)
{
if(!c)c=&playerCamera;
int32* m=c->transformationMatrix;
MATRIX_MULT3x3=*(m++);
MATRIX_MULT3x3=*(m++);
MATRIX_MULT3x3=*(m++);
MATRIX_MULT3x3=*(m++);
MATRIX_MULT3x3=*(m++);
MATRIX_MULT3x3=*(m++);
MATRIX_MULT3x3=*(m++);
MATRIX_MULT3x3=*(m++);
MATRIX_MULT3x3=*m;
}
void multProjectionMatrix(camera_struct* c)
{
if(!c)c=&playerCamera;
int32* m=c->projectionMatrix;
MATRIX_MULT4x4=*(m++);
MATRIX_MULT4x4=*(m++);
MATRIX_MULT4x4=*(m++);
MATRIX_MULT4x4=*(m++);
MATRIX_MULT4x4=*(m++);
MATRIX_MULT4x4=*(m++);
MATRIX_MULT4x4=*(m++);
MATRIX_MULT4x4=*(m++);
MATRIX_MULT4x4=*(m++);
MATRIX_MULT4x4=*(m++);
MATRIX_MULT4x4=*(m++);
MATRIX_MULT4x4=*(m++);
MATRIX_MULT4x4=*(m++);
MATRIX_MULT4x4=*(m++);
MATRIX_MULT4x4=*(m++);
MATRIX_MULT4x4=*m;
}
static inline void projectVectorPlane(vect3D* v, vect3D n)
{
if(!v)return;
int32 r=dotProduct(*v,n);
*v=vectDifference(*v,vectMult(n,r));
}
void fixMatrix(int32* m) //3x3
{
if(!m)return;
vect3D x=vect(m[0],m[3],m[6]);
vect3D y=vect(m[1],m[4],m[7]);
vect3D z=vect(m[2],m[5],m[8]);
projectVectorPlane(&x,y);
projectVectorPlane(&z,y);
projectVectorPlane(&z,x);
x=normalize(x);
y=normalize(y);
z=normalize(z);
m[0]=x.x;m[3]=x.y;m[6]=x.z;
m[1]=y.x;m[4]=y.y;m[7]=y.z;
m[2]=z.x;m[5]=z.y;m[8]=z.z;
}
void multMatrix33(int32* m1, int32* m2, int32* m) //3x3
{
int i, j;
// for(i=0;i<4;i++)for(j=0;j<4;j++)m[i+j*4]=m1[i+0*4]*m2[0+j*4]+m1[i+1*4]*m2[1+j*4]+m1[i+2*4]*m2[2+j*4]+m1[i+3*4]*m2[3+j*4];
for(i=0;i<3;i++)for(j=0;j<3;j++)m[j+i*3]=mulf32(m1[0+i*3],m2[j+0*3])+mulf32(m1[1+i*3],m2[j+1*3])+mulf32(m1[2+i*3],m2[j+2*3]);
}
void multMatrix44(int32* m1, int32* m2, int32* m) //4x4
{
int i, j;
// for(i=0;i<4;i++)for(j=0;j<4;j++)m[i+j*4]=mulf32(m1[0+j*4],m2[i+0*4])+mulf32(m1[1+j*4],m2[i+1*4])+mulf32(m1[2+j*4],m2[i+2*4])+mulf32(m1[3+j*4],m2[i+3*4]);
for(i=0;i<4;i++)for(j=0;j<4;j++)m[i+j*4]=mulf32(m1[0+j*4],m2[i+0*4])+mulf32(m1[1+j*4],m2[i+1*4])+mulf32(m1[2+j*4],m2[i+2*4])+mulf32(m1[3+j*4],m2[i+3*4]);
}
void changeBase(int32* tm, vect3D x, vect3D y, vect3D z, bool r)
{
int32 m[9], bcm[9];
bcm[0]=x.x;bcm[1]=y.x;bcm[2]=z.x;
bcm[3]=x.y;bcm[4]=y.y;bcm[5]=z.y;
bcm[6]=x.z;bcm[7]=y.z;bcm[8]=z.z;
// NOGBA("MATRIX");
// NOGBA("%d %d %d",bcm[0],bcm[1],bcm[2]);
// NOGBA("%d %d %d",bcm[0+3],bcm[1+3],bcm[2+3]);
// NOGBA("%d %d %d",bcm[0+3+3],bcm[1+3+3],bcm[2+3+3]);
if(r)multMatrix33(tm,bcm,m);
else multMatrix33(bcm,tm,m);
memcpy(tm,m,9*sizeof(int32));
}
void rotateMatrixX(int32* tm, int32 x, bool r)
{
int i;
int32 rm[9], m[9];
for(i=0;i<9;i++)rm[i]=0;
rm[0]=inttof32(1);
rm[4]=cosLerp(x);
rm[5]=sinLerp(x);
rm[7]=-sinLerp(x);
rm[8]=cosLerp(x);
if(r)multMatrix33(rm,tm,m);
else multMatrix33(tm,rm,m);
memcpy(tm,m,9*sizeof(int32));
}
void rotateMatrixY(int32* tm, int32 x, bool r)
{
int i;
int32 rm[9], m[16];
for(i=0;i<9;i++)rm[i]=0;
rm[0]=cosLerp(x);
rm[2]=sinLerp(x);
rm[4]=inttof32(1);
rm[6]=-sinLerp(x);
rm[8]=cosLerp(x);
if(r)multMatrix33(rm,tm,m);
else multMatrix33(tm,rm,m);
memcpy(tm,m,9*sizeof(int32));
}
void rotateMatrixZ(int32* tm, int32 x, bool r)
{
int i;
int32 rm[9], m[16];
for(i=0;i<9;i++)rm[i]=0;
rm[0]=cosLerp(x);
rm[1]=sinLerp(x);
rm[3]=-sinLerp(x);
rm[4]=cosLerp(x);
rm[8]=inttof32(1);
if(r)multMatrix33(rm,tm,m);
else multMatrix33(tm,rm,m);
memcpy(tm,m,9*sizeof(int32));
}
void translateMatrix(int32* tm, int32 x, int32 y, int32 z)
{
int i;
int32 rm[16], m[16];
for(i=0;i<16;i++)rm[i]=0;
rm[0]=inttof32(1);
rm[1+4*1]=inttof32(1);
rm[2+4*2]=inttof32(1);
rm[3+4*3]=inttof32(1);
rm[0+3*4]=x;
rm[1+3*4]=y;
rm[2+3*4]=z;
multMatrix44(rm,tm,m);
memcpy(tm,m,16*sizeof(int32));
}
void initCamera(camera_struct* c)
{
if(!c)c=&playerCamera;
c->position=vect(0,HEIGHTUNIT*STARTHEIGHT,0);
c->angle=vect(0,0,0);
c->angle2=vect(0,0,0);
c->object.position=c->position;
c->object.speed=vect(0,0,0);
c->lookAt=false;
initTransformationMatrix(c);
initProjectionMatrix(c, 70*90, inttof32(4)/3, inttof32(1), inttof32(500));
}
vect3D getUnitVector(camera_struct* c)
{
if(!c)c=&playerCamera;
vect3D v;
// v.x=-mulf32(sinLerp(c->angle.y),cosLerp(c->angle.x));
// v.y=sinLerp(c->angle.x);
// v.z=-mulf32(cosLerp(c->angle.y),cosLerp(c->angle.x));
v.x=-c->transformationMatrix[2];
v.y=-c->transformationMatrix[5];
v.z=-c->transformationMatrix[8];
return v;
}
void projectCamera(camera_struct* c)
{
if(!c)c=&playerCamera;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// gluPerspective(70, 256.0 / 192.0, 5.0, 1000);
// gluPerspective(70, 256.0 / 192.0, 1.0, 500);
// gluPerspectivef32(70*90, inttof32(4)/3, inttof32(1), inttof32(500));
// gluPerspective(70, 256.0 / 192.0, 0.1, 600);
multProjectionMatrix(c);
glMatrixMode(GL_MODELVIEW);
}
void transformCamera(camera_struct* c)
{
if(!c)c=&playerCamera;
multTransformationMatrix(c);
glTranslatef32(-c->position.x,-c->position.y,-c->position.z);
}
vect3D getCameraPosition(camera_struct* c)
{
if(!c)c=&playerCamera;
return c->position;
}
void setCamera(camera_struct* c, vect3D v)
{
if(!c)c=&playerCamera;
c->position=v;
}
void moveCamera(camera_struct* c, vect3D v)
{
if(!c)c=&playerCamera;
vect3D v1=normalize(vect(c->transformationMatrix[2],0/*c->transformationMatrix[5]*/,c->transformationMatrix[8]));
c->object.speed.x+=mulf32(v.z,v1.x)+mulf32(v.x,c->transformationMatrix[0]);
c->object.speed.y+=/*mulf32(v.z,v1.y)+*/mulf32(v.x,c->transformationMatrix[3]);
c->object.speed.z+=mulf32(v.z,v1.z)+mulf32(v.x,c->transformationMatrix[6]);
}
void rotateCamera(camera_struct* c, vect3D a)
{
if(!c)c=&playerCamera;
rotateMatrixX(c->transformationMatrix,-a.x,false);
rotateMatrixY(c->transformationMatrix,a.y,true);
rotateMatrixZ(c->transformationMatrix,a.z,false);
c->angle.x+=a.x;
c->angle.y+=a.y;
c->angle.z+=a.z;
// if(c->angle.x>4096*2)c->angle.x=4096*2;
// if(c->angle.x<-4096-2048)c->angle.x=-4096-2048;
}
void updateCameraPreview(room_struct* r, camera_struct* c)
{
if(!c)c=&playerCamera;
updatePhysicsObjectRoom(r,&c->object,true);
c->position=c->object.position;
}
bool pointInFrustum(frustum_struct* f, vect3D v)
{
if(!f)f=&playerCamera.frustum;
return ((evaluatePlanePoint(&f->plane[0],v)>0)&&(evaluatePlanePoint(&f->plane[1],v)>0)&&(evaluatePlanePoint(&f->plane[2],v)>0)
&&(evaluatePlanePoint(&f->plane[3],v)>0)&&(evaluatePlanePoint(&f->plane[4],v)>0)&&(evaluatePlanePoint(&f->plane[5],v)>0));
}
void updateFrustum(camera_struct* c)
{
if(!c)c=&playerCamera;
frustum_struct* f=&c->frustum;
//near
f->plane[0].A=c->viewMatrix[mcoord(2,0)]+c->viewMatrix[mcoord(3,0)];
f->plane[0].B=c->viewMatrix[mcoord(2,1)]+c->viewMatrix[mcoord(3,1)];
f->plane[0].C=c->viewMatrix[mcoord(2,2)]+c->viewMatrix[mcoord(3,2)];
f->plane[0].D=c->viewMatrix[mcoord(2,3)]+c->viewMatrix[mcoord(3,3)];
// f->plane[0].D=0;
//far
f->plane[1].A=-c->viewMatrix[mcoord(2,0)]+c->viewMatrix[mcoord(3,0)];
f->plane[1].B=-c->viewMatrix[mcoord(2,1)]+c->viewMatrix[mcoord(3,1)];
f->plane[1].C=-c->viewMatrix[mcoord(2,2)]+c->viewMatrix[mcoord(3,2)];
f->plane[1].D=-c->viewMatrix[mcoord(2,3)]+c->viewMatrix[mcoord(3,3)];
//left
f->plane[2].A=c->viewMatrix[mcoord(0,0)]+c->viewMatrix[mcoord(3,0)];
f->plane[2].B=c->viewMatrix[mcoord(0,1)]+c->viewMatrix[mcoord(3,1)];
f->plane[2].C=c->viewMatrix[mcoord(0,2)]+c->viewMatrix[mcoord(3,2)];
f->plane[2].D=c->viewMatrix[mcoord(0,3)]+c->viewMatrix[mcoord(3,3)];
//right
f->plane[3].A=-c->viewMatrix[mcoord(0,0)]+c->viewMatrix[mcoord(3,0)];
f->plane[3].B=-c->viewMatrix[mcoord(0,1)]+c->viewMatrix[mcoord(3,1)];
f->plane[3].C=-c->viewMatrix[mcoord(0,2)]+c->viewMatrix[mcoord(3,2)];
f->plane[3].D=-c->viewMatrix[mcoord(0,3)]+c->viewMatrix[mcoord(3,3)];
//bottom
f->plane[4].A=c->viewMatrix[mcoord(1,0)]+c->viewMatrix[mcoord(3,0)];
f->plane[4].B=c->viewMatrix[mcoord(1,1)]+c->viewMatrix[mcoord(3,1)];
f->plane[4].C=c->viewMatrix[mcoord(1,2)]+c->viewMatrix[mcoord(3,2)];
f->plane[4].D=c->viewMatrix[mcoord(1,3)]+c->viewMatrix[mcoord(3,3)];
//top
f->plane[5].A=-c->viewMatrix[mcoord(1,0)]+c->viewMatrix[mcoord(3,0)];
f->plane[5].B=-c->viewMatrix[mcoord(1,1)]+c->viewMatrix[mcoord(3,1)];
f->plane[5].C=-c->viewMatrix[mcoord(1,2)]+c->viewMatrix[mcoord(3,2)];
f->plane[5].D=-c->viewMatrix[mcoord(1,3)]+c->viewMatrix[mcoord(3,3)];
int i=0;
for(i=0;i<6;i++)
{
int32 r=sqrtf32(mulf32(f->plane[i].A,f->plane[i].A)+mulf32(f->plane[i].B,f->plane[i].B)+mulf32(f->plane[i].C,f->plane[i].C));
f->plane[i].A=divf32(f->plane[i].A,r);
f->plane[i].B=divf32(f->plane[i].B,r);
f->plane[i].C=divf32(f->plane[i].C,r);
f->plane[i].D=divf32(f->plane[i].D,r);
f->plane[i].point.x=-mulf32(f->plane[i].D,f->plane[i].A);
f->plane[i].point.y=-mulf32(f->plane[i].D,f->plane[i].B);
f->plane[i].point.z=-mulf32(f->plane[i].D,f->plane[i].C);
}
}
void updateCamera(camera_struct* c)
{
if(!c)c=&playerCamera;
c->position=c->object.position;
updateViewMatrix(c);
updateFrustum(c);
iprintf("alignment : %d \n",c->transformationMatrix[3]);
// if(c->transformationMatrix[4]<-32)
// {
// rotateMatrixX(c->transformationMatrix, -(1<<10), false);
// }else
{
if(c->transformationMatrix[3]>32)
{
if(c->transformationMatrix[3]>512)rotateMatrixZ(c->transformationMatrix, (1<<10), false);
else if(c->transformationMatrix[3]>256)rotateMatrixZ(c->transformationMatrix, (1<<9), false);
else if(c->transformationMatrix[3]>128)rotateMatrixZ(c->transformationMatrix, (1<<8), false);
// else if(c->transformationMatrix[3]>64)rotateMatrixZ(c->transformationMatrix, (1<<7), false);
// else if(c->transformationMatrix[3]>12)rotateMatrixZ(c->transformationMatrix, (1<<6), false);
}else if(c->transformationMatrix[3]<-32)
{
if(c->transformationMatrix[3]<-512)rotateMatrixZ(c->transformationMatrix, -(1<<10), false);
else if(c->transformationMatrix[3]<-256)rotateMatrixZ(c->transformationMatrix, -(1<<9), false);
else if(c->transformationMatrix[3]<-128)rotateMatrixZ(c->transformationMatrix, -(1<<8), false);
// else if(c->transformationMatrix[3]<-64)rotateMatrixZ(c->transformationMatrix, -(1<<7), false);
// else if(c->transformationMatrix[3]<-12)rotateMatrixZ(c->transformationMatrix, -(1<<6), false);
}
}
fixMatrix(c->transformationMatrix); //compensate fixed point errors
}
camera_struct* getPlayerCamera(void){return &playerCamera;}

696
arm9/source/game/doors.c Normal file
View File

@ -0,0 +1,696 @@
#include "editor/editor_main.h"
doorCollection_struct doorCollection;
mtlImg_struct* doorMtl;
extern roomEdit_struct roomEdits[NUMROOMEDITS];
void initDoor(door_struct* d)
{
if(!d)return;
d->used=false;
d->primaryRoom=d->secondaryRoom=NULL;
d->position=0;
d->height=0;
}
void deleteDoor(door_struct* d)
{
if(!d)return;
d->used=false;
}
void initDoorCollection(doorCollection_struct* dc)
{
if(!dc)dc=&doorCollection;
int i;
for(i=0;i<NUMDOORS;i++)
{
initDoor(&dc->door[i]);
}
doorMtl=createTexture("door.pcx", "textures");
}
bool doorCollides(doorCollection_struct* dc, room_struct* r, doorDirection dd, u16 p, door_struct* d2)
{
if(!dc)dc=&doorCollection;
int i;
for(i=0;i<NUMDOORS;i++)
{
if(dc->door[i].used && dc->door[i].primaryRoom==r)
{
door_struct* d=&dc->door[i];
if(d!=d2 && d->direction==dd && abs(p-d->position)<DOORSIZE)return true;
}
}
return false;
}
bool checkDoorWay(door_struct* d, room_struct* r, int x, int y, bool secondary, bool override)
{
if(!d||!d->primaryRoom||(secondary&&!d->secondaryRoom)||(!override&&(!d->open||d->percentage)))return false;
switch(d->direction)
{
case doorUp:
if(!secondary)return y<0&&x<d->position+DOORSIZE&&x>=d->position;
else {x+=r->position.x-d->primaryRoom->position.x;return y>=r->height&&x<d->position+DOORSIZE&&x>=d->position;}
break;
case doorDown:
if(!secondary)return y>=r->height&&x<d->position+DOORSIZE&&x>=d->position;
else {x+=r->position.x-d->primaryRoom->position.x;return y<0&&x<d->position+DOORSIZE&&x>=d->position;}
break;
case doorLeft:
if(!secondary)return x<0&&y<d->position+DOORSIZE&&y>=d->position;
else {y+=r->position.y-d->primaryRoom->position.y;return x>=r->width&&y<d->position+DOORSIZE&&y>=d->position;}
break;
case doorRight:
if(!secondary)return x>=r->width&&y<d->position+DOORSIZE&&y>=d->position;
else {y+=r->position.y-d->primaryRoom->position.y;return x<0&&y<d->position+DOORSIZE&&y>=d->position;}
break;
}
return false;
}
door_struct* inDoorWay(doorCollection_struct* dc, room_struct* r, int x, int y, bool secondary, bool override)
{
if(!dc)dc=&doorCollection;
int i;
for(i=0;i<NUMDOORS;i++)
{
if(dc->door[i].used && ((!secondary && dc->door[i].primaryRoom==r)||(secondary && dc->door[i].secondaryRoom==r)))
{
door_struct* d=&dc->door[i];
if(checkDoorWay(d,r,x,y,secondary,override))return d;
}
}
return NULL;
}
vect2D getDoorPosition2(room_struct* r, door_struct* d)
{
vect2D v=vect2(0,0);
if(!d || !d->primaryRoom)return v;
room_struct* pr=d->primaryRoom;
switch(d->direction)
{
case doorUp:
v=vect2(d->position,0);
break;
case doorDown:
v=vect2(d->position,pr->height);
break;
case doorLeft:
v=vect2(0,d->position);
break;
case doorRight:
v=vect2(pr->width,d->position);
break;
}
v.x-=r->position.x-pr->position.x;
v.y-=r->position.y-pr->position.y;
return v;
}
bool checkDoorTouches(door_struct* d, roomEdit_struct* re, int x, int y, bool secondary)
{
if(!d || !d->primaryRoom)return false;
switch(d->direction)
{
case doorUp:
if(!secondary)return y==0&&x<d->position+DOORSIZE&&x>=d->position;
else {x+=re->position.x-d->primaryRoom->position.x;return y==re->size.y-1&&x<d->position+DOORSIZE&&x>=d->position;}
break;
case doorDown:
if(!secondary)return (y==(re->size.y-1))&&x<d->position+DOORSIZE&&x>=d->position;
else {x+=re->position.x-d->primaryRoom->position.x;return (y==0)&&x<d->position+DOORSIZE&&x>=d->position;}
break;
case doorLeft:
if(!secondary)return x==0&&y<d->position+DOORSIZE&&y>=d->position;
else {y+=re->position.y-d->primaryRoom->position.y;return x==re->size.x-1&&y<d->position+DOORSIZE&&y>=d->position;}
break;
case doorRight:
if(!secondary)return (x==(re->size.x-1))&&y<d->position+DOORSIZE&&y>=d->position;
else {y+=re->position.y-d->primaryRoom->position.y;return (x==0)&&y<d->position+DOORSIZE&&y>=d->position;}
break;
}
return false;
}
door_struct* doorTouches(doorCollection_struct* dc, roomEdit_struct* re, int x, int y, bool secondary)
{
if(!dc)dc=&doorCollection;
int i;
for(i=0;i<NUMDOORS;i++)
{
if(dc->door[i].used && ((!secondary && dc->door[i].primaryRoom==&re->data)||(secondary && dc->door[i].secondaryRoom==&re->data)))
{
door_struct* d=&dc->door[i];
if(checkDoorTouches(d,re,x,y,secondary))return d;
}
}
return NULL;
}
void doorGetSecondaryRoom(door_struct* d)
{
if(!d || !d->primaryRoom)return;
d->secondaryRoom=NULL;
room_struct* pr=d->primaryRoom;
int i;
for(i=0;i<NUMROOMEDITS;i++)
{
if(roomEdits[i].used && &roomEdits[i].data!=pr)
{
room_struct* r=&roomEdits[i].data;
switch(d->direction)
{
case doorUp:
if(r->position.y+r->height==pr->position.y && r->position.x<d->position+pr->position.x && r->position.x+r->width>d->position+pr->position.x+DOORSIZE)
{
d->secondaryRoom=r;
return;
}
break;
case doorDown:
if(r->position.y==pr->position.y+pr->height && r->position.x<d->position+pr->position.x && r->position.x+r->width>d->position+pr->position.x+DOORSIZE)
{
d->secondaryRoom=r;
return;
}
break;
case doorLeft:
if(r->position.x+r->width==pr->position.x && r->position.y<d->position+pr->position.y && r->position.y+r->height>d->position+pr->position.y+DOORSIZE)
{
d->secondaryRoom=r;
return;
}
break;
case doorRight:
if(r->position.x==pr->position.x+pr->width && r->position.y<d->position+pr->position.y && r->position.y+r->height>d->position+pr->position.y+DOORSIZE)
{
d->secondaryRoom=r;
return;
}
break;
}
}
}
}
void getSecondaryRooms(doorCollection_struct* dc)
{
if(!dc)dc=&doorCollection;
int i;
for(i=0;i<NUMDOORS;i++)
{
if(dc->door[i].used)
{
doorGetSecondaryRoom(&dc->door[i]);
NOGBA("door %d : %p (vs %p)",i,dc->door[i].secondaryRoom,dc->door[i].primaryRoom);
}
}
}
door_struct* createDoor(doorCollection_struct* dc, room_struct* pr, u16 position, doorDirection dir, bool override)
{
if(!dc)dc=&doorCollection;
if(!override && doorCollides(dc, pr, dir, position, NULL))return NULL;
int i;
for(i=0;i<NUMDOORS;i++)
{
if(!dc->door[i].used)
{
door_struct* d=&dc->door[i];
d->used=true;
d->open=false;
d->selected=false;
d->position=position;
d->percentage=128;
d->direction=dir;
d->primaryRoom=pr;
d->secondaryRoom=NULL;
return d;
}
}
return NULL;
}
bool confirmDoor(door_struct* d)
{
if(!d||!d->primaryRoom)return false;
int k1=0, k2=0;
room_struct* pr=d->primaryRoom;
switch(d->direction)
{
case doorUp:
k1=d->position+0*pr->width;
k2=d->position+1+0*pr->width;
break;
case doorDown:
k1=d->position+(pr->height-1)*pr->width;
k2=d->position+1+(pr->height-1)*pr->width;
break;
case doorRight:
k1=(pr->width-1)+d->position*pr->width;
k2=(pr->width-1)+(d->position+1)*pr->width;
break;
case doorLeft:
k1=(0)+d->position*pr->width;
k2=(0)+(d->position+1)*pr->width;
break;
}
d->height=pr->floor[k1];
return (pr->floor[k1]==pr->floor[k2])&&(pr->materials[k1]==pr->materials[k2])&&(pr->floor[k1]+DOORHEIGHT<pr->ceiling[k1])&&(pr->floor[k2]+DOORHEIGHT<pr->ceiling[k2]);
}
void confirmRoomDoors(doorCollection_struct* dc, room_struct* r)
{
if(!dc)dc=&doorCollection;
int i;
for(i=0;i<NUMDOORS;i++)
{
if(dc->door[i].used && dc->door[i].primaryRoom==r && !confirmDoor(&dc->door[i]))deleteDoor(&dc->door[i]);
}
}
void confirmDoors(doorCollection_struct* dc)
{
if(!dc)dc=&doorCollection;
int i;
for(i=0;i<NUMDOORS;i++)
{
if(dc->door[i].used && !confirmDoor(&dc->door[i]))deleteDoor(&dc->door[i]);
}
}
void drawDoor(roomEdit_struct* re, door_struct* d)
{
if(!d)return;
glPushMatrix();
if(d->selected)glColor3b(0,0,255);
else glColor3b(0,255,0);
switch(d->direction)
{
case doorUp:
glTranslate3f32(d->position*(1<<9),0,0);
glScalef32(DOORSIZE*(1<<9),inttof32(1),inttof32(1));
glBegin(GL_QUADS);
glVertex3v16(0, OUTLINEWIDTH, 0);
glVertex3v16(inttof32(1), OUTLINEWIDTH, 0);
glVertex3v16(inttof32(1), 0, 0);
glVertex3v16(0, 0, 0);
break;
case doorDown:
glTranslate3f32(d->position*(1<<9),re->size.y*(1<<9)-OUTLINEWIDTH,0);
glScalef32(DOORSIZE*(1<<9),inttof32(1),inttof32(1));
glBegin(GL_QUADS);
glVertex3v16(0, OUTLINEWIDTH, 0);
glVertex3v16(inttof32(1), OUTLINEWIDTH, 0);
glVertex3v16(inttof32(1), 0, 0);
glVertex3v16(0, 0, 0);
break;
case doorRight:
glTranslate3f32(re->size.x*(1<<9)-OUTLINEWIDTH,d->position*(1<<9),0);
glScalef32(inttof32(1),DOORSIZE*(1<<9),inttof32(1));
glBegin(GL_QUADS);
glVertex3v16(0, 0, 0);
glVertex3v16(0, inttof32(1), 0);
glVertex3v16(OUTLINEWIDTH, inttof32(1), 0);
glVertex3v16(OUTLINEWIDTH, 0, 0);
break;
case doorLeft:
glTranslate3f32(0,d->position*(1<<9),0);
glScalef32(inttof32(1),DOORSIZE*(1<<9),inttof32(1));
glBegin(GL_QUADS);
glVertex3v16(0, 0, 0);
glVertex3v16(0, inttof32(1), 0);
glVertex3v16(OUTLINEWIDTH, inttof32(1), 0);
glVertex3v16(OUTLINEWIDTH, 0, 0);
break;
}
glPopMatrix(1);
}
void drawRoomDoors(doorCollection_struct* dc, roomEdit_struct* re)
{
if(!dc)dc=&doorCollection;
int i;
room_struct* r=&re->data;
glPushMatrix();
glTranslate3f32(re->position.x*(1<<9),re->position.y*(1<<9),64);
for(i=0;i<NUMDOORS;i++)
{
if(dc->door[i].used && dc->door[i].primaryRoom==r)
{
door_struct* d=&dc->door[i];
drawDoor(re, d);
}
}
glPopMatrix(1);
}
void getDoorRectangle(door_struct* d, bool primary, rectangle_struct* rrrec)
{
rectangle_struct rec=(rectangle_struct){vect(0,0,0),vect(0,0,0),vect(0,0,0)};
if(!d || !d->primaryRoom)return;
if(primary)
{
room_struct* pr=d->primaryRoom;
switch(d->direction)
{
case doorUp:
rec.position=vect(d->position,d->height,0);
rec.size=vect(DOORSIZE,DOORHEIGHT,0);
rec.normal=vect(0,0,-inttof32(1));
break;
case doorDown:
rec.position=vect(d->position+DOORSIZE,d->height,pr->height);
rec.size=vect(-DOORSIZE,DOORHEIGHT,0);
rec.normal=vect(0,0,inttof32(1));
break;
case doorLeft:
rec.position=vect(0,d->height,d->position+DOORSIZE);
rec.size=vect(0,DOORHEIGHT,-DOORSIZE);
rec.normal=vect(-inttof32(1),0,0);
break;
case doorRight:
rec.position=vect(pr->width,d->height,d->position);
rec.size=vect(0,DOORHEIGHT,DOORSIZE);
rec.normal=vect(inttof32(1),0,0);
break;
}
}else{
if(!d->secondaryRoom)return;
room_struct* pr=d->secondaryRoom;
switch(d->direction)
{
case doorUp:
rec.position=vect(d->primaryRoom->position.x-d->secondaryRoom->position.x+d->position+DOORSIZE,d->height,pr->height);
rec.size=vect(-DOORSIZE,DOORHEIGHT,0);
rec.normal=vect(0,0,-inttof32(1));
break;
case doorDown:
rec.position=vect(d->primaryRoom->position.x-d->secondaryRoom->position.x+d->position,d->height,0);
rec.size=vect(DOORSIZE,DOORHEIGHT,0);
rec.normal=vect(0,0,inttof32(1));
break;
case doorLeft:
rec.position=vect(pr->width,d->height,d->primaryRoom->position.y-d->secondaryRoom->position.y+d->position);
rec.size=vect(0,DOORHEIGHT,DOORSIZE);
rec.normal=vect(-inttof32(1),0,0);
break;
case doorRight:
rec.position=vect(0,d->height,d->primaryRoom->position.y-d->secondaryRoom->position.y+d->position+DOORSIZE);
rec.size=vect(0,DOORHEIGHT,-DOORSIZE);
rec.normal=vect(inttof32(1),0,0);
break;
}
}
rrrec->position=rec.position;
rrrec->size=rec.size;
rrrec->normal=rec.normal;
}
bool collideLineDoor(door_struct* d, vect3D o, vect3D v, int32 dist)
{
if(!d || !d->primaryRoom)return false;
rectangle_struct rec;
getDoorRectangle(d,true,&rec);
return collideLineRectangle(&rec, o, v, dist, NULL, NULL);
}
bool collideSegmentDoors(doorCollection_struct* dc, room_struct* r, vect3D p1, vect3D p2)
{
if(!dc)dc=&doorCollection;
vect3D u=vectDifference(p2,p1);
//(precision problem)
u=vectMultInt(u,100);
int32 dist=magnitude(u);
u=divideVect(u,dist);
dist/=100;
vect3D o=p1;
int i;
for(i=0;i<NUMDOORS;i++)
{
if(dc->door[i].used && dc->door[i].primaryRoom)
{
room_struct* pr=dc->door[i].primaryRoom;
o=convertSize(vectDifference(vect(r->position.x,0,r->position.y),vect(pr->position.x,0,pr->position.y)));
o=addVect(p1,convertSize(vectDifference(vect(r->position.x,0,r->position.y),vect(pr->position.x,0,pr->position.y))));
if(collideLineDoor(&dc->door[i],o,u,dist))return true;
}
}
return false;
}
void renderDoorRectangle(door_struct* d, rectangle_struct rec)
{
s16 percentage=d->percentage;
vect3D pos=convertVect(rec.position);
vect3D size=convertSize(rec.size);
size.y*=percentage;
size.y/=128;
vect3D p1=vect(0,(inttot16(63)*(128-percentage))/128,0);
vect3D p2=vect(inttot16(63),inttot16(63),0);
int32 t1=TEXTURE_PACK(p1.x, p1.y);
int32 t2=TEXTURE_PACK(p2.x, p1.y);
int32 t3=TEXTURE_PACK(p2.x, p2.y);
int32 t4=TEXTURE_PACK(p1.x, p2.y);
if(!size.x)
{
glBegin(GL_QUAD);
GFX_TEX_COORD = t2;
glVertex3v16(pos.x, pos.y, pos.z);
GFX_TEX_COORD = t1;
glVertex3v16(pos.x, pos.y, pos.z+size.z);
GFX_TEX_COORD = t4;
glVertex3v16(pos.x, pos.y+size.y, pos.z+size.z);
GFX_TEX_COORD = t3;
glVertex3v16(pos.x, pos.y+size.y, pos.z);
}else{
glBegin(GL_QUAD);
GFX_TEX_COORD = t2;
glVertex3v16(pos.x+size.x, pos.y, pos.z);
GFX_TEX_COORD = t3;
glVertex3v16(pos.x+size.x, pos.y+size.y, pos.z);
GFX_TEX_COORD = t4;
glVertex3v16(pos.x, pos.y+size.y, pos.z);
GFX_TEX_COORD = t1;
glVertex3v16(pos.x, pos.y, pos.z);
}
}
void renderDoorLightmap(door_struct* d, rectangle_struct rec)
{
s16 percentage=d->percentage;
vect3D pos=convertVect(rec.position);
vect3D size=convertSize(rec.size);
size.y*=percentage;
size.y/=128;
vect3D p1=vect(inttot16(rec.lmPos.x),inttot16(rec.lmPos.y),0);
vect3D p2=vect(inttot16(rec.lmPos.x+rec.lmSize.x-1),inttot16(rec.lmPos.y+rec.lmSize.y-1),0);
int32 t1=TEXTURE_PACK(p1.x, p1.y);
int32 t2=TEXTURE_PACK(p1.x, p2.y);
int32 t3=TEXTURE_PACK(p2.x, p2.y);
int32 t4=TEXTURE_PACK(p2.x, p1.y);
if(rec.rot)
{
p2=vect(inttot16(rec.lmPos.x+rec.lmSize.y-1),inttot16(rec.lmPos.y+rec.lmSize.x-1),0);
t1=TEXTURE_PACK(p1.x, p1.y);
t4=TEXTURE_PACK(p1.x, p2.y);
t3=TEXTURE_PACK(p2.x, p2.y);
t2=TEXTURE_PACK(p2.x, p1.y);
}
if(!size.x)
{
glBegin(GL_QUAD);
GFX_TEX_COORD = t1;
glVertex3v16(pos.x, pos.y, pos.z);
GFX_TEX_COORD = t2;
glVertex3v16(pos.x, pos.y, pos.z+size.z);
GFX_TEX_COORD = t3;
glVertex3v16(pos.x, pos.y+size.y, pos.z+size.z);
GFX_TEX_COORD = t4;
glVertex3v16(pos.x, pos.y+size.y, pos.z);
}else{
glBegin(GL_QUAD);
GFX_TEX_COORD = t1;
glVertex3v16(pos.x+size.x, pos.y, pos.z);
GFX_TEX_COORD = t2;
glVertex3v16(pos.x+size.x, pos.y+size.y, pos.z);
GFX_TEX_COORD = t3;
glVertex3v16(pos.x, pos.y+size.y, pos.z);
GFX_TEX_COORD = t4;
glVertex3v16(pos.x, pos.y, pos.z);
}
}
void renderDoor(room_struct* r, door_struct* d)
{
glPushMatrix();
glPolyFmt(POLY_ALPHA(31) | POLY_CULL_BACK);
applyMTL(doorMtl);
if(r==d->primaryRoom)renderDoorRectangle(d, d->primaryRec);
else if(r==d->secondaryRoom)renderDoorRectangle(d, d->secondaryRec);
if(r->lmSlot)
{
glPolyFmt(POLY_ALPHA(31) | (1<<14) | POLY_CULL_BACK);
applyMTL(r->lmSlot->mtl);
if(r==d->primaryRoom)renderDoorLightmap(d, d->primaryRec);
else if(r==d->secondaryRoom)renderDoorLightmap(d, d->secondaryRec);
}
glPopMatrix(1);
}
void getRoomDoorRectangles(doorCollection_struct* dc, room_struct* r)
{
if(!dc)dc=&doorCollection;
int i;
for(i=0;i<NUMDOORS;i++)
{
if(dc->door[i].used && (r==dc->door[i].primaryRoom || r==dc->door[i].secondaryRoom))
{
door_struct* d=&dc->door[i];
getDoorRectangle(d,true,&d->primaryRec);
getDoorRectangle(d,false,&d->secondaryRec);
}
}
}
void renderRoomDoors(doorCollection_struct* dc, room_struct* r)
{
if(!dc)dc=&doorCollection;
glPushMatrix();
int i;
for(i=0;i<NUMDOORS;i++)
{
if(dc->door[i].used && (dc->door[i].primaryRoom==r||dc->door[i].secondaryRoom==r))
{
door_struct* d=&dc->door[i];
renderDoor(r, d);
}
}
glPopMatrix(1);
}
void updateDoor(door_struct* d)
{
if(!d)return;
if(!d->open && d->percentage<128)
{
d->percentage-=4;
if(d->percentage<=0)
{
d->percentage=0;
d->open=true;
d->timer=0;
}
}else if(d->open && d->percentage>0)
{
d->percentage+=4;
if(d->percentage>=128)
{
d->percentage=128;
d->open=false;
}
}
if(d->open && !d->percentage)
{
d->timer++;
if(d->timer>DOORPERIOD)d->percentage++;
}
}
void updateDoors(doorCollection_struct* dc)
{
if(!dc)dc=&doorCollection;
int i;
for(i=0;i<NUMDOORS;i++)
{
if(dc->door[i].used)updateDoor(&dc->door[i]);
}
}
bool toggleDoor(room_struct* r, door_struct* d)
{
if(!d || !d->secondaryRoom)return false;
if(!d->open && d->percentage){d->percentage--;return true;}
else if(d->open && !d->percentage){d->percentage++;return true;}
return false;
}
bool isDoorOpen(doorCollection_struct* dc, room_struct* r1, room_struct* r2)
{
if(!r1 || !r2)return false;
if(!dc)dc=&doorCollection;
int i;
for(i=0;i<NUMDOORS;i++)
{
door_struct* d=&dc->door[i];
if(d->used && ((d->primaryRoom==r1 && d->secondaryRoom==r2) || (d->primaryRoom==r2 && d->secondaryRoom==r1)))
{
if((d->open || (d->percentage!=0 && d->percentage!=128)))return true;
}
}
return false;
}
void closeRoomDoors(doorCollection_struct* dc, room_struct* r, door_struct* d)
{
if(!r)return;
if(!dc)dc=&doorCollection;
int i;
for(i=0;i<NUMDOORS;i++)
{
if(dc->door[i].used && d!=&dc->door[i] && (dc->door[i].primaryRoom==r || dc->door[i].secondaryRoom==r))
{
dc->door[i].open=false;
dc->door[i].percentage=128;
}
}
}
door_struct* getClosestDoorRoom(doorCollection_struct* dc, room_struct* r, vect2D p, int* distt)
{
if(!dc)dc=&doorCollection;
int i;
int mindist=999999999;
door_struct* closestDoor=NULL;
for(i=0;i<NUMDOORS;i++)
{
if(dc->door[i].used && (dc->door[i].primaryRoom==r||dc->door[i].secondaryRoom==r))
{
door_struct* d=&dc->door[i];
vect2D v=getDoorPosition2(r, d);
int dist=(v.x-p.x)*(v.x-p.x)+(v.y-p.y)*(v.y-p.y);
if(dist<mindist)
{
mindist=dist;
closestDoor=d;
}
}
}
*distt=mindist;
return closestDoor;
}

261
arm9/source/game/enemy.c Normal file
View File

@ -0,0 +1,261 @@
#include "game/game_main.h"
enemy_struct enemy[NUMENEMIES];
md2Model_struct enemyModel; //TEMP
void initEn(enemy_struct* e)
{
if(!e)return;
e->object.position=vect(0,0,0);
e->object.speed=vect(0,0,0);
e->modelInstance.currentAnim=0;
e->modelInstance.currentFrame=0;
e->used=false;
}
void initEnemies(void)
{
int i;
for(i=0;i<NUMENEMIES;i++)initEn(&enemy[i]);
loadMd2Model("enemy.md2", "enemy1.pcx", &enemyModel);
}
void createEn(room_struct* r, vect3D p)
{
int i;
for(i=0;i<NUMENEMIES;i++)
{
if(!enemy[i].used)
{
enemy_struct* e=&enemy[i];
e->used=true;
e->tilePosition=vect(p.x,p.y,p.z);
e->nextTilePosition=vect(p.x,p.y,p.z);
e->progress=0;
e->object.position=vect(p.x*(TILESIZE*2)+TILESIZE,p.y*HEIGHTUNIT,p.z*(TILESIZE*2)+TILESIZE);
e->object.speed=vect(0,0,0);
e->r=r;
e->angle=0;
e->path.first=NULL;
e->life=100;
e->task=0;
e->detected=false;
e->pathed=false;
e->targetPosition=vect(0,0,0);
e->modelInstance.model=&enemyModel;
e->modelInstance.currentAnim=0;
e->modelInstance.currentFrame=0;
e->modelInstance.nextFrame=1;
e->modelInstance.interpCounter=0;
e->ec=getEntityCollection(r);
break;
}
}
}
vect3D getVector(enemy_struct* e, entity_struct* ent)
{
vect3D p=ent->position;
vect3D v=vectDifference(e->object.position,vect(p.x*(TILESIZE*2),p.z*HEIGHTUNIT,p.y*(TILESIZE*2)));
v=vectMultInt(v,100);
int32 dist=magnitude(v);
v=divideVect(v,dist);
// dist/=100;
return vect(f32tov10(v.x),f32tov10(v.y),f32tov10(v.z));
}
void setUpEnemyLighting(enemy_struct* e, u32* params)
{
entity_struct *l1, *l2, *l3;
int32 d1, d2, d3;
getClosestLights(e->ec, e, &l1, &l2, &l3, &d1, &d2, &d3);
*params=POLY_ALPHA(31) | POLY_CULL_FRONT;
glMaterialf(GL_AMBIENT, RGB15(2,2,2));
glMaterialf(GL_DIFFUSE, RGB15(31,31,31));
glMaterialf(GL_SPECULAR, RGB15(0,0,0));
glMaterialf(GL_EMISSION, RGB15(0,0,0));
if(l1)
{
*params|=POLY_FORMAT_LIGHT0;
vect3D v=getVector(e, l1);
d1*=64;
int32 v2=31-((31*d1)*(((lightData_struct*)l1->data)->intensity));
glLight(0, RGB15(v2,v2,v2), v.x, v.y, v.z);
if(l2)
{
*params|=POLY_FORMAT_LIGHT1;
vect3D v=getVector(e, l2);
int32 v2=31-((31*d2)*(((lightData_struct*)l2->data)->intensity));
glLight(1, RGB15(v2,v2,v2), v.x, v.y, v.z);
if(l3)
{
*params|=POLY_FORMAT_LIGHT2;
vect3D v=getVector(e, l3);
int32 v2=31-((31*d3)*(((lightData_struct*)l3->data)->intensity));
glLight(2, RGB15(v2,v2,v2), v.x, v.y, v.z);
}
}
}
}
void drawEnemy(enemy_struct* e)
{
if(!e || !e->used || !e->r || !e->r->lmSlot || !e->r->lmSlot->used)return;
glPushMatrix();
glTranslate3f32(TILESIZE*2*e->r->position.x, 0, TILESIZE*2*e->r->position.y);
glTranslate3f32(-TILESIZE*2, 0, -TILESIZE*2);
glTranslate3f32(e->object.position.x,e->object.position.y,e->object.position.z);
bool r=BoxTest(0,0,0,TILESIZE*2,HEIGHTUNIT*16,TILESIZE*2);
glTranslate3f32(TILESIZE*2, 0, TILESIZE*2);
// NOGBA("boxtest %d",(int)r);
if(r)
{
u32 params=0;
setUpEnemyLighting(e, &params);
glRotateYi(e->angle);
glScalef32(3<<10,3<<10,3<<10);
renderModelFrameInterp(e->modelInstance.currentFrame,e->modelInstance.nextFrame,e->modelInstance.interpCounter,e->modelInstance.model,params);
}
glPopMatrix(1);
}
void drawEnemies(void)
{
int i;
for(i=0;i<NUMENEMIES;i++)
{
if(enemy[i].used)drawEnemy(&enemy[i]);
}
}
void moveEnemyTo(enemy_struct* e, int x, int y, u8 task)
{
if(!e)return;
if(x<0 || y<0 || x>e->r->width-1 || y>e->r->height-1)return;
if(x==e->tilePosition.x && y==e->tilePosition.y)return;
if(e->path.first){freePath(&e->path);}
e->task=task;
e->targetPosition=vect(x,0,y);
e->path.first=getPath(e->r,vect2(e->tilePosition.x,e->tilePosition.z),vect2(x,y));
}
void moveRoomEnemiesTo(room_struct* r, int x, int y, u8 task)
{
if(!r)return;
int i;
for(i=0;i<NUMENEMIES;i++)
{
if(enemy[i].used && enemy[i].r==r)
{
moveEnemyTo(&enemy[i], x, y, task);
}
}
}
bool collideLineEnemy(enemy_struct* e, vect3D l, vect3D u, int32 d, int32* k, vect3D* ip)
{
if(!e)return false;
rectangle_struct rec;
rec.position=e->tilePosition;
rec.size=vect(1,10,0);
rec.normal=vect(0,0,inttof32(1));
if(collideLineRectangle(&rec,vect(l.x-TILESIZE*2,l.y,l.z-TILESIZE*2),u,d,k,ip))return true;
rec.position=e->tilePosition;
rec.size=vect(0,10,1);
rec.normal=vect(inttof32(1),0,0);
if(collideLineRectangle(&rec,vect(l.x-TILESIZE*2,l.y,l.z-TILESIZE*2),u,d,k,ip))return true;
return false;
}
enemy_struct* collideLineRoomEnemies(room_struct* r, vect3D l, vect3D u, int32 d, int32* k, vect3D* ip)
{
if(!r)return NULL;
int i;
for(i=0;i<NUMENEMIES;i++)
{
if(enemy[i].used && enemy[i].life>0 && enemy[i].r==r)
{
if(collideLineEnemy(&enemy[i], l, u, d, k, ip))return &enemy[i];
}
}
return NULL;
}
void updateEnemy(enemy_struct* e)
{
if(!e || !e->used || !e->r || !e->r->lmSlot || !e->r->lmSlot->used)return;
player_struct* p=getPlayer();
// if(e->r!=p->currentRoom)return;
int dist=100;
if(e->life<=0)
{
if(e->modelInstance.currentFrame!=enemyModel.animations[ANIMDEATH].end)changeAnimation(&e->modelInstance,ANIMDEATH,true);
else {e->used=false;return;}
// if(e->modelInstance.currentAnim!=ANIMDEATH)mmEffect(SFX_ENEMY1DEAD);
}else{
if(p->currentRoom==e->r)
{
if(!e->task && e->detected)moveEnemyTo(e,p->relativePosition.x,p->relativePosition.z,RUNTO);
if(e->path.first)e->pathed=true;
vect3D p1=e->tilePosition, p2=p->relativePosition;
dist=(p1.x-p2.x)*(p1.x-p2.x)+(p1.z-p2.z)*(p1.z-p2.z)+(p1.y-p2.y)*(p1.y-p2.y);
if(dist<42 && e->modelInstance.currentAnim!=ANIMPAIN && e->modelInstance.currentAnim!=ANIMATTACK && e->pathed){damagePlayer(NULL);changeAnimation(&e->modelInstance,ANIMATTACK,true);}
if(dist<120){/*if(!e->detected)mmEffect(SFX_SCREAM);*/e->detected=true;}
// NOGBA("d %d",dist);
// NOGBA("RUNNING TO YOU MY LOVE");
// NOGBA("mem free : %dko (%do)",getMemFree()/1024,getMemFree());
}
if(e->task==WALKTO || e->task==RUNTO)
{
u8 speed=ENEMYWALKINGSPEED;
if(e->task==WALKTO)changeAnimation(&e->modelInstance,ANIMWALK,false);
else {changeAnimation(&e->modelInstance,ANIMRUN,false);speed=ENEMYRUNNINGSPEED;}
if(e->tilePosition.x!=e->nextTilePosition.x || e->tilePosition.z!=e->nextTilePosition.z || e->path.first)
{
if(e->tilePosition.x<e->nextTilePosition.x)e->angle=1<<13;
else if(e->tilePosition.x>e->nextTilePosition.x)e->angle=-(1<<13);
else if(e->tilePosition.z<e->nextTilePosition.z)e->angle=0;
else if(e->tilePosition.z>e->nextTilePosition.z)e->angle=(1<<14);
e->object.position.x=e->tilePosition.x*TILESIZE*2+TILESIZE+(((e->nextTilePosition.x-e->tilePosition.x)*TILESIZE*2)*e->progress)/speed;
e->object.position.z=e->tilePosition.z*TILESIZE*2+TILESIZE+(((e->nextTilePosition.z-e->tilePosition.z)*TILESIZE*2)*e->progress)/speed;
if(e->modelInstance.currentAnim!=ANIMPAIN && e->modelInstance.currentAnim!=ANIMATTACK && dist>32)e->progress++;
}else e->task=0;
if(e->progress>=speed)
{
e->progress=0;
e->tilePosition=e->nextTilePosition;
bool r=popPathCell(&e->path, &e->nextTilePosition.x, &e->nextTilePosition.z);
if(!r)
{
e->nextTilePosition=e->tilePosition;
e->path.first=NULL;
}
}
}else changeAnimation(&e->modelInstance,ANIMIDLE,false);
}
s16 v=updateSimplePhysicsObjectRoom(e->r,&e->object);
if(v>=0)e->tilePosition.y=v;
updateAnimation(&e->modelInstance);
}
void updateEnemies(void)
{
int i;
for(i=0;i<NUMENEMIES;i++)
{
if(enemy[i].used){updateEnemy(&enemy[i]);}
}
}
void freeEnemies(void)
{
freeMd2Model(&enemyModel);
}

273
arm9/source/game/game.c Normal file
View File

@ -0,0 +1,273 @@
#include "game/game_main.h"
bool currentBuffer;
int mainBG;
u16 mainScreen[256*192];
PrintConsole bottomScreen;
extern roomEdit_struct roomEdits[NUMROOMEDITS];
void initGame(void)
{
int oldv=getMemFree();
NOGBA("mem free : %dko (%do)",getMemFree()/1024,getMemFree());
NOGBA("initializing...");
videoSetMode(MODE_5_3D | DISPLAY_BG3_ACTIVE);
videoSetModeSub(MODE_0_2D);
glInit();
vramSetPrimaryBanks(VRAM_A_TEXTURE,VRAM_B_TEXTURE,VRAM_C_LCD,VRAM_D_MAIN_BG_0x06000000);
vramSetBankH(VRAM_H_SUB_BG);
vramSetBankI(VRAM_I_SUB_BG_0x06208000);
glEnable(GL_TEXTURE_2D);
// glEnable(GL_ANTIALIAS);
glEnable(GL_BLEND);
glClearColor(31,31,0,31);
glClearPolyID(63);
glClearDepth(0x7FFF);
glViewport(0,0,255,191);
initVramBanks(1);
initTextures();
initPathfindingGlobal();
initRoomEditor();
initCamera(NULL);
initPlayer(NULL);
initParticles();
initLightMaps();
initMaterials();
initDoorCollection(NULL);
loadMaterialSlices("slices.ini");
loadMaterials("materials.ini");
initEnemies();
readMap("lalala.map", true);
currentBuffer=false;
getVramStatus();
NOGBA("START mem free : %dko (%do)",getMemFree()/1024,getMemFree());
NOGBA("vs mem free : %dko (%do)",oldv/1024,oldv);
fadeIn();
mainBG=bgInit(3, BgType_Bmp16, BgSize_B16_256x256, 0, 0);
bgSetPriority(mainBG, 0);
REG_BG0CNT=BG_PRIORITY(3);
consoleInit(&bottomScreen, 3, BgType_Text4bpp, BgSize_T_256x256, 16, 0, false, true);
consoleSelect(&bottomScreen);
initPortals();
//PHYSICS
initPI9();
// createBox(vect(TILESIZE,TILESIZE,TILESIZE),vect(-inttof32(0),HEIGHTUNIT*16,-inttof32(0)),inttof32(1));
// createBox(vectMultInt(vect(TILESIZE,TILESIZE,TILESIZE),4),vectMultInt(vect(-inttof32(0),HEIGHTUNIT*16,-inttof32(0)),4),inttof32(1));
// createAAR(vectMultInt(vect(TILESIZE*24,0,TILESIZE*24),4), vectMultInt(vect(-TILESIZE*12,HEIGHTUNIT*11,-TILESIZE*12),4), vect(0,inttof32(1),0));
// createAAR(vectMultInt(vect(0,HEIGHTUNIT*16,TILESIZE*16),4), vectMultInt(vect(TILESIZE*5,HEIGHTUNIT*11,-TILESIZE*4),4), vect(-inttof32(1),0,0));
transferRectangles(&roomEdits[0].data);
makeGrid();
startPI();
}
extern md2Model_struct enemyModel;
bool testbool=false;
bool switchPortal=false;
portal_struct *currentPortal, *previousPortal;
extern md2Model_struct enemyModel; //TEMP
void postProcess(u16* scrP, u32* stackP);
bool orangeSeen, blueSeen;
extern u16** stackEnd;
u16* ppStack[192*16];
extern u8 selectID;
extern OBB_struct objects[NUMOBJECTS];
static inline void render1(void)
{
scanKeys();
playerControls(NULL);
// if(keysDown()&KEY_X)createBox(vect(TILESIZE,TILESIZE,TILESIZE),vect(-inttof32(0),HEIGHTUNIT*26,-inttof32(0)),inttof32(1));
if(keysDown()&KEY_X)createBox(vectMultInt(vect(192,192,192),4),vectMultInt(vect(-inttof32(0),HEIGHTUNIT*26,-inttof32(0)),4),inttof32(1));
if(keysDown()&KEY_B)applyForce(selectID, vect(-TILESIZE*4,0,0), vect(0,inttof32(150),0));
if(keysDown()&KEY_Y){selectID++;selectID%=NUMOBJECTS;if(!objects[selectID].used)selectID=0;}
if(objects[selectID].used && keysHeld()&KEY_A)
{
camera_struct* c=getPlayerCamera();
// applyForce(selectID, vect(0,0,0), vect(0,inttof32(2)*5,0));
// applyForce(selectID, vect(0,0,0), vectMultInt(normalize(vectDifference(vectMultInt(addVect(getPlayer()->object->position,vectDivInt(vect(-c->transformationMatrix[2],-c->transformationMatrix[5],-c->transformationMatrix[8]),8)),4),objects[selectID].position)),100));
setVelocity(selectID, vectMultInt(/*normalize*/(vectDifference(vectMultInt(addVect(getPlayer()->object->position,vectDivInt(vect(-c->transformationMatrix[2],-c->transformationMatrix[5],-c->transformationMatrix[8]),8)),4),objects[selectID].position)),4));
// updatePlayerPI(NULL);
}
updatePlayer(NULL);
updatePortals();
// if(currentPortal)GFX_CLEAR_COLOR=currentPortal->color|(31<<16);
// else GFX_CLEAR_COLOR=0;
GFX_CLEAR_COLOR=0;
while(fifoCheckValue32(FIFO_USER_08)){u32 cnt=fifoGetValue32(FIFO_USER_08);NOGBA("ALERT %d \n",cnt-4096);}
projectCamera(NULL);
glPushMatrix();
glScalef32(SCALEFACT,SCALEFACT,SCALEFACT);
transformCamera(NULL);
drawRoomsGame(128);
updateParticles();
drawParticles();
glPushMatrix();
glScalef32(inttof32(1)/4,inttof32(1)/4,inttof32(1)/4);
drawOBBs();
// drawAARs();
glPopMatrix(1);
drawPortal(&portal1);
drawPortal(&portal2);
glPopMatrix(1);
glFlush(0);
}
static inline void render2(void)
{
if(!(orangeSeen||blueSeen)){previousPortal=NULL;return;}
if((switchPortal||!blueSeen)&&orangeSeen)currentPortal=&portal1;
else currentPortal=&portal2;
previousPortal=currentPortal;
switchPortal^=1;
glClearColor(0,0,0,31);
updatePortalCamera(currentPortal, NULL);
projectCamera(&currentPortal->camera);
glPushMatrix();
glScalef32(SCALEFACT,SCALEFACT,SCALEFACT);
transformCamera(&currentPortal->camera);
drawRoomsGame(0);
glPushMatrix();
camera_struct* c=getPlayerCamera();
glTranslatef32(c->position.x,c->position.y-TILESIZE*3,c->position.z);
glRotateYi(c->angle.y+16384);
renderModelFrameInterp(0,0,0,&enemyModel,POLY_ALPHA(31)|POLY_CULL_FRONT);
glPopMatrix(1);
glPushMatrix();
glScalef32(inttof32(1)/4,inttof32(1)/4,inttof32(1)/4);
drawOBBs();
// drawAARs();
glPopMatrix(1);
glPopMatrix(1);
glFlush(0);
}
static inline void postProcess1(void)
{
postProcess(mainScreen,ppStack);
}
static inline void postProcess2(void)
{
u16* p1=mainScreen;
u16* p2=portal1.viewPoint;
u16* p3=portal2.viewPoint;
u16** stp;
u16* scrp=NULL, oscrp=NULL;
blueSeen=orangeSeen=false;
for(stp=ppStack;stp<stackEnd;stp++)
{
scrp=(*stp)-p1;
int val=(int)scrp;
if(val>256*192*2){blueSeen=true;val-=256*192*2;scrp=(u16*)val;if((int)scrp-(int)oscrp>0)dmaCopy((void*)((int)p3+(int)oscrp*2), (void*)((int)bgGetGfxPtr(mainBG)+(int)oscrp*2), (int)((int)scrp-(int)oscrp)*2);}
else if(val>256*192){orangeSeen=true;val-=256*192;scrp=(u16*)val;if((int)scrp-(int)oscrp>0)dmaCopy((void*)((int)p2+(int)oscrp*2), (void*)((int)bgGetGfxPtr(mainBG)+(int)oscrp*2), (int)((int)scrp-(int)oscrp)*2);}
else if((int)scrp-(int)oscrp>0){dmaCopy((void*)((int)p1+(int)oscrp*2), (void*)((int)bgGetGfxPtr(mainBG)+(int)oscrp*2), (int)((int)scrp-(int)oscrp)*2);}
oscrp=scrp;
}
}
void gameFrame(void)
{
int lala;
switch(currentBuffer)
{
case false:
iprintf("\x1b[0;0H");
cpuStartTiming(0);
postProcess1();
// iprintf("frm 1 : %d \n",cpuGetTiming());
render1();
// iprintf("frm 1 : %d \n",cpuEndTiming());
swiWaitForVBlank();
if(previousPortal)dmaCopy(VRAM_C, previousPortal->viewPoint, 256*192*2);
setRegCapture(true, 0, 15, 2, 0, 3, 1, 0);
break;
case true:
cpuStartTiming(0);
postProcess2();
// iprintf("frm 2 : %d \n",cpuGetTiming());
render2();
listenPI9();
// iprintf("frm 2 : %d \n",cpuEndTiming());
swiWaitForVBlank();
dmaCopy(VRAM_C, mainScreen, 256*192*2);
setRegCapture(true, 0, 15, 2, 0, 3, 1, 0);
break;
}
currentBuffer^=1;
}
void killGame(void)
{
fadeOut();
NOGBA("KILLING IT");
wipeMapEdit();
freeEnemies();
freePlayer();
freeState(NULL);
NOGBA("START mem free : %dko (%do)",getMemFree()/1024,getMemFree());
}
void gameVBL(void)
{
}

View File

@ -0,0 +1,76 @@
#include "game/game_main.h"
lightMapSlots_struct lightMapSlots[LIGHTMAPSLOTS];
void initLightMaps(void)
{
int i;
u16 palette[8];
for(i=0;i<8;i++){u8 v=(i*31)/7;palette[i]=RGB15(v,v,v);}
for(i=0;i<LIGHTMAPSLOTS;i++)
{
lightMapSlots[i].used=false;
lightMapSlots[i].r=NULL;
lightMapSlots[i].mtl=createReservedTextureBufferA5I3(NULL,palette,32,32,(void*)(0x6800000+0x0020000*(i+1)));
}
}
lightMapSlots_struct* getLightMapSlot(void)
{
int i;
for(i=0;i<LIGHTMAPSLOTS;i++)
{
if(!lightMapSlots[i].used)
{
lightMapSlots[i].used=true;
lightMapSlots[i].r=NULL;
return &lightMapSlots[i];
}
}
return NULL;
}
void loadLightMap(room_struct* r)
{
if(!r||!r->lightMapBuffer||(r->lmSlot&&r->lmSlot->used))return;
NOGBA("here?");
r->lmSlot=getLightMapSlot();
if(!r->lmSlot)return;
r->lmSlot->r=r;
changeTextureSizeA5I3(r->lmSlot->mtl,r->lmSize.x,r->lmSize.y);
loadToBank(r->lmSlot->mtl,r->lightMapBuffer);
}
void unloadLightMap(room_struct* r)
{
if(!r||!r->lightMapBuffer)return;
if(!r->lmSlot)return;
r->lmSlot->used=false;
r->lmSlot=NULL;
}
void unloadLightMaps(room_struct* r, room_struct* r2)
{
int i;
for(i=0;i<LIGHTMAPSLOTS;i++)
{
if(lightMapSlots[i].used && &lightMapSlots[i]!=r->lmSlot && &lightMapSlots[i]!=r2->lmSlot)
{
room_struct* r3=lightMapSlots[i].r;
if(r3 && r3->lmSlot==&lightMapSlots[i])r3->lmSlot=NULL;
lightMapSlots[i].r=NULL;
lightMapSlots[i].used=false;
}
}
}
extern roomEdit_struct roomEdits[NUMROOMEDITS];
void unloadAllLightMaps(room_struct* r)
{
int i;
for(i=0;i<NUMROOMEDITS;i++)
{
if(!roomEdits[i].used && &roomEdits[i].data!=r && roomEdits[i].data.lmSlot)unloadLightMap(&roomEdits[i].data);
}
}

759
arm9/source/game/map.c Normal file
View File

@ -0,0 +1,759 @@
#include "game/game_main.h"
#define A5I3
extern doorCollection_struct doorCollection;
void initRectangleList(rectangleList_struct* p)
{
p->first=NULL;
p->num=0;
}
rectangle_struct* addRectangle(rectangle_struct r, rectangleList_struct* p)
{
listCell_struct* pc=(listCell_struct*)malloc(sizeof(listCell_struct));
pc->next=p->first;
pc->data=r;
p->first=pc;
p->num++;
return &pc->data;
}
void popRectangle(rectangleList_struct* p)
{
p->num--;
if(p->first)
{
listCell_struct* pc=p->first;
p->first=pc->next;
free(pc);
}
}
void initRectangle(rectangle_struct* rec, vect3D pos, vect3D size)
{
int x, y;
s8 sign=1;
rec->position=pos;
rec->size=size;
rec->normal=vect(0,0,0);
if(!size.x)
{
x=abs(size.y)*LIGHTMAPRESOLUTION;
y=abs(size.z)*LIGHTMAPRESOLUTION;
rec->normal.x=inttof32(1);
}else if(!size.y)
{
x=abs(size.x)*LIGHTMAPRESOLUTION;
y=abs(size.z)*LIGHTMAPRESOLUTION;
rec->normal.y=inttof32(-1);
}else{
x=abs(size.x)*LIGHTMAPRESOLUTION;
y=abs(size.y)*LIGHTMAPRESOLUTION;
rec->normal.z=inttof32(1);
}
sign*=(size.x>=0)?1:-1;
sign*=(size.y>=0)?1:-1;
sign*=(size.z>=0)?1:-1;
rec->normal=vect(rec->normal.x*sign,rec->normal.y*sign,rec->normal.z*sign);
// NOGBA("n : %d %d %d",rec->normal.x,rec->normal.y,rec->normal.z);
rec->lmSize.x=x;
rec->lmSize.y=y;
rec->hide=false;
}
vect3D getUnitVect(rectangle_struct* rec)
{
vect3D u=vect(0,0,0);
vect3D size=rec->size;
if(size.x>0)u.x=(TILESIZE*2)/LIGHTMAPRESOLUTION;
else if(size.x)u.x=-(TILESIZE*2)/LIGHTMAPRESOLUTION;
if(size.y>0)u.y=HEIGHTUNIT/LIGHTMAPRESOLUTION;
else if(size.y)u.y=-HEIGHTUNIT/LIGHTMAPRESOLUTION;
if(size.z>0)u.z=(TILESIZE*2)/LIGHTMAPRESOLUTION;
else if(size.z)u.z=-(TILESIZE*2)/LIGHTMAPRESOLUTION;
return u;
}
bool collideLineMap(room_struct* r, rectangle_struct* rec, vect3D l, vect3D u, int32 d, vect3D* i)
{
listCell_struct *lc=r->rectangles.first;
vect3D v;
while(lc)
{
if(&lc->data!=rec)
{
// NOGBA("%p vs %p",rec,&lc->data);
if(collideLineRectangle(&lc->data,l,u,d,NULL,&v)){if(i)*i=v;return true;}
}
lc=lc->next;
}
return false;
}
rectangle_struct* collideLineMapClosest(room_struct* r, rectangle_struct* rec, vect3D l, vect3D u, int32 d, vect3D* i)
{
listCell_struct *lc=r->rectangles.first;
vect3D v;
int32 lowestK=d;
rectangle_struct* hit=NULL;
while(lc)
{
if(&lc->data!=rec)
{
// NOGBA("%p vs %p",rec,&lc->data);
int32 k;
// if(collideLineRectangle(&lc->data,l,u,d,&k,&v)){if(k<lowestK){*i=v;lowestK=k;}}
if(collideLineRectangle(&lc->data,l,u,lowestK,&k,&v)){if(k<lowestK){*i=v;lowestK=k;hit=&lc->data;}}
}
lc=lc->next;
}
return hit;
}
u8 computeLighting(vect3D l, int32 intensity, vect3D p, rectangle_struct* rec, room_struct* r)
{
int32 dist=sqDistance(l,p);
int32 rdist=sqrtf32(dist);
dist=mulf32(dist,dist);
// int32 dist=distance(l,p);
if(dist<intensity)
{
vect3D u=vectDifference(p,l);
u=divideVect(u,rdist);
// NOGBA("dv : %d, %d, %d",u.x,u.y,u.z);
if(collideLineMap(r, rec, l, u, rdist, NULL))return 0;
int32 v=dotProduct(u,rec->normal);
v=max(0,v);
v*=3;
v/=4;
v+=inttof32(1)/4;
// int32 v=inttof32(1);
return mulf32(v,(31-((dist*31)/intensity)));
}else return 0;
}
u8 computeLightings(entityCollection_struct* ec, vect3D p, rectangle_struct* rec, room_struct* r)
{
if(ec)
{
int v=0;
int i;
for(i=0;i<ENTITYCOLLECTIONNUM;i++)
{
if(ec->entity[i].used && ec->entity[i].type==lightEntity && ec->entity[i].data)
{
entity_struct* e=&ec->entity[i];
lightData_struct* d=ec->entity[i].data;
// NOGBA("%d LIGHT ! %d, %d, %d, %d",i,e->position.x,e->position.y,e->position.z,d->intensity);
v+=computeLighting(vect(e->position.x*TILESIZE*2,e->position.z*HEIGHTUNIT,e->position.y*TILESIZE*2), d->intensity, p, rec, r);
}
}
return (u8)(31-min(max(v,0),31));
}
return 0;
}
void fillBuffer(u8* buffer, vect2D p, vect2D s, u8* v, bool rot, int w)
{
int i;
// u8 vt=(rand()%31)<<3;
if(!rot)
{
for(i=0;i<s.x;i++)
{
int j;
for(j=0;j<s.y;j++)
{
buffer[p.x+i+(p.y+j)*w]=v[i+j*s.x];
// buffer[p.x+i+(p.y+j)*w]=vt;
}
}
}else{
for(i=0;i<s.x;i++)
{
int j;
for(j=0;j<s.y;j++)
{
buffer[p.x+j+(p.y+i)*w]=v[i+j*s.x];
// buffer[p.x+j+(p.y+i)*w]=vt;
}
}
}
}
void addRoomRectangle(room_struct* r, entityCollection_struct* ec, rectangle_struct rec, material_struct* mat)
{
if((!rec.size.x && (!rec.size.z || !rec.size.y)) || (!rec.size.y && !rec.size.z))return;
initRectangle(&rec, rec.position, rec.size);
if(mat)rec.material=mat;
else{
u16 x=rec.position.x;
u16 y=rec.position.z;
if(rec.size.x<0)x+=rec.size.x;
if(rec.size.z<0)y+=rec.size.z;
if(x>=r->width)x=r->width-1;
if(y>=r->height)y=r->height-1;
rec.material=r->materials[x+y*r->width];
}
// NOGBA("mat : %d",getMaterialID(rec.material));
/*rectangle_struct* rec2=*/addRectangle(rec, &r->rectangles);
// if(ec)generateLightmap(ec, rec2, r);
}
void generateLightmap(entityCollection_struct* ec, rectangle_struct* rec, room_struct* r, u8* b)
{
if(rec && r->lightMap)// && rec->lightMap)
{
u16 x=rec->lmSize.x, y=rec->lmSize.y;
// u16 x=rec->lightMap->width, y=rec->lightMap->height;
u8* data=malloc(x*y);
vect3D p=vect(rec->position.x*TILESIZE*2-TILESIZE,rec->position.y*HEIGHTUNIT,rec->position.z*TILESIZE*2-TILESIZE);
NOGBA("p : %d, %d, %d",p.x,p.y,p.z);
// u16 palette[256];
// u16 palette[8];
int i;
// for(i=0;i<256;i++){u8 v=i%32;palette[i]=RGB15(v,v,v);}
// for(i=0;i<8;i++){u8 v=0;palette[i]=RGB15(v,v,v);}
vect3D u=getUnitVect(rec);
for(i=0;i<x;i++)
{
int j;
for(j=0;j<y;j++)
{
// data[i+j*rec->lightMap->width]=max(max(31-j,31-i),0);
#ifdef A5I3
if(!rec->size.x)data[i+j*x]=computeLightings(ec,addVect(p,vect(0,i*u.y+u.y/2,j*u.z+u.z/2)),rec,r)<<3;
else if(rec->size.y)data[i+j*x]=computeLightings(ec,addVect(p,vect(i*u.x+u.x/2,j*u.y+u.y/2,0)),rec,r)<<3;
else data[i+j*x]=computeLightings(ec,addVect(p,vect(i*u.x+u.x/2,0,j*u.z+u.z/2)),rec,r)<<3;
#else
if(!rec->size.x)data[i+j*x]=computeLightings(ec,addVect(p,vect(0,i*u.y+u.y/2,j*u.z+u.z/2)),rec,r);//<<3;
else if(rec->size.y)data[i+j*x]=computeLightings(ec,addVect(p,vect(i*u.x+u.x/2,j*u.y+u.y/2,0)),rec,r);//<<3;
else data[i+j*x]=computeLightings(ec,addVect(p,vect(i*u.x+u.x/2,0,j*u.z+u.z/2)),rec,r);//<<3;
#endif
}
}
NOGBA("p2");
fillBuffer(b, vect2(rec->lmPos.x,rec->lmPos.y), vect2(rec->lmSize.x,rec->lmSize.y), data, rec->rot, r->lmSize.x);
NOGBA("p3");
// loadPartToBank(r->lightMap,data,x,y,rec->lmPos.x,rec->lmPos.y,rec->rot);
// loadPaletteToBank(rec->lightMap,palette,8*2);
free(data);
NOGBA("p4");
}else NOGBA("NOTHING?");
}
void generateLightmaps(roomEdit_struct* re, room_struct* r, entityCollection_struct* ec)
{
if(!re || !r || !ec || re->lightUpToDate)return;
listCell_struct *lc=r->rectangles.first;
getRoomDoorRectangles(NULL, &re->data);
rectangle2DList_struct rl;
initRectangle2DList(&rl);
while(lc)
{
insertRectangle2DList(&rl,(rectangle2D_struct){vect2(0,0),vect2(abs(lc->data.size.x?lc->data.size.x:lc->data.size.y)*LIGHTMAPRESOLUTION,abs((lc->data.size.y&&lc->data.size.x)?(lc->data.size.y):lc->data.size.z)*LIGHTMAPRESOLUTION),&lc->data,false});
lc=lc->next;
}
int i;
doorCollection_struct* dc=&doorCollection;
for(i=0;i<NUMDOORS;i++)
{
if(dc->door[i].used)
{
door_struct* d=&dc->door[i];
if(r==d->primaryRoom)
{
rectangle_struct* rec=&d->primaryRec;
vect2D s=vect2(abs(rec->size.x?rec->size.x:rec->size.y)*LIGHTMAPRESOLUTION,abs((rec->size.y&&rec->size.x)?(rec->size.y):rec->size.z)*LIGHTMAPRESOLUTION);
rec->lmSize=vect(s.x,s.y,0);
insertRectangle2DList(&rl,(rectangle2D_struct){vect2(0,0),s,rec,false});
}
if(r==d->secondaryRoom)
{
rectangle_struct* rec=&d->secondaryRec;
vect2D s=vect2(abs(rec->size.x?rec->size.x:rec->size.y)*LIGHTMAPRESOLUTION,abs((rec->size.y&&rec->size.x)?(rec->size.y):rec->size.z)*LIGHTMAPRESOLUTION);
rec->lmSize=vect(s.x,s.y,0);
insertRectangle2DList(&rl,(rectangle2D_struct){vect2(0,0),s,rec,false});
}
}
}
short w=32, h=32;
// packRectangles(&rl, 512, 256);
// packRectangles(&rl, w, h);
bool rr=packRectanglesSize(&rl, &w, &h);
r->lmSize=vect(w,h,0);
NOGBA("done : %d %dx%d",(int)rr,w,h);
if(!r->lightMap)
{
#ifdef A5I3
u16 palette[8];
for(i=0;i<8;i++){u8 v=(i*31)/7;palette[i]=RGB15(v,v,v);}
r->lightMap=createReservedTextureBufferA5I3(NULL,palette,w,h,(void*)(0x6800000+0x0020000));
#else
u16 palette[256];
for(i=0;i<256;i++){u8 v=i%32;palette[i]=RGB15(v,v,v);}
r->lightMap=createTextureBuffer(NULL,palette,w,h);
#endif
}else changeTextureSizeA5I3(r->lightMap,w,h);
if(r->lightMapBuffer)free(r->lightMapBuffer);
r->lightMapBuffer=malloc(w*h);
// fillBuffer(buffer, vect2(0,0), vect2(512,256), 0, false);
lc=r->rectangles.first;
while(lc)
{
generateLightmap(ec, &lc->data, r, r->lightMapBuffer);
lc=lc->next;
}
for(i=0;i<NUMDOORS;i++)
{
if(dc->door[i].used)
{
door_struct* d=&dc->door[i];
if(r==d->primaryRoom)generateLightmap(ec, &d->primaryRec, r, r->lightMapBuffer);
if(r==d->secondaryRoom)generateLightmap(ec, &d->secondaryRec, r, r->lightMapBuffer);
}
}
NOGBA("done generating, loading...");
loadToBank(r->lightMap,r->lightMapBuffer);
NOGBA("loaded.");
freeRectangle2DList(&rl);
NOGBA("freed.");
re->lightUpToDate=true;
}
void removeRectangles(room_struct* r)
{
while(r->rectangles.num)popRectangle(&r->rectangles);
}
vect3D convertNormal(vect3D n, int32 v)
{
if(n.x>0)n.x=v;
else if(n.x<0)n.x=-v;
if(n.y>0)n.y=v;
else if(n.y<0)n.y=-v;
if(n.z>0)n.z=v;
else if(n.z<0)n.z=-v;
return n;
}
vect3D getOverlayRectanglePosition(rectangle_struct rec)
{
int32 v=LIGHTCONST;
vect3D u=addVect(convertVect(rec.position),convertNormal(rec.normal,-LIGHTCONST));
if(rec.size.x>0)u.x-=v;
else if(rec.size.x)u.x+=v;
if(rec.size.y>0)u.y-=v;
else if(rec.size.y)u.y+=v;
if(rec.size.z>0)u.z-=v;
else if(rec.size.z)u.z+=v;
return u;
}
vect3D getOverlayRectangleSize(rectangle_struct rec)
{
int32 v=LIGHTCONST;
vect3D u=convertSize(rec.size);
if(u.x>0)u.x+=2*v;
else if(u.x)u.x-=2*v;
if(u.y>0)u.y+=2*v;
else if(u.y)u.y-=2*v;
if(u.z>0)u.z+=2*v;
else if(u.z)u.z-=2*v;
return u;
}
void drawRect(rectangle_struct rec, vect3D pos, vect3D size, bool c)
{
// if(c)glPolyFmt(POLY_ALPHA(31) | POLY_CULL_BACK);
// else glPolyFmt(POLY_DECAL | POLY_ALPHA(31) | POLY_CULL_BACK);
// vect3D size=vect(rec.size.x*TILESIZE*2,rec.size.y*HEIGHTUNIT,rec.size.z*TILESIZE*2);
// if(!c)applyMTL(rec.lightMap);
// if(c)unbindMtl();
// glColor3b(255,255,255);
// NOGBA("%d %d",pos.x,pos.x);
if(rec.hide)return;
vect3D p1=vect(inttot16(rec.lmPos.x),inttot16(rec.lmPos.y),0);
vect3D p2=vect(inttot16(rec.lmPos.x+rec.lmSize.x-1),inttot16(rec.lmPos.y+rec.lmSize.y-1),0);
int32 t1=TEXTURE_PACK(p1.x, p1.y);
int32 t2=TEXTURE_PACK(p1.x, p2.y);
int32 t3=TEXTURE_PACK(p2.x, p2.y);
int32 t4=TEXTURE_PACK(p2.x, p1.y);
if(rec.rot)
{
p2=vect(inttot16(rec.lmPos.x+rec.lmSize.y-1),inttot16(rec.lmPos.y+rec.lmSize.x-1),0);
t1=TEXTURE_PACK(p1.x, p1.y);
t4=TEXTURE_PACK(p1.x, p2.y);
t3=TEXTURE_PACK(p2.x, p2.y);
t2=TEXTURE_PACK(p2.x, p1.y);
}
int32 t[4];
if(c)
{
// p1=vect(0,0,0);
// if(!rec.size.x)p2=vect(inttot16(16*rec.size.y-1),inttot16(64*rec.size.z-1),0);
// else if(!rec.size.y)p2=vect(inttot16(64*rec.size.x-1),inttot16(64*rec.size.z-1),0);
// else p2=vect(inttot16(64*rec.size.x-1),inttot16(16*rec.size.y-1),0);
// t1=TEXTURE_PACK(p1.x, p1.y);
// t2=TEXTURE_PACK(p1.x, p2.y);
// t3=TEXTURE_PACK(p2.x, p2.y);
// t4=TEXTURE_PACK(p2.x, p1.y);
c=false;
glColor3b(255,255,255);
bindMaterial(rec.material,&rec,t);
t1=t[0];
t2=t[1];
t3=t[2];
t4=t[3];
}
if(!rec.size.x)
{
glBegin(GL_QUAD);
GFX_TEX_COORD = t1;
glVertex3v16(pos.x, pos.y, pos.z);
GFX_TEX_COORD = t2;
glVertex3v16(pos.x, pos.y, pos.z+size.z);
GFX_TEX_COORD = t3;
glVertex3v16(pos.x, pos.y+size.y, pos.z+size.z);
GFX_TEX_COORD = t4;
glVertex3v16(pos.x, pos.y+size.y, pos.z);
}else if(rec.size.y){
glBegin(GL_QUAD);
GFX_TEX_COORD = t1;
glVertex3v16(pos.x, pos.y, pos.z);
GFX_TEX_COORD = t2;
glVertex3v16(pos.x, pos.y+size.y, pos.z);
GFX_TEX_COORD = t3;
glVertex3v16(pos.x+size.x, pos.y+size.y, pos.z);
GFX_TEX_COORD = t4;
glVertex3v16(pos.x+size.x, pos.y, pos.z);
}else{
glBegin(GL_QUAD);
GFX_TEX_COORD = t1;
glVertex3v16(pos.x, pos.y, pos.z);
GFX_TEX_COORD = t2;
glVertex3v16(pos.x, pos.y, pos.z+size.z);
GFX_TEX_COORD = t3;
glVertex3v16(pos.x+size.x, pos.y, pos.z+size.z);
GFX_TEX_COORD = t4;
glVertex3v16(pos.x+size.x, pos.y, pos.z);
}
}
void transferRectangle(vect3D pos, vect3D size, vect3D normal)
{
if(size.x<0){pos.x+=size.x;size.x=-size.x;}
if(size.y<0){pos.y+=size.y;size.y=-size.y;}
if(size.z<0){pos.z+=size.z;size.z=-size.z;}
createAAR(vectMultInt(size,4), vectMultInt(pos,4), vectMultInt(normal,-1));
}
void transferRectangles(room_struct* r)
{
listCell_struct *lc=r->rectangles.first;
int i=0;
while(lc)
{
transferRectangle(addVect(convertSize(vect(r->position.x,0,r->position.y)),convertVect(lc->data.position)),convertSize(lc->data.size),lc->data.normal);
lc=lc->next;
i++;
if(!(i%8))swiWaitForVBlank();
}
}
void drawRectangles(room_struct* r, u8 mode)
{
glPolyFmt(POLY_ALPHA(31) | POLY_CULL_BACK);
// glPolyFmt(POLY_ALPHA(31) | POLY_CULL_NONE);
listCell_struct *lc=r->rectangles.first;
unbindMtl();
GFX_COLOR=RGB15(31,31,31);
int i=0;
while(lc)
{
drawRect(lc->data,convertVect(lc->data.position),convertSize(lc->data.size),true);
i++;
lc=lc->next;
}
if(mode&6)
{
lc=r->rectangles.first;
glPolyFmt(POLY_ALPHA(31) | (1<<14) | POLY_CULL_BACK);
if(mode&2)applyMTL(r->lightMap);
else if(r->lmSlot)applyMTL(r->lmSlot->mtl);
GFX_COLOR=RGB15(31,31,31);
while(lc)
{
drawRect(lc->data,convertVect(lc->data.position),convertSize(lc->data.size),false);
lc=lc->next;
}
}
if(mode&128 && currentPortal)
{
lc=r->rectangles.first;
glPolyFmt(POLY_ALPHA(31) | POLY_CULL_FRONT);
unbindMtl();
GFX_COLOR=currentPortal->color;
while(lc)
{
drawRect(lc->data,convertVect(lc->data.position),convertSize(lc->data.size),false);
lc=lc->next;
}
}
glPolyFmt(POLY_ALPHA(31) | POLY_CULL_BACK);
}
bool compare(room_struct* r, u8 v, int i, int j)
{
if(i<0 || j<0 || i>r->width-1 || j>r->height-1)return false;
u8 v2=r->floor[i+j*r->width];
u8 v3=r->ceiling[i+j*r->width];
if(v2>=v3)return false;
return (v2<=v+MAXSTEP);
}
void getPathfindingData(room_struct* r)
{
if(!r)return;
// if(r->pathfindingData)free(r->pathfindingData);
r->pathfindingData=malloc(sizeof(u8)*r->width*r->height);
if(!r->pathfindingData)return;
int i, j;
for(i=0;i<r->width;i++)
{
for(j=0;j<r->height;j++)
{
u8 v=r->floor[i+j*r->width];
u8* v2=&r->pathfindingData[i+j*r->width];
*v2=0;
if(compare(r, v, i, j-1))*v2|=DIRUP;
if(compare(r, v, i, j+1))*v2|=DIRDOWN;
if(compare(r, v, i-1, j))*v2|=DIRLEFT;
if(compare(r, v, i+1, j))*v2|=DIRRIGHT;
// if(i==5)NOGBA("v %d : %d %d %d %d",j,(*v2)&DIRUP,(*v2)&DIRDOWN,(*v2)&DIRLEFT,(*v2)&DIRRIGHT);
// *v2=DIRUP|DIRDOWN|DIRLEFT|DIRRIGHT;
}
}
NOGBA("got PF data %d %d",r->width,r->height);
}
void initRoom(room_struct* r, u16 w, u16 h, vect3D p)
{
if(r)
{
r->width=w;
r->height=h;
r->position=p;
r->lmSlot=NULL;
initRectangleList(&r->rectangles);
if(r->height && r->width)
{
r->floor=malloc(r->height*r->width);
r->ceiling=malloc(r->height*r->width);
r->materials=malloc(r->height*r->width*sizeof(material_struct*));
int i;for(i=0;i<r->height*r->width;i++){r->floor[i]=DEFAULTFLOOR;r->ceiling[i]=DEFAULTCEILING;r->materials[i]=NULL;}
}else {r->floor=r->ceiling=NULL;}
r->lightMap=NULL;
r->lightMapBuffer=NULL;
r->pathfindingData=NULL;
r->doorWay=NULL;
}
}
void getDoorWayData(doorCollection_struct* dc, room_struct* r)
{
if(!r || r->doorWay)return;
if(!dc)dc=&doorCollection;
r->doorWay=malloc(sizeof(void*)*(r->width+r->height)*4);
int i, j;
void** dw=r->doorWay;
for(j=0;j<2;j++)for(i=0;i<r->width;i++)
{
door_struct* d=inDoorWay(NULL, r, i, j-2, false, true);
if(d){dw[i+j*r->width]=(void*)d;}
else
{
d=inDoorWay(NULL, r, i, j-2, true, true);
if(d){dw[i+j*r->width]=(void*)d;}
else dw[i+j*r->width]=NULL;
}
}
dw=&r->doorWay[r->width*2];
for(j=0;j<2;j++)for(i=0;i<r->width;i++)
{
door_struct* d=inDoorWay(NULL, r, i, r->height+j, false, true);
if(d)dw[i+j*r->width]=(void*)d;
else
{
d=inDoorWay(NULL, r, i, r->height+j, true, true);
if(d){dw[i+j*r->width]=(void*)d;}
else dw[i+j*r->width]=NULL;
}
}
dw=&r->doorWay[r->width*4];
for(j=0;j<2;j++)for(i=0;i<r->height;i++)
{
door_struct* d=inDoorWay(NULL, r, j-2, i, false, true);
if(d)dw[i+j*r->height]=(void*)d;
else
{
d=inDoorWay(NULL, r, j-2, i, true, true);
if(d)dw[i+j*r->height]=(void*)d;
else dw[i+j*r->height]=NULL;
}
}
dw=&r->doorWay[r->width*4+r->height*2];
for(j=0;j<2;j++)for(i=0;i<r->height;i++)
{
door_struct* d=inDoorWay(NULL, r, r->width+j, i, false, true);
if(d)dw[i+j*r->height]=(void*)d;
else
{
d=inDoorWay(NULL, r, r->width+j, i, true, true);
if(d)dw[i+j*r->height]=(void*)d;
else dw[i+j*r->height]=NULL;
}
}
}
void resizeRoom(room_struct* r, u16 w, u16 h, vect3D p)
{
if(r)
{
if(!r->height || ! r->width || !r->floor || !r->ceiling){initRoom(r, w, h, p);return;}
int i, j;
int h2=h, w2=w;
r->position=p;
u8* temp1=r->floor;
u8* temp2=r->ceiling;
material_struct** temp3=r->materials;
r->floor=malloc(h*w);
r->ceiling=malloc(h*w);
r->materials=malloc(sizeof(material_struct*)*h*w);
if(w>r->width)w2=r->width;
if(h>r->height)h2=r->height;
for(j=0;j<h2;j++){for(i=0;i<w2;i++){r->floor[i+j*w]=temp1[i+j*r->width];r->ceiling[i+j*w]=temp2[i+j*r->width];r->materials[i+j*w]=temp3[i+j*r->width];}for(;i<w;i++){r->floor[i+j*w]=DEFAULTFLOOR;r->ceiling[i+j*w]=DEFAULTCEILING;r->materials[i+j*w]=NULL;}}
for(;j<h;j++)for(i=0;i<w;i++){r->floor[i+j*w]=DEFAULTFLOOR;r->ceiling[i+j*w]=DEFAULTCEILING;r->materials[i+j*w]=NULL;}
r->height=h;
r->width=w;
free(temp1);
free(temp2);
free(temp3);
}
}
void drawRoom(room_struct* r, u8 mode) //obviously temp
{
if(!r)return;
int i, j;
u8* f=r->floor;
if(mode&8)
{
room_struct* r2=getCurrentRoom();
if(r->lmSlot && r2 && r!=r2 && !isDoorOpen(NULL,r,r2)){NOGBA("HAPPENED");r->lmSlot->used=false;r->lmSlot=NULL;}
if(r->lmSlot && !r->lmSlot->used)r->lmSlot=NULL;
if(!r->lmSlot)return;
}
glPushMatrix();
glTranslate3f32(TILESIZE*2*r->position.x, 0, TILESIZE*2*r->position.y);
// glPushMatrix();
// glTranslate3f32(-TILESIZE,0,-TILESIZE);
// glScalef32(TILESIZE*2*r->width,HEIGHTUNIT*31,TILESIZE*2*r->height);
// bool res=BoxTest(0,0,0,inttof32(1),inttof32(1),inttof32(1));
// if(!res)return;
// glPopMatrix(1);
if(mode&1)drawRectangles(r, mode);
else{
unbindMtl();
glBegin(GL_QUAD);
for(j=0;j<r->height;j++)
{
for(i=0;i<r->width;i++)
{
s16 v=HEIGHTUNIT*(*(f++));
s16 x=TILESIZE*2*i, y=TILESIZE*2*j;
glColor3b(255,0,0);
glVertex3v16(-TILESIZE+x, v, -TILESIZE+y);
glColor3b(0,255,0);
glVertex3v16(TILESIZE+x, v, -TILESIZE+y);
glColor3b(0,0,255);
glVertex3v16(TILESIZE+x, v, TILESIZE+y);
glColor3b(255,0,255);
glVertex3v16(-TILESIZE+x, v, TILESIZE+y);
}
}
f=r->ceiling;
for(j=0;j<r->height;j++)
{
for(i=0;i<r->width;i++)
{
s16 v=HEIGHTUNIT*(*(f++));
s16 x=TILESIZE*2*i, y=TILESIZE*2*j;
glColor3b(255,0,0);
glVertex3v16(-TILESIZE+x, v, -TILESIZE+y);
glColor3b(0,255,0);
glVertex3v16(TILESIZE+x, v, -TILESIZE+y);
glColor3b(0,0,255);
glVertex3v16(TILESIZE+x, v, TILESIZE+y);
glColor3b(255,0,255);
glVertex3v16(-TILESIZE+x, v, TILESIZE+y);
}
}
glEnd();
}
glPopMatrix(1);
}
void freeRoom(room_struct* r)
{
if(r)
{
if(r->floor)free(r->floor);
if(r->ceiling)free(r->ceiling);
if(r->materials)free(r->materials);
r->floor=NULL;
r->ceiling=NULL;
r->materials=NULL;
if(r->lightMapBuffer)free(r->lightMapBuffer);
r->lightMapBuffer=NULL;
if(r->pathfindingData)free(r->pathfindingData);
r->pathfindingData=NULL;
if(r->doorWay)free(r->doorWay);
r->doorWay=NULL;
if(r->lightMap)r->lightMap->used=false;
removeRectangles(r);
}
}

View File

@ -0,0 +1,105 @@
#include "game/game_main.h"
particle_struct particles[NUMPARTICLES];
void initParticles(void)
{
int i;
for(i=0;i<NUMPARTICLES;i++)
{
particles[i].used=false;
}
}
void createParticles(vect3D position, vect3D speed, u16 life, u16 color)
{
int i;
for(i=0;i<NUMPARTICLES;i++)
{
if(!particles[i].used)
{
particle_struct* p=&particles[i];
p->used=true;
p->position=position;
p->speed=speed;
p->life=life;
p->color=color;
p->alpha=31;
p->timer=0;
return;
}
}
}
void drawParticle(particle_struct* p)
{
if(!p)return;
glPushMatrix();
// glPolyFmt(POLY_ALPHA(p->alpha) | POLY_CULL_NONE);
glPolyFmt(POLY_ALPHA(p->alpha) | POLY_CULL_NONE | POLY_ID(48));
GFX_COLOR=p->color;
glTranslate3f32(p->position.x,p->position.y,p->position.z);
glScalef32(1<<8,1<<8,1<<8);
glBegin(GL_QUADS);
const u16 size=1;
GFX_VERTEX10=NORMAL_PACK(-size, size, 0);
GFX_VERTEX10=NORMAL_PACK(size, size, 0);
GFX_VERTEX10=NORMAL_PACK(size, -size, 0);
GFX_VERTEX10=NORMAL_PACK(-size, -size, 0);
GFX_VERTEX10=NORMAL_PACK(0, size, -size);
GFX_VERTEX10=NORMAL_PACK(0, size, size);
GFX_VERTEX10=NORMAL_PACK(0, -size, size);
GFX_VERTEX10=NORMAL_PACK(0, -size, -size);
glPopMatrix(1);
}
void drawParticles(void)
{
int i;
unbindMtl();
for(i=0;i<NUMPARTICLES;i++)
{
if(particles[i].used)drawParticle(&particles[i]);
}
}
void updateParticle(particle_struct* p)
{
if(!p)return;
p->position.y-=GRAVITY/4;
p->timer++;
p->alpha=31-(p->timer*31)/p->life;
if(p->timer>p->life)p->used=false;
p->position=addVect(p->position,p->speed);
}
void updateParticles(void)
{
int i;
unbindMtl();
for(i=0;i<NUMPARTICLES;i++)
{
if(particles[i].used)updateParticle(&particles[i]);
}
}
void particleExplosion(vect3D p, int number, u16 color)
{
int i;
const u16 speed=32;
for(i=0;i<number;i++)
{
createParticles(p, vect((rand()%speed)-speed/2,(rand()%speed)-speed/2,(rand()%speed)-speed/2), 30, color);
}
}
void particleExplosionDir(vect3D p, vect3D dir, int number, u16 color)
{
int i;
const u16 speed=8;
for(i=0;i<number;i++)
{
createParticles(p, addVect(dir,vect((rand()%speed)-speed/2,(rand()%speed)-speed/2,(rand()%speed)-speed/2)), 90, color);
}
}

View File

@ -0,0 +1,310 @@
#include "game/game_main.h"
#define PATHCELLNUM (2048)
#define LISTNODENUM (2048)
// #define PNNETSIZE (128*128)
#define PNNETSIZE (64*64)
pathCell_struct pathCellPoolDATA[PATHCELLNUM];
listNode_struct listNodePoolDATA[LISTNODENUM];
pathCell_struct* pathCellPool;
listNode_struct* listNodePool;
pathNode_struct pathNodes[PNNETSIZE];
int lnCnt;
int pcCnt;
void initPathCellPool(void)
{
int i;
for(i=0;i<PATHCELLNUM-1;i++)
{
pathCellPoolDATA[i].next=&pathCellPoolDATA[i+1];
}
pathCellPoolDATA[i].next=NULL;
pathCellPool=&pathCellPoolDATA[0];
pcCnt=PATHCELLNUM;
}
pathCell_struct* getPathCell()
{
if(pathCellPool)
{
pathCell_struct* pc=pathCellPool;
pathCellPool=pathCellPool->next;
pc->next=NULL;
pcCnt--;
return pc;
}else return NULL;
}
void freePathCell(pathCell_struct* pc)
{
if(!pc)return;
pc->next=pathCellPool;
pathCellPool=pc;
pcCnt++;
}
void initListNodePool(void)
{
int i;
for(i=0;i<LISTNODENUM-1;i++)
{
listNodePoolDATA[i].next=&listNodePoolDATA[i+1];
}
listNodePoolDATA[i].next=NULL;
listNodePool=&listNodePoolDATA[0];
lnCnt=LISTNODENUM;
}
listNode_struct* getListNode()
{
if(listNodePool)
{
listNode_struct* pc=listNodePool;
listNodePool=listNodePool->next;
pc->next=NULL;
lnCnt++;
return pc;
}else return NULL;
}
void freeListNode(listNode_struct* ln)
{
if(!ln)return;
ln->next=listNodePool;
listNodePool=ln;
lnCnt--;
}
void initPathfindingGlobal(void)
{
initPathCellPool();
initListNodePool();
}
void initPath(path_struct* p)
{
if(!p)return;
p->first=NULL;
}
void addPathCell(path_struct* p, unsigned char x, unsigned char y)
{
if(!p)return;
pathCell_struct* pc=getPathCell();
if(!pc)return;
pc->X=x;
pc->Y=y;
pc->next=p->first;
p->first=pc;
}
bool popPathCell(path_struct* p, int* x, int* y)
{
if(!p || !p->first){if(x)*x=-1;if(y)*y=-1;return false;}
pathCell_struct* pc=p->first;
p->first=pc->next;
if(x)*x=pc->X;
if(y)*y=pc->Y;
pc->next=NULL;
freePathCell(pc);
// NOGBA("*pop* %p",p->first);
return true;
}
void initOpenList(openList_struct* ol)
{
if(!ol)return;
ol->first=NULL;
}
void addListNode(openList_struct* ol, pathNode_struct* pn)
{
if(!ol || !pn || pn->inList!=noList)return;
listNode_struct* ln=(listNode_struct*)getListNode();
if(!ln)return;
ln->data=pn;
ln->next=ol->first;
ol->first=ln;
}
pathNode_struct* getLowestFcost(openList_struct* ol)
{
if(!ol)return NULL;
listNode_struct* ln=ol->first;
listNode_struct *lowest=ln, *previous=NULL;
while(ln && ln->next)
{
if(ln->next->data->fCost < lowest->data->fCost)
{
lowest=ln->next;
previous=ln;
}
ln=ln->next;
}
if(lowest)
{
pathNode_struct* pn=lowest->data;
if(previous)previous->next=lowest->next;
else ol->first=lowest->next;
lowest->next=NULL;
freeListNode(lowest);
return pn;
}else return NULL;
}
void freeOpenList(openList_struct* ol)
{
if(!ol)return;
listNode_struct* ln=ol->first;
while(ln)
{
// NOGBA("freeing");
listNode_struct* ln2=ln->next;
ln->next=NULL;
freeListNode(ln);
ln=ln2;
}
}
bool initPathfinding(pathfindingSystem_struct* pfs, unsigned char* data, unsigned char w, unsigned char h, vect2D o, vect2D t)
{
if(!pfs || !data)return false;
if(o.x==t.x&&o.y==t.y)return false;
pfs->height=h;
pfs->width=w;
pfs->data=data;
pfs->origin=o;
pfs->target=t;
pfs->path.first=NULL;
pfs->openList.first=NULL;
initPath(&pfs->path);
initOpenList(&pfs->openList);
// pfs->nodes=(pathNode_struct*)malloc(sizeof(pathNode_struct)*w*h);
pfs->nodes=pathNodes;
if(!pfs->nodes){NOGBA("TROUUUUUBLE");return false;}
int i, j;
for(i=0;i<w;i++)
{
for(j=0;j<h;j++)
{
pfs->nodes[i+j*w].fCost=0;
pfs->nodes[i+j*w].inList=noList;
pfs->nodes[i+j*w].parentX=0;
pfs->nodes[i+j*w].parentY=0;
pfs->nodes[i+j*w].X=i;
pfs->nodes[i+j*w].Y=j;
}
}
return true;
}
void addOpenList(pathfindingSystem_struct* pfs, pathNode_struct* ppn, int X, int Y)
{
// NOGBA("adding : %d %d ?",X,Y);
if(!pfs || !ppn || X<0 || Y<0 || X>pfs->width-1 || Y>pfs->height-1)return;
pathNode_struct* pn=&pfs->nodes[X+Y*pfs->width];
// NOGBA("%d %d, %d",X,Y,pn->inList);
if(pn->inList==noList)
{
addListNode(&pfs->openList,pn);
pn->inList=openList;
pn->parentX=ppn->X;
pn->parentY=ppn->Y;
pn->gCost=ppn->gCost+1;
pn->fCost=abs(pn->X-pfs->target.x)+abs(pn->Y-pfs->target.y)+pn->gCost;
// NOGBA("added : %d %d",pn->X,pn->Y);
}else if(pn->inList==openList && pn->gCost-1>ppn->gCost)
{
pn->fCost-=pn->gCost;
pn->gCost=ppn->gCost+1;
pn->fCost+=pn->gCost;
pn->parentX=ppn->X;
pn->parentY=ppn->Y;
// NOGBA("revised : %d %d",pn->X,pn->Y);
}
}
bool findPath(pathfindingSystem_struct* pfs)
{
if(!pfs)return false;
addListNode(&pfs->openList,&pfs->nodes[pfs->origin.x+pfs->origin.y*pfs->width]);
pfs->nodes[pfs->origin.x+pfs->origin.y*pfs->width].inList=openList;
pfs->nodes[pfs->origin.x+pfs->origin.y*pfs->width].gCost=0;
pfs->nodes[pfs->origin.x+pfs->origin.y*pfs->width].fCost=0;
pathNode_struct* pn;
while(1)
{
pn=getLowestFcost(&pfs->openList);
if(!pn || (pn->X==pfs->target.x && pn->Y==pfs->target.y))break;
unsigned char v=pfs->data[pn->X+pn->Y*pfs->width];
if(v&DIRUP)addOpenList(pfs, pn, pn->X, pn->Y-1);
if(v&DIRDOWN)addOpenList(pfs, pn, pn->X, pn->Y+1);
if(v&DIRLEFT)addOpenList(pfs, pn, pn->X-1, pn->Y);
if(v&DIRRIGHT)addOpenList(pfs, pn, pn->X+1, pn->Y);
pn->inList=closedList;
// NOGBA("mem free : %dko (%do)",getMemFree()/1024,getMemFree());
// NOGBA("doing : %d %d %d (%d %d) (%d)",v,pn->X,pn->Y,lnCnt,pcCnt,pfs->nodes[0+11*pfs->width].inList);
}
// NOGBA("%p %d %d",pn,pn->X,pn->Y);
if(pn)
{
while(!(pn->X==pfs->origin.x && pn->Y==pfs->origin.y))
{
addPathCell(&pfs->path, pn->X, pn->Y);
pn=&pfs->nodes[pn->parentX+pn->parentY*pfs->width];
// NOGBA("not popping");
}
return true;
}
return false;
}
void freePath(path_struct* p)
{
if(!p)return;
while(popPathCell(p,NULL,NULL));//NOGBA("popping");
p->first=NULL;
// free(p);
}
void freePathfinding(pathfindingSystem_struct* pfs)
{
if(!pfs)return;
// NOGBA("mem free : %dko (%do)",getMemFree()/1024,getMemFree());
freeOpenList(&pfs->openList);
// if(pfs->nodes)free(pfs->nodes);
}
void printPath(path_struct* p)
{
if(!p)return;
pathCell_struct* pc=p->first;
while(pc)
{
NOGBA("%d %d",pc->X,pc->Y);
pc=pc->next;
}
}
pathCell_struct* getPath(room_struct* r, vect2D origin, vect2D target)
{
if(!r)return NULL;
if((origin.x==target.x&&origin.y==target.y)||origin.x<0||origin.y<0||target.x<0||target.y<0||origin.x>r->width-1||origin.y>r->height-1||target.x>r->width-1||target.y>r->height-1)return NULL;
pathfindingSystem_struct pfs;
if(!r->pathfindingData)getPathfindingData(r);
if(!initPathfinding(&pfs, r->pathfindingData, r->width, r->height, origin, target)){freePathfinding(&pfs);return NULL;}
// NOGBA("finding path... %d %d -> %d %d)",origin.x,origin.y,target.x,target.y);
if(!findPath(&pfs)){freePathfinding(&pfs);return NULL;};
// NOGBA("found path !");
printPath(&pfs.path);
freePathfinding(&pfs);
return pfs.path.first;
}

331
arm9/source/game/physics.c Normal file
View File

@ -0,0 +1,331 @@
#include "game/game_main.h"
#define PLAYERSIZEY (TILESIZE*3)
#define PLAYERSIZEY2 (TILESIZE)
#define PLAYERSIZEX (TILESIZE-32)
#define BOXNUM 10
extern roomEdit_struct roomEdits[NUMROOMEDITS];
vect3D boxDefinition[]={vect(0,-PLAYERSIZEY,0),
vect(-PLAYERSIZEX,-PLAYERSIZEY+MAXSTEP*HEIGHTUNIT+2,-PLAYERSIZEX),
vect(PLAYERSIZEX,-PLAYERSIZEY+MAXSTEP*HEIGHTUNIT+2,-PLAYERSIZEX),
vect(PLAYERSIZEX,-PLAYERSIZEY+MAXSTEP*HEIGHTUNIT+2,PLAYERSIZEX),
vect(-PLAYERSIZEX,-PLAYERSIZEY+MAXSTEP*HEIGHTUNIT+2,PLAYERSIZEX),
vect(0,PLAYERSIZEY2,0),
vect(-PLAYERSIZEX,PLAYERSIZEY2,-PLAYERSIZEX),
vect(PLAYERSIZEX,PLAYERSIZEY2,-PLAYERSIZEX),
vect(PLAYERSIZEX,PLAYERSIZEY2,PLAYERSIZEX),
vect(-PLAYERSIZEX,PLAYERSIZEY2,PLAYERSIZEX)};
bool pointInRoom(room_struct* r, vect3D p, vect3D* v)
{
if(!r)return false;
vect3D rp=vectDifference(p,convertVect(vect(r->position.x,0,r->position.y)));
vect3D s=convertSize(vect(r->width,0,r->height));
if(v)*v=rp;
return rp.x>=0&&rp.z>=0&&rp.x<s.x&&rp.z<s.z;
}
bool objectInRoom(room_struct* r, physicsObject_struct* o, vect3D* v)
{
if(!r || !o)return false;
return pointInRoom(r,o->position,v);
}
room_struct* getRoomPoint(vect3D p)
{
int i;
for(i=0;i<NUMROOMEDITS;i++)
{
if(roomEdits[i].used && pointInRoom(&roomEdits[i].data, p, NULL))
{
return &roomEdits[i].data;
}
}
return NULL;
}
vect3D convertCoord(room_struct* r, vect3D p)
{
if(!r)return vect(0,0,0);
vect3D rp=vectDifference(p,convertVect(vect(r->position.x,0,r->position.y)));
// rp.x+=TILESIZE;
// rp.z+=TILESIZE;
if(rp.x>=0)rp.x/=TILESIZE*2;
else rp.x=rp.x/(TILESIZE*2)-1;
if(rp.z>=0)rp.z/=TILESIZE*2;
else rp.z=rp.z/(TILESIZE*2)-1;
if(rp.y>=0)rp.y/=HEIGHTUNIT;
else rp.y=rp.y/(HEIGHTUNIT)-1;
return rp;
}
door_struct* getInDoorWay(room_struct* r, int i, int j)
{
if(!r->doorWay)return NULL;
if(j<0)
{
if(j<-2)return NULL;
j+=2;
return (door_struct*)r->doorWay[i+j*r->width];
}else if(i<0)
{
if(i<-2)return NULL;
i+=2;
return (door_struct*)r->doorWay[j+i*r->height+r->width*4];
}else if(j>=r->height)
{
j-=r->height;
if(j>1)return NULL;
return (door_struct*)r->doorWay[i+j*r->width+r->width*2];
}else if(i>=r->width)
{
i-=r->width;
if(i>1)return NULL;
return (door_struct*)r->doorWay[j+i*r->height+r->width*4+r->height*2];
}
return NULL;
}
u8 getValue(room_struct* r, int i, int j, int w, int h, bool floor)
{
if(i>=0 && i<w && j>=0 && j<h)
{
if(floor)return r->floor[i+j*w];
else return r->ceiling[i+j*w];
}else{
if((i<0 && j<0)||(i<0 && j>=h)||(i>=w && j<0)||(i>=w && j>=h))return ((floor)?(MAXHEIGHT):(0));
else{
// door_struct* d=inDoorWay(NULL, r, i, j, false);
// if(d)return ((floor)?(d->height):(d->height+DOORHEIGHT));
// else{
// d=inDoorWay(NULL, r, i, j, true);
// if(d)return ((floor)?(d->height):(d->height+DOORHEIGHT));
// else return ((floor)?(MAXHEIGHT):(0));
// }
door_struct* d=getInDoorWay(r, i, j);
if(d && (d->open&&!d->percentage))return ((floor)?(d->height):(d->height+DOORHEIGHT));
else return ((floor)?(MAXHEIGHT):(0));
// if(inDoorWay(NULL, r, i, j, false)||inDoorWay(NULL, r, i, j, true))return ((floor)?(0):(MAXHEIGHT));
// else return ((floor)?(MAXHEIGHT):(0));
}
}
}
bool collides(room_struct* r, vect3D p1, vect3D p2, int32 y1, int32 y2, bool stairs, bool override)
{
if(!r)return false;
if(override && (p2.x<0 || p2.z<0 || p2.x>=r->width || p2.z>=r->height))return true;
// u8 v1=r->floor[p1.x+p1.z*r->width];
// u8 v3=r->floor[p2.x+p2.z*r->width];
// u8 v4=r->ceiling[p2.x+p2.z*r->width];
u8 v1=getValue(r, p1.x, p1.z, r->width, r->height, true);
u8 v3=getValue(r, p2.x, p2.z, r->width, r->height, true);
u8 v4=getValue(r, p2.x, p2.z, r->width, r->height, false);
if(stairs && v3-v1>0 && v3-v1<=MAXSTEP && y2<v3*HEIGHTUNIT){return false;}
return ((y2<v3*HEIGHTUNIT) || (y2>=v4*HEIGHTUNIT));
}
void collidePoint(room_struct* r, vect3D p, vect3D* v, bool stairs, bool override)
{
vect3D rp=vectDifference(p,convertVect(vect(r->position.x,0,r->position.y)));
vect3D op=convertCoord(r, p);
if(/*!collideSegmentDoors(NULL,r,pp,addVect(pp,vect(v->x,0,0))) &&*/ collides(r,op,convertCoord(r,vect(p.x+v->x,p.y,p.z)), p.y, p.y, stairs, override)){if(override&&v->x)NOGBA("x col !");v->x=(v->x>0)?(TILESIZE*2*(op.x+1)-rp.x-MARGIN):(TILESIZE*2*(op.x)-rp.x+MARGIN);}
if(/*!collideSegmentDoors(NULL,r,pp,addVect(pp,vect(v->x,0,v->z))) &&*/ collides(r,op,convertCoord(r,vect(p.x+v->x,p.y,p.z+v->z)), p.y, p.y, stairs, override)){if(override&&v->z)NOGBA("z col !");v->z=(v->z>0)?(TILESIZE*2*(op.z+1)-rp.z-MARGIN):(TILESIZE*2*(op.z)-rp.z+MARGIN);}
}
void updatePhysicsObjectRoom(room_struct* r, physicsObject_struct* o, bool both)
{
vect3D t;
if(r && o && objectInRoom(r, o, &t))
{
NOGBA("py : %d; vy : %d",o->position.y-PLAYERSIZEY,o->speed.y);
collidePoint(r,addVect(o->position,vect(0,-PLAYERSIZEY,0)),&o->speed,true,true);
// collidePoint(r,addVect(o->position,vect(-PLAYERSIZEX,-PLAYERSIZEY+MAXSTEP*HEIGHTUNIT+2,-PLAYERSIZEX)),&o->speed,false);
// collidePoint(r,addVect(o->position,vect(PLAYERSIZEX,-PLAYERSIZEY+MAXSTEP*HEIGHTUNIT+2,-PLAYERSIZEX)),&o->speed,false);
// collidePoint(r,addVect(o->position,vect(PLAYERSIZEX,-PLAYERSIZEY+MAXSTEP*HEIGHTUNIT+2,PLAYERSIZEX)),&o->speed,false);
// collidePoint(r,addVect(o->position,vect(-PLAYERSIZEX,-PLAYERSIZEY+MAXSTEP*HEIGHTUNIT+2,PLAYERSIZEX)),&o->speed,false);
// collidePoint(r,addVect(o->position,vect(0,PLAYERSIZEY2,0)),&o->speed,false);
// collidePoint(r,addVect(o->position,vect(-PLAYERSIZEX,PLAYERSIZEY2,-PLAYERSIZEX)),&o->speed,false);
// collidePoint(r,addVect(o->position,vect(PLAYERSIZEX,PLAYERSIZEY2,-PLAYERSIZEX)),&o->speed,false);
// collidePoint(r,addVect(o->position,vect(PLAYERSIZEX,PLAYERSIZEY2,PLAYERSIZEX)),&o->speed,false);
// collidePoint(r,addVect(o->position,vect(-PLAYERSIZEX,PLAYERSIZEY2,PLAYERSIZEX)),&o->speed,false);
}
if(both)
{
o->position=addVect(o->position,o->speed);
o->speed=vect(0,o->speed.y,0);
}
}
s16 updateSimplePhysicsObjectRoom(room_struct* r, physicsObject_struct* o)
{
s16 v1=-1;
if(r && o)
{
// o->speed.y-=GRAVITY;
// vect3D p=addVect(o->position,vect(0,0,0));
// collidePoint(r,p,&o->speed,true,true);
vect3D t2=vectDivInt(o->position,TILESIZE*2);
v1=r->floor[t2.x+t2.z*r->width];
o->position.y=v1*HEIGHTUNIT+16;
// vect3D* v=&o->speed;
// if(v1*HEIGHTUNIT>=p.y+v->y){v->y=v1*HEIGHTUNIT-p.y+16;}
// else{
// u8 v2=r->ceiling[t2.x+t2.z*r->width];
// p=addVect(o->position,vect(0,PLAYERSIZEY2,0));
// if(v2*HEIGHTUNIT<p.y+v->y){v->y=v2*HEIGHTUNIT-p.y-4;}
// }
}
o->position=addVect(o->position,o->speed);
o->speed=vect(0,0,0);
return v1;
}
bool boxInRoom(room_struct* r, physicsObject_struct* o)
{
int j;
for(j=0;j<BOXNUM;j++)
{
vect3D t;
vect3D p=addVect(o->position,boxDefinition[j]);
if(pointInRoom(r,p,&t))return true;
}
return false;
}
bool checkObjectCollision(physicsObject_struct* o, room_struct* r)
{
listCell_struct *lc=r->rectangles.first;
vect3D o1=vectDifference(o->position,convertVect(vect(r->position.x,0,r->position.y)));
bool ret=false;
while(lc) //add culling
{
vect3D o2=getClosestPointRectangle(&lc->data,o1);
o2=addVect(o2,convertVect(vect(r->position.x,0,r->position.y)));
collidePortal(r,&lc->data,&portal1,&o2);
collidePortal(r,&lc->data,&portal2,&o2);
o2=vectDifference(o2,convertVect(vect(r->position.x,0,r->position.y)));
vect3D v=vectDifference(o2,o1);
int sqd=sqMagnitude(v);
if(sqd<o->sqRadius)
{
sqd=v.x*v.x+v.y*v.y+v.z*v.z;
u32 d=sqrtf32((sqd));
v=divideVect(vectMult(vect(v.x,v.y,v.z),-((o->radius<<6)-d)),d);
o->position=addVect(o->position,v);
o1=vectDifference(o->position,convertVect(vect(r->position.x,0,r->position.y)));
ret=true;
}
lc=lc->next;
}
return ret;
}
void collideObjectRoom(physicsObject_struct* o, room_struct* r)
{
if(!o)return;
if(!r)return;
vect3D pos=o->position;
o->speed.y-=16;
// if(o->speed.y>200)o->speed.y=200;
// else if(o->speed.y<-200)o->speed.y=-200; //temporary limit (hopefully)
if(o->speed.y>800)o->speed.y=800;
else if(o->speed.y<-800)o->speed.y=-800;
int32 length=magnitude(o->speed);
iprintf("length %d \n",length);
bool ret=false;
if(length<200)
{
o->position=addVect(o->position,o->speed);
ret=checkObjectCollision(o,r);
}else{
vect3D v=divideVect(o->speed,length);
v=vectDivInt(v,32);
while(length>128)
{
o->position=addVect(o->position,v);
ret=ret||checkObjectCollision(o,r);
length-=128;
}
v=vectMult(v,length*32);
o->position=addVect(o->position,v);
checkObjectCollision(o,r);
}
o->speed=vect(0,o->position.y-pos.y,0);
// if(!(o->position.y-pos.y))o->speed=vect(0,0,0);
// else o->speed=vect(o->position.x-pos.x,o->position.y-pos.y,o->position.z-pos.z);
// o->speed=vect(o->position.x-pos.x,o->position.y-pos.y,o->position.z-pos.z);
// if(ret){o->speed.x-=o->speed.x/2;o->speed.z-=o->speed.z/2;}
// else {o->speed.x-=o->speed.x/4;o->speed.z-=o->speed.z/4;}
// o->speed=vect(((o->position.x-pos.x)*9)/10,o->position.y-pos.y,((o->position.z-pos.z)*9)/10);
}
void updatePhysicsObject(physicsObject_struct* o)
{
if(o)
{
// o->speed.y-=GRAVITY;
// bool changed=false;
/*int i;
for(i=0;i<NUMROOMEDITS;i++)
{
if(roomEdits[i].used && boxInRoom(&roomEdits[i].data,o))
{
int j;
for(j=0;j<BOXNUM;j++)
{
vect3D p=addVect(o->position,boxDefinition[j]);
// vect3D t;
// if(pointInRoom(&roomEdits[i].data,p,&t))
{
collidePoint(&roomEdits[i].data,p,&o->speed,!j, false);
}
}
}
}
o->position=addVect(o->position,vect(o->speed.x,0,o->speed.z));
o->speed=vect(0,o->speed.y,0);
for(i=0;i<NUMROOMEDITS;i++)
{
vect3D t;
if(roomEdits[i].used)
{
vect3D p=addVect(o->position,vect(0,-PLAYERSIZEY,0));
if(pointInRoom(&roomEdits[i].data,p,&t))
{
room_struct* r=&roomEdits[i].data;
vect3D t2=vectDivInt(t,TILESIZE*2);
u8 v1=r->floor[t2.x+t2.z*r->width];
vect3D* v=&o->speed;
if(v1*HEIGHTUNIT>=p.y+v->y){changed=true;v->y=v1*HEIGHTUNIT-p.y+4;break;}
u8 v2=r->ceiling[t2.x+t2.z*r->width];
p=addVect(o->position,vect(0,PLAYERSIZEY2,0));
if(v2*HEIGHTUNIT<p.y+v->y){changed=true;v->y=v2*HEIGHTUNIT-p.y-4;break;}
break;
}
}
}*/
o->position=addVect(o->position,o->speed);
// o->speed=vect(0,o->speed.y,0);
// if(changed)o->speed.y/=2;
o->speed=vect(0,0,0);
}
}

297
arm9/source/game/player.c Normal file
View File

@ -0,0 +1,297 @@
#include "game/game_main.h"
#define PLAYERRADIUS (256)
#define ERRORMARGIN (2)
#define SQPLAYERRADIUS ((PLAYERRADIUS*PLAYERRADIUS)>>12)
player_struct player;
md2Model_struct gun;
mtlImg_struct* crossHair;
struct gl_texture_t *bottomScreen;
touchPosition touchCurrent, touchOld;
bool isPortalInRectangle(room_struct* r, rectangle_struct* rec, portal_struct* p, vect3D* o)
{
vect3D pr=addVect(convertVect(vect(r->position.x,0,r->position.y)),vect(rec->position.x*TILESIZE*2,rec->position.y*HEIGHTUNIT,rec->position.z*TILESIZE*2));
vect3D sr=vect(rec->size.x*TILESIZE*2,rec->size.y*HEIGHTUNIT,rec->size.z*TILESIZE*2);
*o=vectDifference(pr,p->position);
if(!sr.x)return (equals(o->x,0));
else if(!sr.y)return (equals(o->y,0));
else return (equals(o->z,0));
}
void collidePortal(room_struct* r, rectangle_struct* rec, portal_struct* p, vect3D* point)
{
vect3D o;
if(!isPortalInRectangle(r,rec,p,&o))return;
vect3D v=vectDifference(*point,p->position);
const vect3D u1=p->plane[0], u2=p->plane[1];
int32 xp=dotProduct(v,u1)+PORTALSIZEX;
int32 yp=dotProduct(v,u2)+PORTALSIZEY;
// NOGBA("IN PORTAL ? %d %d", xp, yp);
if(xp<0 || yp<0 || xp>=PORTALSIZEX*2 || yp>=PORTALSIZEY*2)return;
int32 d1=(xp),d2=(yp),d3=PORTALSIZEX*2-(xp),d4=PORTALSIZEY*2-(yp);
if(d1<d2 && d1<d3 && d1<d4)
{
*point=addVect(*point,vectMult(u1,-d1));
}else if(d2<d1 && d2<d3 && d2<d4)
{
*point=addVect(*point,vectMult(u2,-d2));
}else if(d3<d1 && d3<d2 && d3<d4)
{
*point=addVect(*point,vectMult(u1,d3));
}else{
*point=addVect(*point,vectMult(u2,d4));
}
// NOGBA("YES %d %d %d %d",d1,d2,d3,d4);
}
void collidePlayer(player_struct* p, room_struct* r)
{
if(!p)return;
collideObjectRoom(p->object,r);
}
void initPlayer(player_struct* p)
{
if(!p)p=&player;
p->object=&getPlayerCamera()->object;
p->object->position.x=-3*(TILESIZE*2);
// p->object->position.z=6*(TILESIZE*2);
p->object->radius=PLAYERRADIUS;
p->object->sqRadius=SQPLAYERRADIUS;
p->currentRoom=NULL;
touchRead(&touchCurrent);
touchOld=touchCurrent;
p->life=4;
loadMd2Model("pistol.md2","pistol.pcx",&gun);
initModelInstance(&p->modelInstance,&gun);
crossHair=createTexture("crshair.pcx","textures");
bottomScreen=(struct gl_texture_t *)ReadPCXFile("bottom.pcx","bottom");
// bgSub=bgInitSub(3, BgType_Bmp8, BgSize_B8_256x256, 0, 0);
// dmaCopy(bottomScreen->palette, BG_PALETTE_SUB, 256*2);
// copyBottomScreen(0);
}
void damagePlayer(player_struct* p)
{
if(!p)p=&player;
NOGBA("DAMAGE");
// mmEffect(SFX_PLAYERHIT);
p->life--;
}
void drawCrosshair(void)
{
return;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, 255, 191, 0, -1, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
applyMTL(crossHair);
GFX_COLOR=RGB15(31,31,31);
glPushMatrix();
glTranslate3f32(inttof32(128),inttof32(96),0);
glScalef32(inttof32(16),inttof32(16),inttof32(16));
glPolyFmt(POLY_ALPHA(31) | POLY_CULL_NONE);
glBegin(GL_QUADS);
GFX_TEX_COORD = TEXTURE_PACK(32*16, 0);
GFX_VERTEX10 = NORMAL_PACK(-32,-32,0);
GFX_TEX_COORD = TEXTURE_PACK(32*16, 32*16);
GFX_VERTEX10 = NORMAL_PACK(-32,32,0);
GFX_TEX_COORD = TEXTURE_PACK(0, 32*16);
GFX_VERTEX10 = NORMAL_PACK(32,32,0);
GFX_TEX_COORD = 0;
GFX_VERTEX10 = NORMAL_PACK(32,-32,0);
glEnd();
glPolyFmt(POLY_ALPHA(31) | POLY_CULL_BACK);
glPopMatrix(1);
}
s16 depth=-96;
s16 height=-54;
s16 X=-37;
void renderGun(player_struct* p)
{
if(!p)p=&player;
glPushMatrix();
glTranslate3f32(0,height,depth);
glRotateYi(-(1<<13));
// glTranslate3f32(0,0,depth);
// glRotateYi((1<<10));
glMaterialf(GL_AMBIENT, RGB15(31,31,31));
glTranslate3f32(0,0,X);
glScalef32(inttof32(1)>>4,inttof32(1)>>4,inttof32(1)>>4);
renderModelFrameInterp(p->modelInstance.currentFrame, p->modelInstance.nextFrame, p->modelInstance.interpCounter, &gun, POLY_ALPHA(31) | POLY_CULL_FRONT | POLY_FORMAT_LIGHT0);
glPopMatrix(1);
}
void shootPlayerGun(player_struct* p, bool R)
{
if(!p)p=&player;
if(!p->currentRoom)return;
// mmEffect(&gunShot);
// mmEffect(SFX_GUNSHOT);
int32 k=inttof32(300);
vect3D u=getUnitVector(NULL);
vect3D l=vectDifference(p->object->position,convertVect(vect(p->currentRoom->position.x,0,p->currentRoom->position.y)));
// l.x+=u.x/32;
// l.y+=u.y/32;
// l.z+=u.z/32;
vect3D ip=vect(0,0,0);
{
l.x-=TILESIZE;
l.z-=TILESIZE;
rectangle_struct* r=collideLineMapClosest(p->currentRoom, NULL, l, u, k-128, &ip);
if(r)
{
// ip.x+=TILESIZE*2;
// ip.z+=TILESIZE*2;
ip.x+=TILESIZE;
ip.z+=TILESIZE;
vect3D pos=addVect(convertVect(vect(p->currentRoom->position.x,0,p->currentRoom->position.y)),ip);
NOGBA("SHOT WALL ! GOOD GOING %d %d",k,pos.z);
particleExplosion(pos,16,RGB15(31,31,0));
// r->hide^=1;
if(R){movePortal(&portal1, pos, vectMultInt(r->normal,-1), 0);}
else movePortal(&portal2, pos, vectMultInt(r->normal,-1), 0);
}
}
}
void playerControls(player_struct* p)
{
if(!p)p=&player;
if(p->life<=0)changeState(&gameState);
touchRead(&touchCurrent);
if(keysDown() & KEY_TOUCH)touchOld=touchCurrent;
if(keysHeld() & KEY_TOUCH)
{
int16 dx = touchCurrent.px - touchOld.px;
int16 dy = touchCurrent.py - touchOld.py;
vect3D angle=vect(0,0,0);
if (dx<20 && dx>-20 && dy<20 && dy>-20)
{
// if(dx>-2&&dx<2)dx=0;
// if(dy>-2&&dy<2)dy=0;
angle.x -= degreesToAngle(dy);
angle.y -= degreesToAngle(dx);
}
rotateCamera(NULL, angle);
}
// if(keysHeld()&(KEY_A))rotateCamera(NULL, vect(0,0,-(1<<8)));
// if(keysHeld()&(KEY_Y))rotateCamera(NULL, vect(0,0,1<<8));
if((keysHeld()&(KEY_RIGHT))/*||(keysHeld()&(KEY_A))*/)moveCamera(NULL, vect(inttof32(1)>>6,0,0));
if((keysHeld()&(KEY_LEFT))/*||(keysHeld()&(KEY_Y))*/)moveCamera(NULL, vect(-(inttof32(1)>>6),0,0));
if((keysHeld()&(KEY_DOWN))/*||(keysHeld()&(KEY_B))*/)moveCamera(NULL, vect(0,0,inttof32(1)>>6));
if((keysHeld()&(KEY_UP))/*||(keysHeld()&(KEY_X))*/)moveCamera(NULL, vect(0,0,-(inttof32(1)>>6)));
// if(keysHeld()&(KEY_SELECT))moveCamera(NULL, vect(0,-(inttof32(1)>>6),0));
// if(keysHeld()&(KEY_START))moveCamera(NULL, vect(0,inttof32(1)>>6,0));
if(keysDown()&(KEY_START))p->object->speed.y=(inttof32(1)>>4);
if(keysDown()&(KEY_SELECT)){camera_struct* c=getPlayerCamera();p->object->position=c->position=portal1.camera.position;memcpy(c->transformationMatrix,portal1.camera.transformationMatrix,9*sizeof(int32));}
if(!p->modelInstance.oneshot && ((keysDown()&(KEY_R))||(keysDown()&(KEY_L)))){shootPlayerGun(p,keysDown()&(KEY_R));changeAnimation(&p->modelInstance,2,true);}
//DEBUG
// if(keysHeld()&(KEY_R)){height++;}
// if(keysHeld()&(KEY_L)){height--;}
// NOGBA("height : %d",height);
// if(keysHeld()&(KEY_A)){X++;}
// if(keysHeld()&(KEY_B)){X--;}
// NOGBA("X : %d",X);
// if(keysHeld()&(KEY_X)){depth++;}
// if(keysHeld()&(KEY_Y)){depth--;}
// NOGBA("depth : %d",depth);
/*if(keysDown()&(KEY_SELECT))
{
room_struct* r=getRoomPoint(p->object->position);
if(r)
{
vect3D p2=convertCoord(r, p->object->position);
int dist=0;
door_struct* d=getClosestDoorRoom(NULL,r,vect2(p2.x,p2.z),&dist);
if(d)
{
NOGBA("DOOOOOOR %d %p",dist,d);
if((!d->open||dist>0) && dist<=4)
{
closeRoomDoors(NULL, r, d);
if(toggleDoor(r,d))
{
// mmEffect(SFX_DOOR);
if(d->open)
{
// room_struct* r2=d->secondaryRoom;
// if(r==r2)r2=d->primaryRoom;
// unloadLightMaps(r,r2);
}else{
unloadLightMaps(r,NULL);
room_struct* r2=d->secondaryRoom;
if(r==r2)r2=d->primaryRoom;
loadLightMap(r2);
}
}
}
// moveRoomEnemiesTo(r,p2.x,p2.z,RUNTO);
}
}
}*/
touchOld=touchCurrent;
}
room_struct* getCurrentRoom(void){return player.currentRoom;}
player_struct* getPlayer(void){return &player;}
void updatePlayer(player_struct* p)
{
if(!p)p=&player;
// updatePhysicsObjectRoom(NULL,p->object,true);
room_struct* r=getRoomPoint(p->object->position);
if(r)p->currentRoom=r;
if(p->currentRoom)
{
p->relativePosition=convertCoord(r, p->object->position);
p->relativePositionReal=vectDifference(p->object->position,convertVect(vect(r->position.x,0,r->position.y)));
}
if(r && !r->lmSlot)loadLightMap(r);
// createParticles(p->object->position,vect(0,0,0),120);
// particleExplosion(p->object->position,32);
collidePlayer(p,p->currentRoom);
// updatePhysicsObject(p->object);
updateCamera(NULL);
updateAnimation(&p->modelInstance);
}
void freePlayer(void)
{
freeMd2Model(&gun);
freePCX(bottomScreen);
}

Some files were not shown because too many files have changed in this diff Show More