We're scanning horizontally across the screen, from (0,midy) to (midx,midy), and counting how many times it intersects the boundary of the polygon.
For each line, we have two endpoints, (x1,y1) and (x2,y2).
If (y1-midy)*(y2-midy)<0
ix#=x1+(x2-x1)*(midy-y1)/(y2-y1)
If ix<midx hits:+1
EndIf
The first line of code checks if y1 and y2 are on opposite sides of the line. (y1 - midy) will be positive or negative depending on if y1 is higher or lower than midy. The product (y1 - midy)*(y2 - midy) will be positive if y1 and y2 are both higher or both lower than midy, or negative if they're on opposite sides.
So once we know these points are on opposite sides of the line y=midy, we know that this line intersects our scan line, and we need to find out the x-coordinate of the point of intersection.
Now, if this x-coordinate is to the left of midx, then our scan line has to cross this line before it gets to (midx,midy), so we add a "hit" to our tally. Every time we cross a line, we switch from being inside the polygon to outside it, and vice versa. So, if we have an odd number of hits by the time we get to (midx,midy), then that point must be inside the polygon.
Looking at your trouble cases, yes, we need to deal with those. We can deal with case 2 by rejecting lines where y1=y2.
Looking at cases 1 and 3, the difference between them seems to be that in case 1, the two lines touching the scanline are both above it, whereas in case 3 one is below. It stands to reason that when ever you have a vertex of the polygon lying exactly on the scanline, there are exactly two lines coming out of it, so if we only count the ones pointing down, we can deal with case 3.
Here's a modified version of the code above, taking all this into account:
If y1<>y2 'deal with case 2
side#=(y1-midy)*(y2-midy)
If side<0
ix#=x1+(x2-x1)*(midy-y1)/(y2-y1)
If ix<midx hits:+1
ElseIf side=0 'deal with cases 1 and 3
If y1>midy hits:+1
If y2>midy hits:+1
EndIf
EndIf