"git@gitlab.caltech.edu:cs137-21sp/project03.git" did not exist on "df9dd0cdf2174a4cb0c35d84f09fb843bfa27629"
Source
...
Target
Commits (24)
Showing with 631 additions and 13 deletions
+631 -13
color:
script: "/testers/cs3/project02/color/test"
list:
script: "/testers/cs3/project02/list/test"
vector:
script: "/testers/cs3/project02/vector/test"
polygon:
script: "/testers/cs3/project02/polygon/test"
# List of demo programs
DEMOS = bounce
DEMOS = gravity
# List of C files in "libraries" that you will write.
# This also defines the order in which the tests are run.
STUDENT_LIBS = vector vec_list polygon
STUDENT_LIBS = vector list polygon color
# find <dir> is the command to find files in a directory
# ! -name .gitignore tells find to ignore the .gitignore
......@@ -49,7 +49,7 @@ CFLAGS += -Iinclude $(shell sdl2-config --cflags) -Wall -g -fno-omit-frame-point
# -g enables DWARF support, for debugging purposes
# -gsource-map --source-map-base http://localhost:8000/bin/ creates a source map from the C file for debugging
EMCC = emcc
EMCC_FLAGS = -s EXIT_RUNTIME=1 -s ALLOW_MEMORY_GROWTH=1 -s INITIAL_MEMORY=655360000 -s USE_SDL=2 -s USE_SDL_GFX=2 -s USE_SDL_IMAGE=2 -s SDL2_IMAGE_FORMATS='["png"]' -s USE_SDL_TTF=2 -s USE_SDL_MIXER=2 -s ASSERTIONS=1 -O2 -g -gsource-map --source-map-base http://labradoodle.caltech.edu:$(shell cs3-port)/bin/
EMCC_FLAGS = -s EXIT_RUNTIME=1 -s ALLOW_MEMORY_GROWTH=1 -s INITIAL_MEMORY=655360000 -s USE_SDL=2 -s USE_SDL_GFX=2 -s USE_SDL_IMAGE=2 -s SDL2_IMAGE_FORMATS='["png"]' -s USE_SDL_TTF=2 -s USE_SDL_MIXER=2 -s ASSERTIONS=1 -O2 -g -gsource-map --use-preload-plugins --preload-file assets --source-map-base http://labradoodle.caltech.edu:$(shell cs3-port)/bin/
# Compiler flag that links the program with the math library
LIB_MATH = -lm
......@@ -69,7 +69,7 @@ WASM_STUDENT_OBJS = $(addprefix out/,$(STUDENT_LIBS:=.wasm.o))
# List of test suite executables, e.g. "bin/test_suite_vector"
TEST_BINS = $(addprefix bin/test_suite_,$(STUDENT_LIBS))
# List of demo executables, i.e. "bin/bounce.html".
DEMO_BINS = $(addsuffix .html, $(addprefix bin/,$(DEMOS)))
DEMO_BINS = $(addsuffix .demo.html, $(addprefix bin/,$(DEMOS)))
# The first Make rule. It is relatively simple
# It builds the files in TEST_BINS and DEMO_BINS, as well as making the server for the demos
......@@ -77,6 +77,9 @@ DEMO_BINS = $(addsuffix .html, $(addprefix bin/,$(DEMOS)))
# You can execute this rule by running the command "make all", or just "make".
all: $(TEST_BINS) $(DEMO_BINS) server
demo: $(DEMO_BINS) server
game: bin/game.html server
# Make the python server for your demos
# To run this, type 'make server'
server:
......@@ -113,13 +116,22 @@ out/%.wasm.o: tests/%.c # or "tests"
# Builds bin/%.html by linking the necessary .wasm.o files.
# Unlike the out/%.wasm.o rule, this uses the LIBS flags and omits the -c flag,
# since it is building a full executable. Also notice it uses our EMCC_FLAGS
bin/%.html: out/emscripten.wasm.o out/%.wasm.o out/sdl_wrapper.wasm.o $(WASM_STUDENT_OBJS)
$(EMCC) $(EMCC_FLAGS) $(CFLAGS) $(LIBS) $^ -o $@
DEMO_REF = color emscripten list polygon sdl_wrapper vector
DEMO_REF_OBJS = $(addprefix ref/,$(DEMO_REF:=.wasm.ref.o))
GAME_REF = emscripten vector
GAME_REF_OBJS = $(addprefix ref/,$(GAME_REF:=.wasm.ref.o))
bin/%.demo.html: out/%.wasm.o $(DEMO_REF_OBJS)
$(EMCC) $(EMCC_FLAGS) $(CFLAGS) $(LIBS) $^ -o $@
bin/game.html: out/game.wasm.o out/sdl_wrapper.wasm.o $(GAME_REF_OBJS)
$(EMCC) $(EMCC_FLAGS) $(CFLAGS) $(LIBS) $^ -o $@
# Builds the test suite executables from the corresponding test .o file
# and the library .o files. The only difference from the demo build command
# is that it doesn't link the SDL libraries.
bin/test_suite_%: out/test_suite_%.o out/test_util.o $(STUDENT_OBJS) $(STAFF_OBJS)
bin/test_suite_%: out/test_suite_%.o out/test_util.o $(STUDENT_OBJS)
$(CC) $(CFLAGS) $(LIBS) $^ -o $@
# Runs the tests. "$(TEST_BINS)" requires the test executables to be up to date.
......@@ -145,3 +157,4 @@ clean:
.PRECIOUS: out/%.o
# Tells Make not to delete the wasm.o files after the executable is built
.PRECIOUS: out/%.wasm.o
.PRECIOUS: ref/%.wasm.ref.o
# project02
For this project, you should begin by adding all your files from the previous project (except for your Makefile and .vscode folder - we've made a few changes to those). Because these diverge based on group, we're asking you to do this manually.
If you can't figure out the `git` comands, please ask at office hours!
Please also remember to submit the Qualtrics form before the deadline! Link here: https://caltech.az1.qualtrics.com/jfe/form/SV_6imPeo1nHVGhSK2
File added
assets/cs2_logo.png

307 KB

assets/cs3_logo.png

649 KB

*
!.gitignore
#include "state.h"
state_t *emscripten_init() {}
void emscripten_main(state_t *state) { /** Write your game code here. */ }
void emscripten_free(state_t *state) {}
\ No newline at end of file
#include "state.h"
state_t *emscripten_init() {}
void emscripten_main(state_t *state) { /** Write your demo code here. */ }
void emscripten_free(state_t *state) {}
\ No newline at end of file
#ifndef __COLOR_H__
#define __COLOR_H__
typedef struct color color_t;
/**
* Initialize a color object.
*
* @param red the double value for red
* @param green the double value for green
* @param blue the double value for blue
* @return a pointer to a color_t object
*/
color_t *color_init(double red, double green, double blue);
/**
* Return the double value of the red component of a color.
*
* @param color a color with r, g, b values
* @return the red component of the color object
*/
double color_get_red(color_t *color);
/**
* Return the double value of the green component of a color.
*
* @param color a color with r, g, b values
* @return the green component of the color object
*/
double color_get_green(color_t *color);
/**
* Return the double value of the blue component of a color.
*
* @param color a color with r, g, b values
* @return the blue component of the color object
*/
double color_get_blue(color_t *color);
/**
* Randomly generate rgb values for color of polygon.
*
* @return a pointer to a color object with randomly generated rgb values
*/
color_t *get_color();
/**
* Free memory allocated for the color object.
*
* @param color a color with r, g, b values
*/
void color_free(color_t *color);
#endif // #ifndef __COLOR_H__
#ifndef __LIST_H__
#define __LIST_H__
#include "vector.h"
#include <stddef.h>
/**
* A growable array of pointers.
* Can store values of any pointer type (e.g. vector_t*, polygon_t*).
* The list automatically grows its internal array when more capacity is needed.
*/
typedef struct list list_t;
/**
* Allocates memory for a new list with space for the given number of elements.
* The list is initially empty.
* Asserts that the required memory was allocated.
*
* @param initial_capacity the number of list elements to allocate space for
* @return a pointer to the newly allocated list
*/
list_t *list_init(size_t initial_capacity);
/**
* Releases the memory allocated for a list.
*
* @param list a pointer to a list returned from list_init()
*/
void list_free(list_t *list);
/**
* Gets the size of a list (the number of occupied elements).
* Note that this is NOT the list's capacity.
*
* @param list a pointer to a list returned from list_init()
* @return the number of elements in the list
*/
size_t list_size(list_t *list);
/**
* Gets the element at a given index in a list.
* Asserts that the index is valid, given the list's current size.
*
* @param list a pointer to a list returned from list_init()
* @param index an index in the list (the first element is at 0)
* @return the element at the given index, as a void*
*/
void *list_get(list_t *list, size_t index);
/**
* Appends an element to the end of a list.
* If the list is filled to capacity, resizes the list to fit more elements
* and asserts that the resize succeeded.
* Also asserts that the value being added is non-NULL.
*
* @param list a pointer to a list returned from list_init()
* @param value the element to add to the end of the list
*/
void list_add(list_t *list, void *value);
/**
* Removes the element at a given index in a list and returns it,
* moving all subsequent elements towards the start of the list.
* Asserts that the index is valid, given the list's current size.
*
* @param list a pointer to a list returned from list_init()
* @return the element at the given index in the list
*/
void *list_remove(list_t *list, size_t index);
#endif // #ifndef __LIST_H__
#ifndef __POLYGON_H__
#define __POLYGON_H__
#include "color.h"
#include "list.h"
typedef struct polygon polygon_t;
/**
* Initialize a polygon object given a list of vertices.
*
* @param points the list of vertices that make up the polygon
* @param initial_velocity a vector representing the initial velocity of the
* polygon
* @param rotation_speed the rotation angle of the polygon per unit time
* @param red double value between 0 and 1 representing the red of the polygon
* @param green double value between 0 and 1 representing the green of the
* polygon
* @param blue double value between 0 and 1 representing the blue of the polygon
* @return a polygon object pointer
*/
polygon_t *polygon_init(list_t *points, vector_t initial_velocity,
double rotation_speed, double red, double green,
double blue);
/**
* Return the list of vectors representing the vertices of the polygon.
*
* @param polygon the pointer to the polygon
* @return a list of vectors
*/
list_t *polygon_get_points(polygon_t *polygon);
/**
* Translate and rotate the polygon then update velocity based on gravity.
*
* @param polygon the pointer to the polygon
* @param time_elapsed time/# of frames elapsed since the last tick
*/
void polygon_move(polygon_t *polygon, double time_elapsed);
/**
* Set the x and y components of a polygon's velocity vector.
*
* @param polygon the pointer to the polygon
* @param v_x x component of velocity to set
* @param v_y y component of velocity to set
*/
void polygon_set_velocity(polygon_t *polygon, double v_x, double v_y);
/**
* Free memory allocated for object associated with a polygon.
*
* @param polygon the pointer to the polygon
*/
void polygon_free(polygon_t *polygon);
/**
* Return x-component of polygon's velocity vector.
*
* @param polygon the pointer to the polygon
* @return the x-velocity of a polygon
*/
double polygon_get_velocity_x(polygon_t *polygon);
/**
* Return y-component of polygon's velocity vector.
*
* @param polygon the pointer to the polygon
* @return the y-velocity of a polygon
*/
double polygon_get_velocity_y(polygon_t *polygon);
/**
* Computes the area of a polygon.
* See https://en.wikipedia.org/wiki/Shoelace_formula#Statement.
*
* @param polygon the pointer to the polygon,
* listed in a counterclockwise direction. There is an edge between
* each pair of consecutive vertices, plus one between the first and last.
* @return the area of the polygon
*/
double polygon_area(polygon_t *polygon);
/**
* Computes the center of mass of a polygon.
* See https://en.wikipedia.org/wiki/Centroid#Of_a_polygon.
*
* @param polygon the pointer to the polygon,
* listed in a counterclockwise direction. There is an edge between
* each pair of consecutive vertices, plus one between the first and last.
* @return the centroid of the polygon
*/
vector_t polygon_centroid(polygon_t *polygon);
/**
* Translates all vertices in a polygon by a given vector.
* Note: mutates the original polygon.
*
* @param polygon the pointer to the polygon
* @param translation the vector to add to each vertex's position
*/
void polygon_translate(polygon_t *polygon, vector_t translation);
/**
* Rotates vertices in a polygon by a given angle about a given point.
*
* @param polygon the pointer to the polygon
* @param angle the angle to rotate the polygon, in radians.
* A positive angle means counterclockwise.
* @param point the point to rotate around
*/
void polygon_rotate(polygon_t *polygon, double angle, vector_t point);
/**
* Return the polygon's color.
*
* @param polygon the list of vertices that make up the polygon
* @return the color_t struct representing the color
*/
color_t *polygon_get_color(polygon_t *polygon);
#endif // #ifndef __POLYGON_H__
#ifndef __SDL_WRAPPER_H__
#define __SDL_WRAPPER_H__
#include "list.h"
#include "polygon.h"
#include <stdbool.h>
/**
* Initializes the SDL window and renderer.
* Must be called once before any of the other SDL functions.
*
* @param min the x and y coordinates of the bottom left of the scene
* @param max the x and y coordinates of the top right of the scene
*/
void sdl_init(vector_t min, vector_t max);
/**
* Checks whether the window has been closed.
*
* @return true if the window was closed, false otherwise
*/
bool sdl_is_done(void);
/**
* Clears the screen. Should be called before drawing polygons in each frame.
*/
void sdl_clear(void);
/**
* Draws a polygon from the given list of vertices and a color.
*
* @param poly the polygon struct to draw
* @param r the red component of the color, from 0 to 1
* @param g the green component of the color, from 0 to 1
* @param b the blue component of the color, from 0 to 1
*/
void sdl_draw_polygon(polygon_t *poly, float r, float g, float b);
/**
* Displays the rendered frame on the SDL window.
* Must be called after drawing the polygons in order to show them.
*/
void sdl_show(void);
/**
* Gets the amount of time that has passed since the last time
* this function was called, in seconds.
*
* @return the number of seconds that have elapsed
*/
double time_since_last_tick(void);
#endif // #ifndef __SDL_WRAPPER_H__
#include "math.h"
#include "polygon.h"
#include "sdl_wrapper.h"
#include <stdio.h>
#include <stdlib.h>
/**
* Stores the demo state
* Use this to store any variable needed every 'tick' of your demo
*/
typedef struct state state_t;
/**
* Initializes sdl as well as the variables needed
* Creates and stores all necessary variables for the demo in a created state
* variable Returns the pointer to this state (This is the state emscripten_main
* and emscripten_free work with)
*/
state_t *emscripten_init();
/**
* Called on each tick of the program
* Updates the state variables and display as necessary, depending on the time
* that has passed
*/
void emscripten_main(state_t *state);
/**
* Frees anything allocated in the demo
* Should free everything in state as well as state itself.
*/
void emscripten_free(state_t *state);
\ No newline at end of file
/** Common functions for tests. */
#ifndef __TEST_UTIL_H__
#define __TEST_UTIL_H__
#include "vector.h"
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
/**
* Returns whether two double values are nearly equal,
* i.e. within 10 ** -7 of each other.
* Floating-point math is approximate, so isclose() is preferable to ==.
* There are some exceptions: ints (<= 53 bits) and fractions whose denominators
* are powers of 2 (e.g. 0.5 or 0.75) can be represented exactly as a double.
*/
bool isclose(double d1, double d2);
/**
* Return if the components of two vectors are exactly equal.
* Floating-point math is approximate, so the result of a
* series of vector computations might not be exactly as expected.
*/
bool vec_equal(vector_t v1, vector_t v2);
/**
* Return if two vectors are close to each other; that is, if the corresponding
* components are within 1e-7 of each other.
* This may be more useful than vec_equal, because vector components are
* doubles, not integers, and floating-point math is approximate.
*/
bool vec_isclose(vector_t v1, vector_t v2);
/**
* Open the file 'filename', read one word into 'testname', and close the file.
* If the file cannot be found, exit with error.
*/
void read_testname(char *filename, char *testname, size_t testname_size);
/*
* This macro checks whether to run the test function (which will be true
* if the test is called without command-line arguments).
* Then, it calls the test function, and prints "<test-func> PASS".
*
* The macro can simply be called as
* DO_TEST(test_func_name)
* It doesn't matter if 'test_func_name' is a valid variable, because
* the macro is a simple text replacement done *before* compilation.
* No ; is needed after the closing ), because again, the macro is a simple
* text replacement, and the statements already have ;s.
*/
#define DO_TEST(TEST_FN) \
if (all_tests || strcmp(testname, #TEST_FN) == 0) { \
TEST_FN(); \
puts(#TEST_FN " PASS"); \
}
/**
* Executes function 'run' and returns whether it causes an assertion failure,
* as detected by a SIGABRT signal.
* Passes the auxiliary argument 'aux' to 'run', i.e. calls run(aux).
*/
bool test_assert_fail(void (*run)(void *aux), void *aux);
#endif // #ifndef __TEST_UTIL_H__
#ifndef __VECTOR_H__
#define __VECTOR_H__
/**
* A real-valued 2-dimensional vector.
* Positive x is towards the right; positive y is towards the top.
* vector_t is defined here instead of vector.c because it is passed *by value*.
*/
typedef struct {
double x;
double y;
} vector_t;
/**
* The zero vector, i.e. (0, 0).
* "extern" declares this global variable without allocating memory for it.
* You will need to define "const vector_t VEC_ZERO = ..." in vector.c.
*/
extern const vector_t VEC_ZERO;
/**
* Adds two vectors.
* Performs the usual componentwise vector sum.
*
* @param v1 the first vector
* @param v2 the second vector
* @return v1 + v2
*/
vector_t vec_add(vector_t v1, vector_t v2);
/**
* Subtracts two vectors.
* Performs the usual componentwise vector difference.
*
* @param v1 the first vector
* @param v2 the second vector
* @return v1 - v2
*/
vector_t vec_subtract(vector_t v1, vector_t v2);
/**
* Computes the additive inverse a vector.
* This is equivalent to multiplying by -1.
*
* @param v the vector whose inverse to compute
* @return -v
*/
vector_t vec_negate(vector_t v);
/**
* Multiplies a vector by a scalar.
* Performs the usual componentwise product.
*
* @param scalar the number to multiply the vector by
* @param v the vector to scale
* @return scalar * v
*/
vector_t vec_multiply(double scalar, vector_t v);
/**
* Computes the dot product of two vectors.
* See https://en.wikipedia.org/wiki/Dot_product#Algebraic_definition.
*
* @param v1 the first vector
* @param v2 the second vector
* @return v1 . v2
*/
double vec_dot(vector_t v1, vector_t v2);
/**
* Computes the cross product of two vectors,
* which lies along the z-axis.
* See https://en.wikipedia.org/wiki/Cross_product#Computing_the_cross_product.
*
* @param v1 the first vector
* @param v2 the second vector
* @return the z-component of v1 x v2
*/
double vec_cross(vector_t v1, vector_t v2);
/**
* Rotates a vector by an angle around (0, 0).
* The angle is given in radians.
* Positive angles are counterclockwise, according to the right hand rule.
* See https://en.wikipedia.org/wiki/Rotation_matrix.
* (You can derive this matrix by noticing that rotation by a fixed angle
* is linear and then computing what it does to (1, 0) and (0, 1).)
*
* @param v the vector to rotate
* @param angle the angle to rotate the vector
* @return v rotated by the given angle
*/
vector_t vec_rotate(vector_t v, double angle);
#endif // #ifndef __VECTOR_H__
#include "color.h"
#include <assert.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
const double COLOR = 255; // max value of each rgb value
struct color {
double red;
double green;
double blue;
};
color_t *color_init(double red, double green, double blue) {
color_t *color = malloc(sizeof(color_t));
assert(color);
color->red = red;
color->green = green;
color->blue = blue;
return color;
}
double color_get_red(color_t *color) { return color->red; }
double color_get_green(color_t *color) { return color->green; }
double color_get_blue(color_t *color) { return color->blue; }
color_t *get_color() {
double r = (double)rand();
double g = (double)rand();
double b = (double)rand();
r = fmod(r, COLOR) / COLOR;
g = fmod(g, COLOR) / COLOR;
b = fmod(b, COLOR) / COLOR;
return color_init(r, g, b);
}
void color_free(color_t *color) { free(color); }
#include "math.h"
#include "polygon.h"
#include "sdl_wrapper.h"
#include "state.h"
#include <stdio.h>
#include <stdlib.h>
#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#endif
state_t *state;
void loop() {
// If needed, generate a pointer to our initial state
if (!state) {
state = emscripten_init();
}
emscripten_main(state);
if (sdl_is_done()) { // Once our demo exits...
emscripten_free(state); // Free any state variables we've been using
#ifdef __EMSCRIPTEN__ // Clean up emscripten environment (if we're using it)
emscripten_cancel_main_loop();
emscripten_force_exit(0);
#else
exit(0);
#endif
return;
}
}
int main() {
#ifdef __EMSCRIPTEN__
// Set loop as the function emscripten calls to request a new frame
emscripten_set_main_loop_arg(loop, NULL, 0, 1);
#else
while (1) {
loop();
}
#endif
}
#include "list.h"
/**
* Implement list methods here!
* You should use the code for vec_list.c as a starting point and modify it to
* fit the new list_t interface.
*/