Initial commit - that's out of the way.
This commit is contained in:
commit
10a973e2f1
|
@ -0,0 +1,4 @@
|
|||
/Makefile.cfg
|
||||
/obj
|
||||
/lib*.a
|
||||
/lib*-*.tar.gz
|
|
@ -0,0 +1,6 @@
|
|||
# libwindmill authors
|
||||
Copyright (C) 2017 Olivier "Ninestars" Lanneau
|
||||
Copyright (C) 2017 Thomas "Cakeisalie5" Touhey
|
||||
|
||||
Ninestars was the one thinking and making the actual code, I (Cakeisalie5)
|
||||
just came along and reorganized the project.
|
|
@ -0,0 +1,3 @@
|
|||
# Contributing to libwindmill
|
||||
For now, external contributions aren't allowed, as the project is in
|
||||
very alpha. Maybe later :)
|
|
@ -0,0 +1,157 @@
|
|||
### GNU LESSER GENERAL PUBLIC LICENSE
|
||||
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc.
|
||||
<http://fsf.org/>
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim copies of this
|
||||
license document, but changing it is not allowed.
|
||||
|
||||
This version of the GNU Lesser General Public License incorporates the
|
||||
terms and conditions of version 3 of the GNU General Public License,
|
||||
supplemented by the additional permissions listed below.
|
||||
|
||||
#### 0. Additional Definitions.
|
||||
|
||||
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||
General Public License, and the "GNU GPL" refers to version 3 of the
|
||||
GNU General Public License.
|
||||
|
||||
"The Library" refers to a covered work governed by this License, other
|
||||
than an Application or a Combined Work as defined below.
|
||||
|
||||
An "Application" is any work that makes use of an interface provided
|
||||
by the Library, but which is not otherwise based on the Library.
|
||||
Defining a subclass of a class defined by the Library is deemed a mode
|
||||
of using an interface provided by the Library.
|
||||
|
||||
A "Combined Work" is a work produced by combining or linking an
|
||||
Application with the Library. The particular version of the Library
|
||||
with which the Combined Work was made is also called the "Linked
|
||||
Version".
|
||||
|
||||
The "Minimal Corresponding Source" for a Combined Work means the
|
||||
Corresponding Source for the Combined Work, excluding any source code
|
||||
for portions of the Combined Work that, considered in isolation, are
|
||||
based on the Application, and not on the Linked Version.
|
||||
|
||||
The "Corresponding Application Code" for a Combined Work means the
|
||||
object code and/or source code for the Application, including any data
|
||||
and utility programs needed for reproducing the Combined Work from the
|
||||
Application, but excluding the System Libraries of the Combined Work.
|
||||
|
||||
#### 1. Exception to Section 3 of the GNU GPL.
|
||||
|
||||
You may convey a covered work under sections 3 and 4 of this License
|
||||
without being bound by section 3 of the GNU GPL.
|
||||
|
||||
#### 2. Conveying Modified Versions.
|
||||
|
||||
If you modify a copy of the Library, and, in your modifications, a
|
||||
facility refers to a function or data to be supplied by an Application
|
||||
that uses the facility (other than as an argument passed when the
|
||||
facility is invoked), then you may convey a copy of the modified
|
||||
version:
|
||||
|
||||
- a) under this License, provided that you make a good faith effort
|
||||
to ensure that, in the event an Application does not supply the
|
||||
function or data, the facility still operates, and performs
|
||||
whatever part of its purpose remains meaningful, or
|
||||
- b) under the GNU GPL, with none of the additional permissions of
|
||||
this License applicable to that copy.
|
||||
|
||||
#### 3. Object Code Incorporating Material from Library Header Files.
|
||||
|
||||
The object code form of an Application may incorporate material from a
|
||||
header file that is part of the Library. You may convey such object
|
||||
code under terms of your choice, provided that, if the incorporated
|
||||
material is not limited to numerical parameters, data structure
|
||||
layouts and accessors, or small macros, inline functions and templates
|
||||
(ten or fewer lines in length), you do both of the following:
|
||||
|
||||
- a) Give prominent notice with each copy of the object code that
|
||||
the Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
- b) Accompany the object code with a copy of the GNU GPL and this
|
||||
license document.
|
||||
|
||||
#### 4. Combined Works.
|
||||
|
||||
You may convey a Combined Work under terms of your choice that, taken
|
||||
together, effectively do not restrict modification of the portions of
|
||||
the Library contained in the Combined Work and reverse engineering for
|
||||
debugging such modifications, if you also do each of the following:
|
||||
|
||||
- a) Give prominent notice with each copy of the Combined Work that
|
||||
the Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
- b) Accompany the Combined Work with a copy of the GNU GPL and this
|
||||
license document.
|
||||
- c) For a Combined Work that displays copyright notices during
|
||||
execution, include the copyright notice for the Library among
|
||||
these notices, as well as a reference directing the user to the
|
||||
copies of the GNU GPL and this license document.
|
||||
- d) Do one of the following:
|
||||
- 0) Convey the Minimal Corresponding Source under the terms of
|
||||
this License, and the Corresponding Application Code in a form
|
||||
suitable for, and under terms that permit, the user to
|
||||
recombine or relink the Application with a modified version of
|
||||
the Linked Version to produce a modified Combined Work, in the
|
||||
manner specified by section 6 of the GNU GPL for conveying
|
||||
Corresponding Source.
|
||||
- 1) Use a suitable shared library mechanism for linking with
|
||||
the Library. A suitable mechanism is one that (a) uses at run
|
||||
time a copy of the Library already present on the user's
|
||||
computer system, and (b) will operate properly with a modified
|
||||
version of the Library that is interface-compatible with the
|
||||
Linked Version.
|
||||
- e) Provide Installation Information, but only if you would
|
||||
otherwise be required to provide such information under section 6
|
||||
of the GNU GPL, and only to the extent that such information is
|
||||
necessary to install and execute a modified version of the
|
||||
Combined Work produced by recombining or relinking the Application
|
||||
with a modified version of the Linked Version. (If you use option
|
||||
4d0, the Installation Information must accompany the Minimal
|
||||
Corresponding Source and Corresponding Application Code. If you
|
||||
use option 4d1, you must provide the Installation Information in
|
||||
the manner specified by section 6 of the GNU GPL for conveying
|
||||
Corresponding Source.)
|
||||
|
||||
#### 5. Combined Libraries.
|
||||
|
||||
You may place library facilities that are a work based on the Library
|
||||
side by side in a single library together with other library
|
||||
facilities that are not Applications and are not covered by this
|
||||
License, and convey such a combined library under terms of your
|
||||
choice, if you do both of the following:
|
||||
|
||||
- a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities, conveyed under the terms of this License.
|
||||
- b) Give prominent notice with the combined library that part of it
|
||||
is a work based on the Library, and explaining where to find the
|
||||
accompanying uncombined form of the same work.
|
||||
|
||||
#### 6. Revised Versions of the GNU Lesser General Public License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions
|
||||
of the GNU Lesser General Public License from time to time. Such new
|
||||
versions will be similar in spirit to the present version, but may
|
||||
differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
as you received it specifies that a certain numbered version of the
|
||||
GNU Lesser General Public License "or any later version" applies to
|
||||
it, you have the option of following the terms and conditions either
|
||||
of that published version or of any later version published by the
|
||||
Free Software Foundation. If the Library as you received it does not
|
||||
specify a version number of the GNU Lesser General Public License, you
|
||||
may choose any version of the GNU Lesser General Public License ever
|
||||
published by the Free Software Foundation.
|
||||
|
||||
If the Library as you received it specifies that a proxy can decide
|
||||
whether future versions of the GNU Lesser General Public License shall
|
||||
apply, that proxy's public statement of acceptance of any version is
|
||||
permanent authorization for you to choose that version for the
|
||||
Library.
|
|
@ -0,0 +1,120 @@
|
|||
#!/usr/bin/make -f
|
||||
#******************************************************************************#
|
||||
# Include variables and message subsystem #
|
||||
#******************************************************************************#
|
||||
include Makefile.vars Makefile.msg
|
||||
|
||||
#******************************************************************************#
|
||||
# General targets #
|
||||
#******************************************************************************#
|
||||
# Build everything.
|
||||
all: all-lib
|
||||
|
||||
# Mostly clean everything. (remove everything but the end results)
|
||||
mostlyclean: mostlyclean-lib
|
||||
mclean: mostlyclean
|
||||
|
||||
# Clean everything.
|
||||
clean fclean: clean-lib
|
||||
$(call qcmd,$(RM) -r lib$(NAME)-*)
|
||||
|
||||
# Clean everything, and configuration.
|
||||
mrproper: clean
|
||||
$(call rmsg,Removing configuration.)
|
||||
$(call qcmd,$(RM) Makefile.cfg)
|
||||
|
||||
# Make a distribution tarball
|
||||
dist: mrproper
|
||||
$(call bcmd,mkdir,lib$(NAME)-$(VERSION),\
|
||||
$(MD) .dist)
|
||||
$(call bcmd,cp,* lib$(NAME)-$(VERSION),\
|
||||
$(CP) -R * .dist)
|
||||
$(call qcmd,\
|
||||
$(MV) .dist lib$(NAME)-$(VERSION))
|
||||
$(call bcmd,tarball,lib$(NAME)-$(VERSION),\
|
||||
tar czf lib$(NAME)-$(VERSION).tar.gz \
|
||||
--exclude .git lib$(NAME)-$(VERSION))
|
||||
$(call qcmd,$(RM) -r lib$(NAME)-$(VERSION))
|
||||
|
||||
# Remake everything. (clean and build)
|
||||
re: clean all
|
||||
|
||||
.PHONY: all mostlyclean mclean clean fclean dist mrproper re
|
||||
#******************************************************************************#
|
||||
# Configuration (version) checking dependencies #
|
||||
#******************************************************************************#
|
||||
# Define the dependencies.
|
||||
CHECKCFG := $(if $(shell test -f Makefile.cfg || echo y),check-config, \
|
||||
$(if $(shell [ "$(VERSION)" = "$(CONFIG_VERSION)" ] || echo y), \
|
||||
check-config-version))
|
||||
|
||||
# Define the rules.
|
||||
check-config:
|
||||
@echo -e "\033[1;31mNo configuration file found!"
|
||||
@echo -e "You should configure before re-running this target.\033[0m"
|
||||
@false
|
||||
check-config-version:
|
||||
@echo -e "\033[1;31mConfiguration version is incorrect!"
|
||||
@echo -e "You should re-configure before re-running this target.\033[0m"
|
||||
@false
|
||||
|
||||
.PHONY: check-config check-config-version
|
||||
#******************************************************************************#
|
||||
# Information getting from the Makefile variables #
|
||||
#******************************************************************************#
|
||||
# Get the project name.
|
||||
getname:
|
||||
@echo lib$(NAME)
|
||||
|
||||
# Get the maintainer
|
||||
getmaintainer:
|
||||
@echo "$(MAINTAINER_NAME) <$(MAINTAINER_MAIL)>"
|
||||
|
||||
# Get the project version.
|
||||
getversion:
|
||||
@echo "$(VERSION)"
|
||||
|
||||
.PHONY: getname getmaintainer getversion
|
||||
#******************************************************************************#
|
||||
# Library-specific targets #
|
||||
#******************************************************************************#
|
||||
# Make the library.
|
||||
all-lib: $(CHECKCFG) lib$(NAME).a
|
||||
|
||||
# Make an object directory.
|
||||
$(OBJDIR)/ $(DIRS:%=$(OBJDIR)/%):
|
||||
$(call bcmd,mkdir,$@,$(MD) $@)
|
||||
|
||||
# Make an object out of a source file.
|
||||
define make-obj-rules
|
||||
ifeq ($(shell test -f $(SRCDIR)/$1.c && echo y),y)
|
||||
$(OBJDIR)/$1.o: $(SRCDIR)/$1.c $(INC) | $(dir $(OBJDIR)/$1)
|
||||
$(call bcmd,cc,$$@,$(CC) -c -o $$@ $$< $(CFLAGS))
|
||||
else
|
||||
$(OBJDIR)/$1.o: $(SRCDIR)/$1.s | $(dir $(OBJDIR)/$1)
|
||||
$(call bcmd,as,$$@,$(AS) -c -o $$@ $$< $(ASFLAGS))
|
||||
endif
|
||||
endef
|
||||
$(foreach src,$(SRC), \
|
||||
$(eval $(call make-obj-rules,$(src))))
|
||||
|
||||
# Make the library.
|
||||
lib$(NAME).a: $(SRC:%=$(OBJDIR)/%.o)
|
||||
$(call bcmd,ar rcs,$@,$(AR) rc $@ $^)
|
||||
|
||||
# Remove the objects directory.
|
||||
mostlyclean-lib:
|
||||
$(call rmsg,Removing object directory.)
|
||||
$(call qcmd,$(RM) -r $(OBJDIR))
|
||||
mclean-lib: mostlyclean-lib
|
||||
|
||||
# Clean and remove the built library.
|
||||
clean-lib: mclean-lib
|
||||
$(call rmsg,Removing the library.)
|
||||
$(call qcmd,$(RM) lib$(NAME).a)
|
||||
|
||||
# Remake the library.
|
||||
re-lib: clean-lib all-lib
|
||||
|
||||
.PHONY: all-lib mostlyclean-lib mclean-lib clean-lib re-lib
|
||||
# End of file.
|
|
@ -0,0 +1,58 @@
|
|||
#!/usr/bin/make -f
|
||||
# The Makefile message subsystem.
|
||||
# For nice logs. 5 dollars per log only.
|
||||
#******************************************************************************#
|
||||
# Colors and misc #
|
||||
#******************************************************************************#
|
||||
# Used colors ANSI modifiers escape codes
|
||||
color_green := 32
|
||||
color_red := 31
|
||||
color_yellow := 33
|
||||
|
||||
# Newline - comes handy in some situations
|
||||
define \n
|
||||
|
||||
|
||||
endef
|
||||
|
||||
#******************************************************************************#
|
||||
# General messages #
|
||||
#******************************************************************************#
|
||||
# Command message - display basic info about the command, and run it.
|
||||
define cmd
|
||||
@$(if $(MAKE_FULL_LOG),,printf "\033[1;""$4""m>\033[0m \033[1m%s\033[0m %s\n" "$1" "$2";)
|
||||
$(if $(MAKE_FULL_LOG),,@)$3
|
||||
endef
|
||||
|
||||
# Quiet command - make it non-quiet if full log is enabled.
|
||||
define qcmd
|
||||
$(if $(MAKE_FULL_LOG),,@)$1
|
||||
endef
|
||||
|
||||
# Normal message - display it.
|
||||
define msg
|
||||
$(if $(MAKE_FULL_LOG),,@printf "\033[1;""$2""m>\033[0m \033[1m%s\033[0m\n" "$1")
|
||||
endef
|
||||
|
||||
#******************************************************************************#
|
||||
# Commands #
|
||||
#******************************************************************************#
|
||||
# Build command
|
||||
define bcmd
|
||||
$(call cmd,$1,$2,$3,$(color_green))
|
||||
endef
|
||||
|
||||
#******************************************************************************#
|
||||
# Messages #
|
||||
#******************************************************************************#
|
||||
# Remove message
|
||||
define rmsg
|
||||
$(call msg,$1,$(color_red))
|
||||
endef
|
||||
|
||||
# Install message
|
||||
define imsg
|
||||
$(call msg,$1,$(color_yellow))
|
||||
endef
|
||||
|
||||
# End of file
|
|
@ -0,0 +1,82 @@
|
|||
#!/usr/bin/make -f
|
||||
#******************************************************************************#
|
||||
# Include configuration #
|
||||
#******************************************************************************#
|
||||
-include Makefile.cfg
|
||||
|
||||
#******************************************************************************#
|
||||
# Project main information #
|
||||
#******************************************************************************#
|
||||
# Project name and supported targets
|
||||
NAME := windmill
|
||||
|
||||
# Maintainer information
|
||||
MAINTAINER_NAME := Thomas \"Cakeisalie5\" Touhey
|
||||
MAINTAINER_MAIL := thomas@touhey.fr
|
||||
|
||||
# Project version
|
||||
MAJOR := 0
|
||||
MINOR := 1
|
||||
INDEV := yes
|
||||
|
||||
# Project version string
|
||||
VERSION := $(MAJOR).$(MINOR)$(if $(INDEV),-indev)
|
||||
|
||||
#******************************************************************************#
|
||||
# Project directories #
|
||||
#******************************************************************************#
|
||||
# Headers directory - where all the headers are.
|
||||
INCDIR := ./include
|
||||
|
||||
# Sources directory - where all the sources are.
|
||||
SRCDIR := ./src
|
||||
|
||||
# Objects directory - where the objects will be put.
|
||||
OBJDIR := ./obj
|
||||
|
||||
#******************************************************************************#
|
||||
# Binary utilities #
|
||||
#******************************************************************************#
|
||||
# Compiler
|
||||
CC := sh3eb-elf-gcc
|
||||
# - Check flags (warnings)
|
||||
CWARN := -Wall -Wextra -Wno-attributes
|
||||
# - For random manipulations (profiling, ...)
|
||||
#CMOREFLAGS :=
|
||||
# - All C compiling flags
|
||||
CFLAGS := $(CWARN) -I $(INCDIR) -std=gnu11 -O2 -ffreestanding
|
||||
|
||||
# Assembler
|
||||
AS := sh3eb-elf-as
|
||||
# - All assembling flags
|
||||
ASFLAGS :=
|
||||
|
||||
# Archiver
|
||||
AR := sh3eb-elf-ar
|
||||
# Directory maker
|
||||
MD := mkdir -p
|
||||
# Symbolic link maker
|
||||
LN := ln -sf
|
||||
# Copier
|
||||
CP := cp
|
||||
# Mover
|
||||
MV := mv
|
||||
# File remover
|
||||
RM := rm -f
|
||||
# Installer
|
||||
INST := install
|
||||
# GZipper
|
||||
GZIP := gzip -f
|
||||
|
||||
#******************************************************************************#
|
||||
# Look for modules and modules sources #
|
||||
#******************************************************************************#
|
||||
# Look up the sources
|
||||
SRC := $(basename $(shell find $(SRCDIR) -mindepth 1 -type f \
|
||||
-name "*.[cs]" -printf "%P\n"))
|
||||
DIRS := $(sort $(dir $(SRC)))
|
||||
|
||||
# Look up the includes
|
||||
INC := $(shell find $(INCDIR) -mindepth 1 -name "*.h")
|
||||
|
||||
# End of file.
|
|
@ -0,0 +1,48 @@
|
|||
# libwindmill - a 3D engine for your CASIO fx-9860G
|
||||
## Introduction
|
||||
Windmill is a 3D engine project by Ninestars, originally developed in C++ and
|
||||
built with the CASIO fx-9860G SDK. It was adapted to compile with GNU
|
||||
utilities by Cakeisalie5.
|
||||
|
||||
This 3D engine is made to be easy to use, and modular, in order to quickly
|
||||
create a game, or to use it in an existing project.
|
||||
It features the following:
|
||||
* Calculates coordinates to display them on screen;
|
||||
* Camera that can move in any direction and turn around using two axes;
|
||||
* Management of display windows;
|
||||
* Depth buffer so objects hidden behind others aren't displayed;
|
||||
* Display of textures defined as images;
|
||||
* Simplified management of meshes and textures;
|
||||
* Display of fixed and dynamic objects that can turn following three axes;
|
||||
* Simultaneous renders.
|
||||
|
||||
Windmill is only a graphical engine, it only displays predefined triangles
|
||||
in space on the screen, which means it doesn't manage collisions between
|
||||
objects, or between an object and the camera.
|
||||
|
||||
## Requirements/setup
|
||||
This project is easier to build under GNU/Linux. It might be possible to
|
||||
build it for Microsoft Windows, but this host platform is not officially
|
||||
supported.
|
||||
|
||||
You will need [GCC][gcc] and [GNU Binutils][binutils], both compiled for the
|
||||
`sh3eb-elf` target, and the [G1A wrapper][wrapper]. A french tutorial of how
|
||||
to make and install all of these can be found [on Planète Casio][pc-gcc-tuto]
|
||||
(steps 1 to 6 included).
|
||||
|
||||
## Build
|
||||
Just type in the following:
|
||||
|
||||
./configure && make
|
||||
|
||||
## Miscellaneous information
|
||||
For the authors of the project, check `AUTHORS.md`.
|
||||
For the license of the project, check `LICENSE.md`.
|
||||
|
||||
If you want to contribute to this project, check the contribution guide
|
||||
in the `CONTRIBUTING.md` file.
|
||||
|
||||
[gcc]: https://gcc.gnu.org/
|
||||
[binutils]: https://www.gnu.org/software/binutils/
|
||||
[wrapper]: https://bitbucket.org/Lephenixnoir/add-in-wrapper.git
|
||||
[pc-gcc-tuto]: http://www.planet-casio.com/Fr/programmation/tutoriels.php?id=61
|
|
@ -0,0 +1,96 @@
|
|||
#!/bin/sh
|
||||
cd "$(dirname $0)"
|
||||
#******************************************************************************#
|
||||
# Defaults #
|
||||
#******************************************************************************#
|
||||
# Project variables
|
||||
name="$(make -s getname)"
|
||||
version="$(make -s getversion)"
|
||||
|
||||
# Maintainer info
|
||||
maintainer="$(make -s getmaintainer)"
|
||||
|
||||
# Make options
|
||||
make_full_log=
|
||||
|
||||
#******************************************************************************#
|
||||
# Help message #
|
||||
#******************************************************************************#
|
||||
usage() {
|
||||
cat <<EOF
|
||||
\`configure\` configures ${name} to adapt to systems that aren't mine.
|
||||
Usage: $0 [OPTION]
|
||||
|
||||
Defaults for the options are specified in brackets.
|
||||
|
||||
General options:
|
||||
--help display this help and exit
|
||||
--version display version information and quit
|
||||
--make-full-log display full commands while making
|
||||
|
||||
Report bugs to ${maintainer}.
|
||||
EOF
|
||||
exit 0
|
||||
}
|
||||
|
||||
#******************************************************************************#
|
||||
# Version message #
|
||||
#******************************************************************************#
|
||||
version() {
|
||||
cat <<EOF
|
||||
${name} configure script v${version}
|
||||
Hand-written by Thomas "Cakeisalie5" Touhey.
|
||||
|
||||
This configure script is free software.
|
||||
There is NO warranty; not even for MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE.
|
||||
EOF
|
||||
exit 0
|
||||
}
|
||||
|
||||
#******************************************************************************#
|
||||
# Check for help and version #
|
||||
#******************************************************************************#
|
||||
put_version=
|
||||
put_help=
|
||||
for arg ; do case "$arg" in
|
||||
--help|-h) put_help=1 ;;
|
||||
--version|-v) put_version=1 ;;
|
||||
esac; done
|
||||
[ $put_version ] && version
|
||||
[ $put_help ] && usage
|
||||
|
||||
#******************************************************************************#
|
||||
# Parse arguments #
|
||||
#******************************************************************************#
|
||||
for arg ; do case "$arg" in
|
||||
--make-full-log) make_full_log=yes ;;
|
||||
*) echo "$arg: didn't read" ;;
|
||||
esac; done
|
||||
|
||||
#******************************************************************************#
|
||||
# Create Makefile configuration #
|
||||
#******************************************************************************#
|
||||
# Clean before.
|
||||
make mrproper MAKE_FULL_LOG=y 1>/dev/null 2>/dev/null
|
||||
|
||||
# Do it!
|
||||
exec 3>&1 1>Makefile.cfg
|
||||
cat <<EOF
|
||||
#!/usr/bin/make -f
|
||||
#******************************************************************************#
|
||||
# Makefile configuration generated by ./configure #
|
||||
#******************************************************************************#
|
||||
# Configuration version and messages configuration
|
||||
CONFIG_VERSION = $version
|
||||
MAKE_FULL_LOG = $make_full_log
|
||||
|
||||
# End of file.
|
||||
EOF
|
||||
exec 1>&3 3>&-
|
||||
chmod +x Makefile.cfg
|
||||
|
||||
# Put the lil' message.
|
||||
echo "Configuration loaded, you can make now."
|
||||
|
||||
# End of file.
|
|
@ -0,0 +1,156 @@
|
|||
/* *****************************************************************************
|
||||
* libwindmill.h -- 3D rendering engine.
|
||||
* Copyright (C) 2017 Olivier "Ninestars" Lanneau
|
||||
* Copyright (C) 2017 Thomas "Cakeisalie5" Touhey <thomas@touhey.fr>
|
||||
*
|
||||
* This file is part of libwindmill.
|
||||
* libwindmill is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 3.0 of the License,
|
||||
* or (at your option) any later version.
|
||||
*
|
||||
* libwindmill is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with libwindmill; if not, see <http://www.gnu.org/licenses/>.
|
||||
* ************************************************************************** */
|
||||
#ifndef LIBWINDMILL_H
|
||||
# define LIBWINDMILL_H
|
||||
# include <stdlib.h>
|
||||
# include <string.h>
|
||||
# include <math.h>
|
||||
# define N 0
|
||||
# define X 1
|
||||
# define Y 2
|
||||
# define Z 3
|
||||
# define XC 4
|
||||
# define YC 5
|
||||
# define ZC 6
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Types */
|
||||
/* ************************************************************************** */
|
||||
/* a vertex */
|
||||
typedef struct Vertex {
|
||||
int x, y, z;
|
||||
char tx, ty;
|
||||
int z_normalized;
|
||||
} wml_vertex_t;
|
||||
|
||||
/* a texture */
|
||||
typedef struct Texture {
|
||||
const unsigned char *sprite;
|
||||
char width, height, offset;
|
||||
} wml_texture_t;
|
||||
|
||||
/* a triangle */
|
||||
typedef struct Triangle {
|
||||
/* coordinates */
|
||||
short x0, y0, z0;
|
||||
short x1, y1, z1;
|
||||
short x2, y2, z2;
|
||||
|
||||
/* textures */
|
||||
struct Texture *texture_front;
|
||||
struct Texture *texture_back;
|
||||
} wml_triangle_t;
|
||||
|
||||
/* a rectangle */
|
||||
typedef struct Rectangle {
|
||||
/* coordinates */
|
||||
short x0, y0, z0;
|
||||
short x1, y1, z1;
|
||||
short x2, y2, z2;
|
||||
|
||||
/* textures */
|
||||
struct Texture *texture_front;
|
||||
struct Texture *texture_back;
|
||||
} wml_rectangle_t;
|
||||
|
||||
/* an object */
|
||||
typedef struct Object {
|
||||
/* coordinates */
|
||||
int x, y, z;
|
||||
char axe; float angle;
|
||||
|
||||
/* rectangles */
|
||||
wml_rectangle_t *list_rect;
|
||||
int list_rect_size;
|
||||
|
||||
/* triangles */
|
||||
wml_triangle_t *list_tri;
|
||||
int list_tri_size;
|
||||
} wml_object_t;
|
||||
|
||||
/* a map */
|
||||
typedef struct Map {
|
||||
int id;
|
||||
|
||||
/* objects */
|
||||
struct Object **list_object;
|
||||
int list_object_size;
|
||||
} wml_map_t;
|
||||
|
||||
/* a scene */
|
||||
typedef struct Scene {
|
||||
/* flow control */
|
||||
int stop_execution;
|
||||
|
||||
/* camera */
|
||||
float camera_x, camera_y, camera_z;
|
||||
float camera_yaw, camera_pitch;
|
||||
int scale_coef, near, far;
|
||||
float near_coef;
|
||||
int far_coef;
|
||||
float div_coef;
|
||||
int viewport_x1, viewport_y1, viewport_x2, viewport_y2;
|
||||
int shift_x, shift_y;
|
||||
unsigned short *z_buffer;
|
||||
int z_buffer_size, z_buffer_offset, z_buffer_width;
|
||||
|
||||
/* texture, map, background */
|
||||
struct Texture *hidden, *black, *white;
|
||||
struct Map map;
|
||||
const unsigned char *background;
|
||||
|
||||
/* i don't know what this is, yet */
|
||||
int a1, a2, a3, a4, a5, a6, a7, a8, a9;
|
||||
} wml_scene_t;
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Functions */
|
||||
/* ************************************************************************** */
|
||||
/* update things */
|
||||
void wml_update_camera(wml_scene_t *scene);
|
||||
void wml_update_viewport(wml_scene_t *scene);
|
||||
|
||||
/* render */
|
||||
void wml_render_draw(wml_scene_t *scene);
|
||||
|
||||
void wml_dynamic(wml_vertex_t *vertex,
|
||||
int axe, int x, int y, int z,
|
||||
float cosinus, float sinus);
|
||||
void wml_transform(wml_scene_t *scene, wml_vertex_t *vertex);
|
||||
|
||||
void wml_render_triangle(wml_scene_t *scene,
|
||||
wml_vertex_t *vertex1, wml_vertex_t *vertex2, wml_vertex_t *vertex3,
|
||||
wml_texture_t *texture);
|
||||
void wml_render_triangle_black(wml_scene_t *scene,
|
||||
wml_vertex_t *vertex1, wml_vertex_t *vertex2, wml_vertex_t *vertex3,
|
||||
wml_texture_t *texture);
|
||||
void wml_render_triangle_white(wml_scene_t *scene,
|
||||
wml_vertex_t *vertex1, wml_vertex_t *vertex2, wml_vertex_t *vertex3,
|
||||
wml_texture_t *texture);
|
||||
|
||||
void wml_edge(wml_vertex_t *a, wml_vertex_t *b, wml_vertex_t *c);
|
||||
void wml_edge_start(wml_vertex_t *a, wml_vertex_t *b, int px, int py);
|
||||
void wml_edge_step_x(wml_vertex_t *a, wml_vertex_t *b);
|
||||
void wml_edge_step_y(wml_vertex_t *a, wml_vertex_t *b);
|
||||
|
||||
void wml_move_camera_face(wml_scene_t *scene, float value);
|
||||
void wml_move_camera_side(wml_scene_t *scene, float value);
|
||||
|
||||
#endif /* LIBWINDMILL_H */
|
|
@ -0,0 +1,27 @@
|
|||
/* *****************************************************************************
|
||||
* libwindmill/internals.h -- libwindmill internal utilities.
|
||||
* Copyright (C) 2017 Olivier "Ninestars" Lanneau
|
||||
* Copyright (C) 2017 Thomas "Cakeisalie5" Touhey <thomas@touhey.fr>
|
||||
*
|
||||
* This file is part of libwindmill.
|
||||
* libwindmill is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 3.0 of the License,
|
||||
* or (at your option) any later version.
|
||||
*
|
||||
* libwindmill is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with libwindmill; if not, see <http://www.gnu.org/licenses/>.
|
||||
* ************************************************************************** */
|
||||
#ifndef LIBWINDMILL_INTERNALS_H
|
||||
# define LIBWINDMILL_INTERNALS_H
|
||||
# include <libwindmill.h>
|
||||
|
||||
void wml_set_vertex_xyz(wml_vertex_t *vertex, int x, int y, int z);
|
||||
void wml_set_vertex_txy(wml_vertex_t *vertex, char tx, char ty);
|
||||
|
||||
#endif /* LIBWINDMILL_INTERNALS_H */
|
|
@ -0,0 +1,191 @@
|
|||
/* *****************************************************************************
|
||||
* draw.c -- draw the scene.
|
||||
* Copyright (C) 2017 Olivier "Ninestars" Lanneau
|
||||
* Copyright (C) 2017 Thomas "Cakeisalie5" Touhey <thomas@touhey.fr>
|
||||
*
|
||||
* This file is part of libwindmill.
|
||||
* libwindmill is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 3.0 of the License,
|
||||
* or (at your option) any later version.
|
||||
*
|
||||
* libwindmill is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with libwindmill; if not, see <http://www.gnu.org/licenses/>.
|
||||
* ************************************************************************** */
|
||||
#include <libwindmill/internals.h>
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Rectangle */
|
||||
/* ************************************************************************** */
|
||||
static void render_rectangle_part(wml_scene_t *scene,
|
||||
wml_texture_t *texture, wml_vertex_t *vertex0,
|
||||
wml_vertex_t *vertex1, wml_vertex_t *vertex2,
|
||||
wml_vertex_t *vertex3)
|
||||
{
|
||||
if (texture == hidden) {
|
||||
/* do nothing */
|
||||
} else if (texture == scene->black) {
|
||||
wml_render_triangle_black(scene, vertex0, vertex1, vertex2);
|
||||
wml_render_triangle_black(scene, vertex1, vertex3, vertex2);
|
||||
} else if (texture == scene->white) {
|
||||
wml_render_triangle_white(scene, vertex0, vertex1, vertex2);
|
||||
wml_render_triangle_white(scene, vertex1, vertex3, vertex2);
|
||||
} else {
|
||||
wml_set_vertex_txy(vertex0, 0, texture->height);
|
||||
wml_set_vertex_txy(vertex1, texture->width, texture->height);
|
||||
wml_set_vertex_txy(vertex2, 0, 0);
|
||||
wml_set_vertex_txy(vertex3, texture->width, 0);
|
||||
|
||||
wml_render_triangle(scene, vertex0, vertex1, vertex2, texture);
|
||||
wml_render_triangle(scene, vertex1, vertex3, vertex2, texture);
|
||||
}
|
||||
}
|
||||
|
||||
static void render_rectangle(wml_scene_t *scene, wml_polygon_t *polygon,
|
||||
float cosinus, float sinus)
|
||||
{
|
||||
wml_vertex_t vertex0, vertex1, vertex2, vertex3;
|
||||
|
||||
int x0 = polygon->x0, y0 = polygon->y0, z0 = polygon->z0;
|
||||
int x1 = polygon->x1, y1 = polygon->y1, z1 = polygon->z1;
|
||||
int x2 = polygon->x2, y2 = polygon->y2, z2 = polygon->z2;
|
||||
int x3 = x1 + x2 - x0, y3 = y1 + y2 - y0, z3 = z1 + z2 - z0;
|
||||
|
||||
wml_set_vertex_xyz(&vertex0, x0, y0, z0);
|
||||
wml_set_vertex_xyz(&vertex1, x1, y1, z1);
|
||||
wml_set_vertex_xyz(&vertex2, x2, y2, z2);
|
||||
wml_set_vertex_xyz(&vertex3, x3, y3, z3);
|
||||
|
||||
/* object dynamique */
|
||||
wml_dynamic(&vertex0, polygon->axe,
|
||||
current_object->x, polygon->y, cosinus, sinus);
|
||||
wml_dynamic(&vertex1, polygon->axe,
|
||||
current_object->x, polygon->y, cosinus, sinus);
|
||||
wml_dynamic(&vertex2, polygon->axe,
|
||||
current_object->x, polygon->y, cosinus, sinus);
|
||||
wml_dynamic(&vertex3, polygon->axe,
|
||||
current_object->x, polygon->y, cosinus, sinus);
|
||||
|
||||
/* calcul des coordonnées après rotation de la caméra et projection
|
||||
* des coordonnées 3D sur l'écran */
|
||||
wml_transform(&vertex0);
|
||||
wml_transform(&vertex1);
|
||||
wml_transform(&vertex2);
|
||||
wml_transform(&vertex3);
|
||||
|
||||
/* si devant la caméra */
|
||||
if (vertex0.z < 0 && vertex1.z < 0 && vertex2.z < 0
|
||||
&& vertex3.z < 0) {
|
||||
int area = wml_edge(&vertex0, &vertex1, &vertex2);
|
||||
if (area > 0) render_rectangle_part(scene,
|
||||
current_rect->texture_front,
|
||||
&vertex0, &vertex1, &vertex2, &vertex3);
|
||||
if (area < 0) render_rectangle_part(scene,
|
||||
current_rect->texture_back,
|
||||
&vertex0, &vertex2, &vertex1, &vertex3);
|
||||
}
|
||||
}
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Triangle */
|
||||
/* ************************************************************************** */
|
||||
static void render_triangle_part(wml_scene_t *scene,
|
||||
wml_texture_t *texture, wml_vertex_t *vertex0,
|
||||
wml_vertex_t *vertex1, wml_vertex_t *vertex2)
|
||||
{
|
||||
if (texture == hidden) {
|
||||
/* do nothing */
|
||||
} else if (texture == scene->black) {
|
||||
wml_render_triangle_black(scene, vertex0, vertex1, vertex2);
|
||||
} else if (texture == scene->white) {
|
||||
wml_render_triangle_white(scene, vertex0, vertex1, vertex2);
|
||||
} else {
|
||||
wml_set_vertex_txy(vertex0, 0, texture->height);
|
||||
wml_set_vertex_txy(vertex1, texture->width, texture->height);
|
||||
wml_set_vertex_txy(vertex2, texture->width, 0);
|
||||
|
||||
wml_render_triangle(scene, vertex0, vertex1, vertex2, texture);
|
||||
}
|
||||
}
|
||||
|
||||
static void render_triangle(wml_scene_t *scene,
|
||||
wml_object_t *object, wml_triangle_t *triangle,
|
||||
float cosinus, float sinus)
|
||||
{
|
||||
wml_vertex_t vertex0, vertex1, vertex2;
|
||||
|
||||
int x0 = triangle->x0, y0 = triangle->y0, z0 = triangle->z0;
|
||||
int x1 = triangle->x1, y1 = triangle->y1, z1 = triangle->z1;
|
||||
int x2 = triangle->x2, y2 = triangle->y2, z2 = triangle->z2;
|
||||
|
||||
wml_set_vertex_xyz(&vertex0, x0, y0, z0);
|
||||
wml_set_vertex_xyz(&vertex1, x1, y1, z1);
|
||||
wml_set_vertex_xyz(&vertex2, x2, y2, z2);
|
||||
|
||||
/* object dynamique */
|
||||
wml_dynamic(&vertex0, triangle->axe,
|
||||
object->x, object->y, cosinus, sinus);
|
||||
wml_dynamic(&vertex1, polygon->axe,
|
||||
object->x, object->y, cosinus, sinus);
|
||||
wml_dynamic(&vertex2, polygon->axe,
|
||||
object->x, object->y, cosinus, sinus);
|
||||
|
||||
/* calcul des coordonnées après rotation de la caméra et projection
|
||||
* des coordonnées 3D sur l'écran */
|
||||
wml_transform(&vertex0);
|
||||
wml_transform(&vertex1);
|
||||
wml_transform(&vertex2);
|
||||
|
||||
/* si devant la caméra */
|
||||
if (vertex0.z < 0 && vertex1.z < 0 && vertex2.z < 0) {
|
||||
int area = wml_edge(&vertex0, &vertex1, &vertex2);
|
||||
if (area > 4) render_triangle_part(scene,
|
||||
current_rect->texture_front,
|
||||
&vertex0, &vertex1, &vertex2, &vertex3);
|
||||
if (area < 4) render_triangle_part(scene,
|
||||
current_rect->texture_back,
|
||||
&vertex0, &vertex2, &vertex1, &vertex3);
|
||||
}
|
||||
}
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Main function */
|
||||
/* ************************************************************************** */
|
||||
/**
|
||||
* wml_render_draw:
|
||||
* Render.
|
||||
*
|
||||
* @arg scene the scene to render.
|
||||
*/
|
||||
|
||||
void wml_render_draw(wml_scene_t *scene)
|
||||
{
|
||||
wml_update_camera(scene);
|
||||
memset(scene->z_buffer, 0xFF, scene->z_buffer_size * 2);
|
||||
|
||||
for (int i = 0; i < scene->map.list_object_size; i++) {
|
||||
wml_object_t *current_object = scene->map.list_object[i];
|
||||
|
||||
/* object dynamique */
|
||||
float cosinus, sinus;
|
||||
if (current_object->axe == N) {
|
||||
cosinus = 0;
|
||||
sinus = 1;
|
||||
} else {
|
||||
cosinus = cosf(current_object->angle);
|
||||
sinus = sinf(current_object->angle);
|
||||
}
|
||||
|
||||
for (int j = 0; j < current_object->list_rect_size; j++)
|
||||
render_rectangle(scene, ¤t_object->list_rect[j],
|
||||
cosinus, sinus);
|
||||
for (int j = 0; j < current_object->list_tri_size; j++)
|
||||
render_triangle(scene, ¤t_object->list_tri[j],
|
||||
cosinus, sinus);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
/* *****************************************************************************
|
||||
* dynamic.c -- dynamic thingies.
|
||||
* Copyright (C) 2017 Olivier "Ninestars" Lanneau
|
||||
* Copyright (C) 2017 Thomas "Cakeisalie5" Touhey <thomas@touhey.fr>
|
||||
*
|
||||
* This file is part of libwindmill.
|
||||
* libwindmill is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 3.0 of the License,
|
||||
* or (at your option) any later version.
|
||||
*
|
||||
* libwindmill is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with libwindmill; if not, see <http://www.gnu.org/licenses/>.
|
||||
* ************************************************************************** */
|
||||
#include <libwindmill/internals.h>
|
||||
|
||||
void wml_dynamic(wml_vertex_t *vertex, int axe, int x, int y, int z,
|
||||
float cosinus, float sinus)
|
||||
{
|
||||
int vertex_x = vertex->x,
|
||||
vertex_y = vertex->y,
|
||||
vertex_z = vertex->z;
|
||||
if (axe == N) {
|
||||
vertex->x = vertex_x + x;
|
||||
vertex->y = vertex_y + y;
|
||||
vertex->z = vertex_z + z;
|
||||
} else if (axe == X) {
|
||||
vertex->x = vertex_x + x;
|
||||
vertex->y = vertex_y * cosinus - vertex_z * sinus + y;
|
||||
vertex->z = vertex_z * sinus + vertex_z * cosinus + z;
|
||||
} else if (axe == Y) {
|
||||
vertex->x = vertex_x * cosinus - vertex_z * sinus + x;
|
||||
vertex->y = vertex_y + y;
|
||||
vertex->z = vertex_x * sinus + vertex_z * cosinus + z;
|
||||
} else if (axe == Z) {
|
||||
vertex->x = vertex_x * cosinus - vertex_y * sinus + x;
|
||||
vertex->y = vertex_x * sinus + vertex_y * cosinus + y;
|
||||
vertex->z = vertex_z + z;
|
||||
}
|
||||
}
|
||||
|
||||
void wml_transform(wml_scene_t *scene, wml_vertex_t *vertex)
|
||||
{
|
||||
int vertex_x = vertex->x - (int)scene->camera_x,
|
||||
vertex_y = vertex->y - (int)scene->camera_y,
|
||||
vertex_z = vertex->z - (int)scene->camera_z;
|
||||
|
||||
/* produit matriciel */
|
||||
int x = scene->a1 * vertex_x + scene->a2 * vertex_y;
|
||||
int y = scene->a4 * vertex_x + scene->a5 * vertex_y + scene->a6 * vertex_z;
|
||||
int z = scene->a7 * vertex_x + scene->a8 * vertex_y + scene->a9 * vertex_z;
|
||||
|
||||
/* perspective */
|
||||
if (z < 0) { /* z < near * 128 * 128 */
|
||||
vertex->x = -(x * scene->scale_coef + 8192) / z + shift_x;
|
||||
vertex->y = -(y * scene->scale_coef + 8192) / z + shift_y;
|
||||
vertex->z = 8192 / z;
|
||||
|
||||
/* calcul de z normalise entre les deux plans de clipping */
|
||||
vertex->z_normalized = -(0xFFFF *
|
||||
(scene->near_coef * z + scene->far_coef) + 32767) / z;
|
||||
} else
|
||||
vertex->z = 1;
|
||||
}
|
|
@ -0,0 +1,121 @@
|
|||
/* *****************************************************************************
|
||||
* render.c -- draw the triangles.
|
||||
* Copyright (C) 2017 Olivier "Ninestars" Lanneau
|
||||
* Copyright (C) 2017 Thomas "Cakeisalie5" Touhey <thomas@touhey.fr>
|
||||
*
|
||||
* This file is part of libwindmill.
|
||||
* libwindmill is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 3.0 of the License,
|
||||
* or (at your option) any later version.
|
||||
*
|
||||
* libwindmill is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with libwindmill; if not, see <http://www.gnu.org/licenses/>.
|
||||
* ************************************************************************** */
|
||||
#include <libwindmill/internals.h>
|
||||
|
||||
void wml_render_triangle(wml_scene_t *scene,
|
||||
wml_vertex_t *vertex1, wml_vertex_t *vertex2, wml_vertex_t *vertex3,
|
||||
wml_texture_t *texture)
|
||||
{
|
||||
/* calcul du rectangle circonscrit au triangle */
|
||||
int min_x = max(scene->viewport_x1 - 64,
|
||||
min(vertex0->x, min(vertex1->x, vertex2->x)));
|
||||
int max_x = min(scene->viewport_x2 - 64,
|
||||
max(vertex0->x, max(vertex1->x, vertex2->x)));
|
||||
int min_y = max(scene->viewport_y1 - 32,
|
||||
min(vertex0->y, min(vertex1->y, vertex2->y)));
|
||||
int max_y = min(scene->viewport_y2 - 32,
|
||||
max(vertex0->y, max(vertex1->y, vertex2->y)));
|
||||
|
||||
/* pré-calcul des coordonnées de la texture */
|
||||
int tx0 = vertex0->tx * vertex0->z;
|
||||
int ty0 = vertex0->ty * vertex0->z;
|
||||
int tx1 = vertex1->tx * vertex1->z;
|
||||
int ty1 = vertex1->ty * vertex1->z;
|
||||
int tx2 = vertex2->tx * vertex2->z;
|
||||
int tx2 = vertex2->ty * vertex2->z;
|
||||
|
||||
/* calcul des produits vectoriels */
|
||||
int px = min_x, py = min_y;
|
||||
int w0_start = wml_edge_start(vertex1, vertex2, px, py);
|
||||
int w0_step_x = wml_edge_step_x(vertex1, vertex2);
|
||||
int w0_step_y = wml_edge_step_y(vertex1, vertex2);
|
||||
int w1_start = wml_edge_start(vertex2, vertex0, px, py);
|
||||
int w1_step_x = wml_edge_step_x(vertex2, vertex0);
|
||||
int w1_step_y = wml_edge_step_y(vertex2, vertex0);
|
||||
int w2_start = wml_edge_start(vertex0, vertex1, px, py);
|
||||
int w2_step_x = wml_edge_step_x(vertex0, vertex1);
|
||||
int w2_step_y = wml_edge_step_y(vertex0, vertex1);
|
||||
|
||||
/* calcul de l'aire du triangle */
|
||||
int area = wml_edge(vertex0, vertex1, vertex2);
|
||||
|
||||
/* ? */
|
||||
int z_num_start = (w0_start * vertex0->z_normalized
|
||||
+ w1_start * vertex1->z_normalized
|
||||
+ w2_start * vertex2->z_normalized) / area;
|
||||
int z_num_step_x = (w0_step_x * vertex0->z_normalized
|
||||
+ w1_step_x * vertex1->z_normalized
|
||||
+ w2_step_x * vertex2->z_normalized) / area;
|
||||
int z_num_step_y = (w0_step_y * vertex0->z_normalized
|
||||
+ w1_step_y * vertex1->z_normalized
|
||||
+ w2_step_y * vertex2->z_normalized) / area;
|
||||
|
||||
/* ? */
|
||||
int z_div_start = w0_start * vertex0->z
|
||||
+ w1_start * vertex1->z
|
||||
+ w2_start * vertex2->z;
|
||||
int z_div_step_x = w0_step_x * vertex0->z
|
||||
+ w1_step_x * vertex1->z
|
||||
+ w2_step_x * vertex2->z;
|
||||
int z_div_step_y = w0_step_y * vertex0->z
|
||||
+ w1_step_y * vertex1->z
|
||||
+ w2_step_y * vertex2->z;
|
||||
|
||||
/* pré-calcul largeur en octet des tableaux */
|
||||
int nbw_tex = (texture->width - 1) / 8 + 1;
|
||||
for (int x = min_x; x <= max_x; x++) {
|
||||
int w0 = w0_start, w1 = w1_start, w2 = w2_start;
|
||||
int z_num = z_num_start, z_div = z_div_start;
|
||||
int offset_vram = (x >> 3) + 520;
|
||||
char mask_vram = 128 >> (x & 7);
|
||||
|
||||
/* parcours en colonne */
|
||||
for (int y = min_y; y <= max_y; y++) {
|
||||
if (w0 >= 0 && w1 >= 0 && w2 >= 0 && z_num > 0) {
|
||||
int address = x + y * z_buffer_width + z_buffer_offset;
|
||||
if (z_num <= z_buffer[address]) {
|
||||
z_buffer[address] = z_num;
|
||||
/* calcul des coordonnées pour la texture */
|
||||
int f_tx = (w0 * tx0 + w1 * tx1 + w2 * tx2) / z_div;
|
||||
int f_ty = (w0 * ty0 + w1 * ty1 + w2 * ty2) / z_div;
|
||||
|
||||
/* calcul du masque pour l'octet */
|
||||
char mask_tx = 128 >> (f_tx & 7);
|
||||
int black = texture->sprite[(f_tx >> 3) + (f_ty * nbw_tex)]
|
||||
& mask_tx;
|
||||
|
||||
/* affichage du pixel */
|
||||
if (black) vram[(y << 4) + offset_vram] |= mask_vram;
|
||||
else vram[(y << 4) + offset_vram] &= ~mask_vram;
|
||||
}
|
||||
}
|
||||
w0 += w0_step_y;
|
||||
w1 += w1_step_y;
|
||||
w2 += w2_step_y;
|
||||
z_num += z_num_step_y;
|
||||
z_div += z_div_step_y;
|
||||
}
|
||||
w0_start += w0_step_x;
|
||||
w1_start += w1_step_x;
|
||||
w2_start += w2_step_x;
|
||||
z_num_start += z_num_step_x;
|
||||
z_div_start += z_div_step_x;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
/* *****************************************************************************
|
||||
* update.c -- update the scene.
|
||||
* Copyright (C) 2017 Olivier "Ninestars" Lanneau
|
||||
* Copyright (C) 2017 Thomas "Cakeisalie5" Touhey <thomas@touhey.fr>
|
||||
*
|
||||
* This file is part of libwindmill.
|
||||
* libwindmill is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 3.0 of the License,
|
||||
* or (at your option) any later version.
|
||||
*
|
||||
* libwindmill is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with libwindmill; if not, see <http://www.gnu.org/licenses/>.
|
||||
* ************************************************************************** */
|
||||
#include <libwindmill/internals.h>
|
||||
|
||||
/**
|
||||
* wml_update_camera:
|
||||
* Update the camera.
|
||||
*
|
||||
* @arg scene the scene to update.
|
||||
*/
|
||||
|
||||
void wml_update_camera(wml_scene_t *scene)
|
||||
{
|
||||
scene->camera_yaw = (int)(scene->camera_yaw + 360) % 360;
|
||||
float camera_yaw_rad = M_PI * scene->camera_yaw / 180.0;
|
||||
|
||||
/* calculate intermediate value */
|
||||
float camera_pitch_rad = M_PI * scene->camera_pitch / 180.0;
|
||||
float cos_yaw = cosf(camera_yaw_rad), sin_yaw = sinf(camera_yaw_rad);
|
||||
float cos_pitch = cosf(camera_pitch_rad);
|
||||
float sin_pitch = sinf(camera_pitch_rad);
|
||||
|
||||
/* set final values */
|
||||
scene->a1 = 128.0 * cos_yaw;
|
||||
scene->a2 = 128.0 * -sin_yaw;
|
||||
scene->a3 = 0.0;
|
||||
scene->a4 = 128.0 * cos_pitch * sin_yaw;
|
||||
scene->a5 = 128.0 * cos_pitch * cos_yaw;
|
||||
scene->a6 = 128.0 * -sin_pitch;
|
||||
scene->a7 = 128.0 * sin_pitch * sin_yaw;
|
||||
scene->a8 = 128.0 * sin_pitch * cos_yaw;
|
||||
scene->a9 = 128.0 * cos_pitch;
|
||||
}
|
||||
|
||||
/**
|
||||
* wml_update_viewport:
|
||||
* Update the viewport.
|
||||
*
|
||||
* @arg scene the scene to update.
|
||||
*/
|
||||
|
||||
void wml_update_viewport(wml_scene_t *scene)
|
||||
{
|
||||
free(scene->z_buffer);
|
||||
scene->shift_x = (scene->viewport_x1 + scene->viewport_x2 - 128) / 2;
|
||||
scene->shift_y = (scene->viewport_y1 + scene->viewport_y2 - 64) / 2;
|
||||
|
||||
scene->z_buffer_size = (scene->viewport_x2 - scene->viewport_x1)
|
||||
* (scene->viewport_y2 -scene->viewport_y2);
|
||||
scene->z_buffer = (unsigned short*)calloc(scene->z_buffer_size, 2);
|
||||
scene->z_buffer_width = scene->viewport_x2 - scene->viewport_x1;
|
||||
scene->z_buffer_offset = 64 - scene->viewport_x1
|
||||
+ scene->z_buffer_width * (32 - scene->viewport_y1);
|
||||
memset(scene->z_buffer, 0xFF, scene->z_buffer_size * 2);
|
||||
}
|
Loading…
Reference in New Issue