mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-12-27 09:31:18 +00:00
Created font 2x2 to sprite converter. Improved a few bitwise operators.
This commit is contained in:
parent
beb30de7d1
commit
91da76e087
@ -2,6 +2,7 @@ package dk.camelot64.kickc.model.operators;
|
|||||||
|
|
||||||
import dk.camelot64.kickc.model.CompileError;
|
import dk.camelot64.kickc.model.CompileError;
|
||||||
import dk.camelot64.kickc.model.types.*;
|
import dk.camelot64.kickc.model.types.*;
|
||||||
|
import dk.camelot64.kickc.model.values.ConstantEnumerable;
|
||||||
import dk.camelot64.kickc.model.values.ConstantInteger;
|
import dk.camelot64.kickc.model.values.ConstantInteger;
|
||||||
import dk.camelot64.kickc.model.values.ConstantLiteral;
|
import dk.camelot64.kickc.model.values.ConstantLiteral;
|
||||||
import dk.camelot64.kickc.model.values.ConstantPointer;
|
import dk.camelot64.kickc.model.values.ConstantPointer;
|
||||||
@ -15,10 +16,10 @@ public class OperatorBitwiseAnd extends OperatorBinary {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ConstantLiteral calculateLiteral(ConstantLiteral left, ConstantLiteral right) {
|
public ConstantLiteral calculateLiteral(ConstantLiteral left, ConstantLiteral right) {
|
||||||
if(left instanceof ConstantInteger && right instanceof ConstantInteger) {
|
if(left instanceof ConstantPointer && right instanceof ConstantEnumerable) {
|
||||||
return new ConstantInteger(((ConstantInteger) left).getInteger() & ((ConstantInteger) right).getInteger());
|
return new ConstantPointer(((ConstantPointer) left).getLocation() & ((ConstantEnumerable) right).getInteger(), ((ConstantPointer) left).getElementType());
|
||||||
} else if(left instanceof ConstantPointer && right instanceof ConstantInteger) {
|
} else if(left instanceof ConstantEnumerable && right instanceof ConstantEnumerable) {
|
||||||
return new ConstantPointer(((ConstantPointer) left).getLocation() & ((ConstantInteger) right).getInteger(), ((ConstantPointer) left).getElementType());
|
return new ConstantInteger(((ConstantEnumerable)left).getInteger() & ((ConstantEnumerable) right).getInteger());
|
||||||
}
|
}
|
||||||
throw new CompileError("Calculation not implemented " + left + " " + getOperator() + " " + right);
|
throw new CompileError("Calculation not implemented " + left + " " + getOperator() + " " + right);
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,14 @@
|
|||||||
package dk.camelot64.kickc.model.operators;
|
package dk.camelot64.kickc.model.operators;
|
||||||
|
|
||||||
import dk.camelot64.kickc.model.CompileError;
|
import dk.camelot64.kickc.model.CompileError;
|
||||||
import dk.camelot64.kickc.model.types.*;
|
import dk.camelot64.kickc.model.types.SymbolType;
|
||||||
|
import dk.camelot64.kickc.model.types.SymbolTypeConversion;
|
||||||
|
import dk.camelot64.kickc.model.types.SymbolTypeInteger;
|
||||||
|
import dk.camelot64.kickc.model.types.SymbolTypePointer;
|
||||||
|
import dk.camelot64.kickc.model.values.ConstantEnumerable;
|
||||||
import dk.camelot64.kickc.model.values.ConstantInteger;
|
import dk.camelot64.kickc.model.values.ConstantInteger;
|
||||||
import dk.camelot64.kickc.model.values.ConstantLiteral;
|
import dk.camelot64.kickc.model.values.ConstantLiteral;
|
||||||
|
import dk.camelot64.kickc.model.values.ConstantPointer;
|
||||||
|
|
||||||
/** Binary bitwise or Operator ( x | y ) */
|
/** Binary bitwise or Operator ( x | y ) */
|
||||||
public class OperatorBitwiseOr extends OperatorBinary {
|
public class OperatorBitwiseOr extends OperatorBinary {
|
||||||
@ -14,8 +19,10 @@ public class OperatorBitwiseOr extends OperatorBinary {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ConstantLiteral calculateLiteral(ConstantLiteral left, ConstantLiteral right) {
|
public ConstantLiteral calculateLiteral(ConstantLiteral left, ConstantLiteral right) {
|
||||||
if(left instanceof ConstantInteger && right instanceof ConstantInteger) {
|
if(left instanceof ConstantPointer && right instanceof ConstantEnumerable) {
|
||||||
return new ConstantInteger(((ConstantInteger) left).getInteger() | ((ConstantInteger) right).getInteger());
|
return new ConstantPointer(((ConstantPointer) left).getLocation() | ((ConstantEnumerable) right).getInteger(), ((ConstantPointer) left).getElementType());
|
||||||
|
} else if(left instanceof ConstantEnumerable && right instanceof ConstantEnumerable) {
|
||||||
|
return new ConstantInteger(((ConstantEnumerable) left).getInteger() | ((ConstantEnumerable) right).getInteger());
|
||||||
}
|
}
|
||||||
throw new CompileError("Calculation not implemented " + left + " " + getOperator() + " " + right);
|
throw new CompileError("Calculation not implemented " + left + " " + getOperator() + " " + right);
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,10 @@ package dk.camelot64.kickc.model.operators;
|
|||||||
|
|
||||||
import dk.camelot64.kickc.model.CompileError;
|
import dk.camelot64.kickc.model.CompileError;
|
||||||
import dk.camelot64.kickc.model.types.*;
|
import dk.camelot64.kickc.model.types.*;
|
||||||
|
import dk.camelot64.kickc.model.values.ConstantEnumerable;
|
||||||
import dk.camelot64.kickc.model.values.ConstantInteger;
|
import dk.camelot64.kickc.model.values.ConstantInteger;
|
||||||
import dk.camelot64.kickc.model.values.ConstantLiteral;
|
import dk.camelot64.kickc.model.values.ConstantLiteral;
|
||||||
|
import dk.camelot64.kickc.model.values.ConstantPointer;
|
||||||
|
|
||||||
/** Binary bitwise exclusive or Operator ( x ^ y ) */
|
/** Binary bitwise exclusive or Operator ( x ^ y ) */
|
||||||
public class OperatorBitwiseXor extends OperatorBinary {
|
public class OperatorBitwiseXor extends OperatorBinary {
|
||||||
@ -14,8 +16,10 @@ public class OperatorBitwiseXor extends OperatorBinary {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ConstantLiteral calculateLiteral(ConstantLiteral left, ConstantLiteral right) {
|
public ConstantLiteral calculateLiteral(ConstantLiteral left, ConstantLiteral right) {
|
||||||
if(left instanceof ConstantInteger && right instanceof ConstantInteger) {
|
if(left instanceof ConstantPointer && right instanceof ConstantEnumerable) {
|
||||||
return new ConstantInteger(((ConstantInteger) left).getInteger() ^ ((ConstantInteger) right).getInteger());
|
return new ConstantPointer(((ConstantPointer) left).getLocation() ^ ((ConstantEnumerable) right).getInteger(), ((ConstantPointer) left).getElementType());
|
||||||
|
} else if(left instanceof ConstantEnumerable && right instanceof ConstantEnumerable) {
|
||||||
|
return new ConstantInteger(((ConstantEnumerable) left).getInteger() ^ ((ConstantEnumerable) right).getInteger());
|
||||||
}
|
}
|
||||||
throw new CompileError("Calculation not implemented " + left + " " + getOperator() + " " + right);
|
throw new CompileError("Calculation not implemented " + left + " " + getOperator() + " " + right);
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,10 @@ package dk.camelot64.kickc.model.operators;
|
|||||||
|
|
||||||
import dk.camelot64.kickc.model.CompileError;
|
import dk.camelot64.kickc.model.CompileError;
|
||||||
import dk.camelot64.kickc.model.ConstantNotLiteral;
|
import dk.camelot64.kickc.model.ConstantNotLiteral;
|
||||||
import dk.camelot64.kickc.model.types.*;
|
import dk.camelot64.kickc.model.types.SymbolType;
|
||||||
|
import dk.camelot64.kickc.model.types.SymbolTypeConversion;
|
||||||
|
import dk.camelot64.kickc.model.types.SymbolTypeInteger;
|
||||||
|
import dk.camelot64.kickc.model.types.SymbolTypePointer;
|
||||||
import dk.camelot64.kickc.model.values.*;
|
import dk.camelot64.kickc.model.values.*;
|
||||||
|
|
||||||
/** Binary plus Operator ( x + y ) */
|
/** Binary plus Operator ( x + y ) */
|
||||||
@ -14,18 +17,11 @@ public class OperatorPlus extends OperatorBinary {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ConstantLiteral calculateLiteral(ConstantLiteral left, ConstantLiteral right) {
|
public ConstantLiteral calculateLiteral(ConstantLiteral left, ConstantLiteral right) {
|
||||||
if(left instanceof ConstantInteger && right instanceof ConstantInteger) {
|
if(left instanceof ConstantPointer && right instanceof ConstantEnumerable) {
|
||||||
return new ConstantInteger(((ConstantInteger) left).getInteger() + ((ConstantInteger) right).getInteger());
|
long location = ((ConstantPointer) left).getLocation() + ((ConstantEnumerable) right).getInteger();
|
||||||
} else if(left instanceof ConstantInteger && right instanceof ConstantChar) {
|
|
||||||
return new ConstantInteger(((ConstantInteger) left).getInteger() + ((ConstantChar) right).getChar());
|
|
||||||
} else if(left instanceof ConstantChar && right instanceof ConstantInteger) {
|
|
||||||
return new ConstantInteger(((ConstantChar) left).getChar() + ((ConstantInteger) right).getInteger());
|
|
||||||
} else if(left instanceof ConstantPointer && right instanceof ConstantInteger) {
|
|
||||||
long location = ((ConstantPointer) left).getLocation() + ((ConstantInteger) right).getInteger();
|
|
||||||
return new ConstantPointer(location, ((ConstantPointer) left).getElementType());
|
return new ConstantPointer(location, ((ConstantPointer) left).getElementType());
|
||||||
} else if(left instanceof ConstantInteger && right instanceof ConstantPointer) {
|
} else if(left instanceof ConstantEnumerable && right instanceof ConstantEnumerable) {
|
||||||
long location = ((ConstantPointer) right).getLocation() + ((ConstantInteger) left).getInteger();
|
return new ConstantInteger(((ConstantEnumerable) left).getInteger() + ((ConstantEnumerable) right).getInteger());
|
||||||
return new ConstantPointer(location, ((ConstantPointer) right).getElementType());
|
|
||||||
} else if(left instanceof ConstantString && right instanceof ConstantInteger) {
|
} else if(left instanceof ConstantString && right instanceof ConstantInteger) {
|
||||||
throw new ConstantNotLiteral("String pointer not literal");
|
throw new ConstantNotLiteral("String pointer not literal");
|
||||||
}
|
}
|
||||||
@ -42,7 +38,7 @@ public class OperatorPlus extends OperatorBinary {
|
|||||||
}
|
}
|
||||||
// Handle numeric types through proper promotion
|
// Handle numeric types through proper promotion
|
||||||
if(SymbolType.isInteger(type1) && SymbolType.isInteger(type2)) {
|
if(SymbolType.isInteger(type1) && SymbolType.isInteger(type2)) {
|
||||||
return SymbolTypeConversion.convertedMathType( (SymbolTypeInteger) type1, (SymbolTypeInteger)type2);
|
return SymbolTypeConversion.convertedMathType((SymbolTypeInteger) type1, (SymbolTypeInteger) type2);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new CompileError("Type inference case not handled " + type1 + " " + getOperator() + " " + type2);
|
throw new CompileError("Type inference case not handled " + type1 + " " + getOperator() + " " + type2);
|
||||||
|
@ -198,6 +198,11 @@ public class TestPrograms {
|
|||||||
assertError("constant-prepost", "Constant value contains a pre/post-modifier");
|
assertError("constant-prepost", "Constant value contains a pre/post-modifier");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//@Test
|
||||||
|
//public void testElefont() throws IOException, URISyntaxException {
|
||||||
|
// compileAndCompare("complex/elefont/elefont-sprites", log());
|
||||||
|
//}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGridBobs() throws IOException, URISyntaxException {
|
public void testGridBobs() throws IOException, URISyntaxException {
|
||||||
compileAndCompare("complex/prebob/grid-bobs");
|
compileAndCompare("complex/prebob/grid-bobs");
|
||||||
|
55
src/test/kc/complex/elefont/elefont-sprites.kc
Normal file
55
src/test/kc/complex/elefont/elefont-sprites.kc
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
// Put a 2x2 font into sprites and show on screen
|
||||||
|
|
||||||
|
import "c64"
|
||||||
|
|
||||||
|
char * const CHARSET_DEFAULT = 0x1000;
|
||||||
|
char * const ELEFONT = 0x2000;
|
||||||
|
char * const SPRITES = 0x3000;
|
||||||
|
char * const SCREEN = 0x0400;
|
||||||
|
char * const SCREEN_SPRITES = SCREEN + SPRITE_PTRS;
|
||||||
|
|
||||||
|
|
||||||
|
kickasm(pc ELEFONT, resource "elefont.bin") {{
|
||||||
|
.import binary "elefont.bin"
|
||||||
|
}}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
*D018 = toD018(SCREEN, CHARSET_DEFAULT);
|
||||||
|
font_2x2_to_sprites(ELEFONT, SPRITES, 64);
|
||||||
|
*SPRITES_ENABLE = 1;
|
||||||
|
SPRITES_XPOS[0] = 100;
|
||||||
|
SPRITES_YPOS[0] = 100;
|
||||||
|
SPRITES_COLS[0] = WHITE;
|
||||||
|
SCREEN_SPRITES[0] = toSpritePtr(SPRITES)+1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert a 2x2-font to sprites
|
||||||
|
// - font_2x2 The source 2x2-font
|
||||||
|
// - sprites The destination sprites
|
||||||
|
// - num_chars The number of chars to convert
|
||||||
|
void font_2x2_to_sprites(char* font_2x2, char* sprites, char num_chars) {
|
||||||
|
char * char_current = font_2x2;
|
||||||
|
char * sprite = sprites;
|
||||||
|
for(char c=0;c<num_chars;c++) {
|
||||||
|
// Upper char
|
||||||
|
char * char_left = char_current;
|
||||||
|
char * char_right = char_current + 0x40*8;
|
||||||
|
char sprite_idx = 0;
|
||||||
|
for(char i: 0..20) {
|
||||||
|
sprite[sprite_idx++] = char_left[i&7];
|
||||||
|
sprite[sprite_idx++] = char_right[i&7];
|
||||||
|
sprite[sprite_idx++] = 0x00;
|
||||||
|
if(i==7) {
|
||||||
|
// Lower char
|
||||||
|
char_left = char_current + 0x80*8;
|
||||||
|
char_right = char_current + 0xc0*8;
|
||||||
|
} else if(i==15) {
|
||||||
|
// Empty char
|
||||||
|
char_left = font_2x2+' '*8;
|
||||||
|
char_right = font_2x2+' '*8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
char_current += 8;
|
||||||
|
sprite += 0x40;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user