Interesting part is in tdraw() which draws one triangle.
First find the bounding box of triangle from view space.
Iterate over pixels in that box.
Map pixel into barycentric coordinates of triangle. (distance from vertexes.)
Check zbuffer to see if visible.
Take dot product of light direction and triangle normal to get shading.
Use barycentric coordinates to interpolate where in texture map to sample shade.
Blend shading and lighting.
Update zbuffer and pixel color.
A model is made of lots of triangles. Each triangle has vertices with additional attributes that map into the texture map.
While true, you end up reading code with your variables more often than you write your variables so I tend to optimize for readability over ease of typing.
In a setting with much arithmetic "x" is also vastly easier to read. See pretty much any mathematics or physics paper or textbook -- made for reading...