This commit is contained in:
dschmenk 2015-02-13 16:47:51 -08:00
commit b8affbb871
7 changed files with 273 additions and 131 deletions

View File

@ -11,7 +11,7 @@ To keep development compartmentalized and easily managed, PLASMA uses relatively
To start things off, here is the standard introductory program:
```
import stdlib
import cmdsys
predef puts
end
@ -62,7 +62,7 @@ The beginning of the source file is the best place for certain declarations. Thi
Module dependencies will direct the loader to make sure these modules are loaded first, thus resolving any outstanding references. A module dependency is declared with the `import` statement block with predefined function and data definitions. The `import` block is completed with an `end`. An example:
```
import stdlib
import cmdsys
const reshgr1 = $0004
predef putc, puts, getc, gets, cls, gotoxy
end
@ -223,7 +223,7 @@ def hgrfill(val)
for yscan = 0 to 191
for xscan = 0 to 19
hgrscan:[yscan][xscan] = val
hgrscan:[yscan, xscan] = val
next
next
end
@ -235,7 +235,7 @@ def hgrfill(val)
for yscan = 0 to 191
for xscan = 0 to 39
hgrscan.[yscan][xscan] = val
hgrscan.[yscan, xscan] = val
next
next
end

View File

@ -3,6 +3,7 @@ package org.badvision.outlaweditor.apple;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
@ -113,12 +114,8 @@ public class AppleImageEditor extends ImageEditor implements EventHandler<MouseE
if (imageData == null) {
PlatformData data = getPlatformData(getPlatform());
if (data == null) {
data = new PlatformData();
data.setWidth(getPlatform().maxImageWidth);
data.setHeight(getPlatform().maxImageHeight);
data.setPlatform(getPlatform().name());
data.setValue(getPlatform().imageRenderer.createImageBuffer(getPlatform().maxImageWidth, getPlatform().maxImageHeight));
getEntity().getDisplayData().add(data);
createNewPlatformImage(getPlatform().maxImageWidth, getPlatform().maxImageHeight);
data = getPlatformData(getPlatform());
}
imageData = data.getValue();
}
@ -394,6 +391,22 @@ public class AppleImageEditor extends ImageEditor implements EventHandler<MouseE
setData(buf);
redraw();
return true;
} else if (contentPath.startsWith("selection/image")) {
String[] bufferDetails = contentPath.substring(16).split("/");
int imageNumber = Integer.parseInt(bufferDetails[0]);
if ("all".equals(bufferDetails[1])) {
Image sourceImage = Application.gameData.getImage().get(imageNumber);
for (PlatformData data : sourceImage.getDisplayData()) {
if (data.getPlatform().equals(getPlatform().toString())) {
setData(Arrays.copyOf(data.getValue(), data.getValue().length));
redraw();
return true;
}
}
System.err.println("Unable to paste from source image, no matching platform data.");
} else {
System.err.println("Unable to paste partial images at this time... sorry. :-(");
}
}
return false;
}
@ -426,9 +439,9 @@ public class AppleImageEditor extends ImageEditor implements EventHandler<MouseE
public void exportImage() {
byte[] output = new byte[0x02000];
int counter = 0;
for (int y = 0; y < 192; y++) {
for (int y = 0; y < getHeight(); y++) {
int offset = calculateHiresOffset(y);
for (int x = 0; x < 40; x++) {
for (int x = 0; x < getWidth(); x++) {
output[offset + x] = getImageData()[counter++];
}
}
@ -448,7 +461,7 @@ public class AppleImageEditor extends ImageEditor implements EventHandler<MouseE
public void resize(final int newWidth, final int newHeight) {
UIAction.confirm("Do you want to scale the image? If you select no, the image will be cropped as needed.", () -> {
rescale(newWidth, newHeight);
}, () -> {
}, () -> {
crop(newWidth, newHeight);
});
}
@ -462,6 +475,8 @@ public class AppleImageEditor extends ImageEditor implements EventHandler<MouseE
* @param newHeight
*/
public void rescale(int newWidth, int newHeight) {
createNewPlatformImage(newWidth, newHeight);
importImage(currentImage);
}
/**
@ -473,4 +488,13 @@ public class AppleImageEditor extends ImageEditor implements EventHandler<MouseE
*/
public void crop(int newWidth, int newHeight) {
}
private void createNewPlatformImage(int width, int height) {
PlatformData data = new PlatformData();
data.setWidth(width);
data.setHeight(height);
data.setPlatform(getPlatform().name());
data.setValue(getPlatform().imageRenderer.createImageBuffer(width, height));
getEntity().getDisplayData().add(data);
}
}

View File

@ -101,11 +101,27 @@ public enum FillPattern {
White_PC(false, 1, false, "+++++++"),
White_Lo(true, 1, false, "+++++++"),
White_Hi(true, 1, true, "+++++++"),
BW1(false, 4, false,
BW1_PC(false, 4, false,
"++--++--++--++--++--++--++--",
"--++--++--++--++--++--++--++"
),
BW2(false, 4, false,
BW1_Lo(true, 4, false,
"++--++--++--++--++--++--++--",
"--++--++--++--++--++--++--++"
),
BW1_Hi(true, 4, true,
"++--++--++--++--++--++--++--",
"--++--++--++--++--++--++--++"
),
BW2_PC(false, 4, false,
"--++--++--++--++--++--++--++",
"++--++--++--++--++--++--++--"
),
BW2_Lo(true, 4, false,
"--++--++--++--++--++--++--++",
"++--++--++--++--++--++--++--"
),
BW2_Hi(true, 4, true,
"--++--++--++--++--++--++--++",
"++--++--++--++--++--++--++--"
);

View File

@ -768,13 +768,16 @@ coalesce: !zone
;------------------------------------------------------------------------------
shared_scan: !zone
php ; save carry (set to check active flg, clr to skip check)
sta isAuxCmd ; save whether main or aux mem
jsr scanForAddr ; scan for block that matches
beq invalAddr ; if not found, invalid
bcs invalAddr ; if addr not exactly equal, invalid
plp
lda tSegType,x ; get existing flags
bcc + ; optionally, skip check of active flag
bpl invalAddr ; must be an active block
rts
+ rts
invalAddr: !zone
ldx #<+
@ -810,6 +813,7 @@ main_lock: !zone
aux_lock:
lda #1 ; index for aux-mem request
shared_lock:
sec ; do check active flag in scan
jsr shared_scan ; scan for exact memory block
ora #$40 ; set the 'locked' flag
sta tSegType,x ; store flags back
@ -826,6 +830,7 @@ main_unlock: !zone
aux_unlock:
lda #1 ; index for aux-mem request
shared_unlock:
sec ; do check active flag in scan
jsr shared_scan ; scan for exact memory block
and #$BF ; mask off the 'locked' flag
sta tSegType,x ; store flags back
@ -842,6 +847,7 @@ main_free: !zone
aux_free:
lda #1 ; index for aux-mem request
shared_free:
clc ; do not check for active flg (ok to multiple free)
jsr shared_scan ; scan for exact memory block
and #$3F ; remove the 'active' and 'locked' flags
sta tSegType,x ; store flags back

View File

@ -81,6 +81,11 @@
jsr _waitKey
}
; Debug code to support macros
jmp _afterDebug
; Fetch a byte pointed to by the first entry on the stack, and advance that entry.
_getStackByte !zone {
inc $101,x
bne +
@ -187,4 +192,6 @@ _waitKey: !zone {
jsr iosave
jsr rdkey
jmp iorest
}
}
_afterDebug:

View File

@ -872,7 +872,7 @@ def move2D(ox, oy)
*relX = ox + *relX
*relY = oy + *relY
checkCrossing()
renderFrame()
redraw = TRUE
end
def moveNorth()

View File

@ -12,7 +12,7 @@
!source "../include/mem.i"
!source "../include/plasma.i"
DEBUG = 1 ; 1=some logging, 2=lots of logging
DEBUG = 0 ; 1=some logging, 2=lots of logging
HEADER_LENGTH=6
SECTION_WIDTH=22
@ -112,10 +112,20 @@ LOAD_SECTION
LDX #00 ; This is a bogus map section, don't load
LDY #00
RTS
.doLoad TAY ; resource # in Y
.doLoad TAY ; resource # in Y
!if DEBUG {
+prStr : !text "loadSection: ",0
+prY
}
LDX #RES_TYPE_2D_MAP
LDA #QUEUE_LOAD
JMP mainLoader
JSR mainLoader
!if DEBUG {
+prStr : !text "->",0
+prYX
+crout
}
RTS
!macro loadSection ptr {
JSR LOAD_SECTION
STX ptr
@ -138,22 +148,38 @@ FINISH_MAP_LOAD
; --> free up unused resource
LDX ptr
LDY ptr+1
BEQ + ; skip if null ptr
LDA #FREE_MEMORY
JSR mainLoader
+
}
;----------------------------------------------------------------------
; >> LOAD TILES
; Load tile resource (A = Resource ID)
LOAD_TILESET
TAY
TAY ; resource # in Y
!if DEBUG {
+prStr : !text "loadTileset ",0
+prY
}
LDX #RES_TYPE_TILESET
LDA #QUEUE_LOAD
JMP mainLoader
!macro loadTileset mapData, ptr {
JSR mainLoader
!if DEBUG {
+prStr : !text "-> ",0
+prYX
+crout
}
RTS
!macro loadTileset mapId, mapData, ptr {
LDY #0
LDX mapId
INX ; if map id is $FF, X is now zero
BEQ + ; and if so, skip loading tileset
LDY #4
LDA (mapData),Y
JSR LOAD_TILESET
STX ptr
+ STX ptr
STY ptr+1
}
;----------------------------------------------------------------------
@ -213,10 +239,12 @@ FREE_ALL_TILES
}
LOAD_ALL_TILES
+loadTileset NW_MAP_LOC, NW_TILESET_LOC
+loadTileset NE_MAP_LOC, NE_TILESET_LOC
+loadTileset SW_MAP_LOC, SW_TILESET_LOC
+loadTileset SE_MAP_LOC, SE_TILESET_LOC
+startLoad
+loadTileset NW_MAP_ID, NW_MAP_LOC, NW_TILESET_LOC
+loadTileset NE_MAP_ID, NE_MAP_LOC, NE_TILESET_LOC
+loadTileset SW_MAP_ID, SW_MAP_LOC, SW_TILESET_LOC
+loadTileset SE_MAP_ID, SE_MAP_LOC, SE_TILESET_LOC
+finishLoad
RTS
!macro loadAllTiles {
JSR LOAD_ALL_TILES
@ -226,19 +254,19 @@ LOAD_ALL_TILES
!zone
CROSS
LDA REL_Y
CMP #VIEWPORT_VERT_PAD-1
CMP #VIEWPORT_VERT_PAD
BPL .10
JSR CROSS_NORTH
.10 LDA REL_Y
CMP #VIEWPORT_VERT_PAD+SECTION_HEIGHT
CMP #(2*SECTION_HEIGHT)-VIEWPORT_VERT_PAD
BMI .20
JSR CROSS_SOUTH
.20 LDA REL_X
CMP #VIEWPORT_HORIZ_PAD-1
CMP #VIEWPORT_HORIZ_PAD
BPL .30
JSR CROSS_WEST
.30 LDA REL_X
CMP #VIEWPORT_HORIZ_PAD+SECTION_WIDTH
CMP #(2*SECTION_WIDTH)-VIEWPORT_HORIZ_PAD
BMI .40
JSR CROSS_EAST
.40 RTS
@ -246,6 +274,17 @@ CROSS
; >> CROSS NORTH BOUNDARY (Load next section to the north)
!zone
CROSS_NORTH
; Get new NW section
LDY #NORTH
LDA (NW_MAP_LOC),Y
CMP #$FF
BEQ .noMap
TAX
; Get new NE section
LDA (NE_MAP_LOC),Y
PHA
TXA
PHA
+freeAllTiles
+freeResource SW_MAP_LOC
+freeResource SE_MAP_LOC
@ -257,23 +296,39 @@ CROSS_NORTH
+move_word NW_MAP_LOC, SW_MAP_LOC
+move_byte NE_MAP_ID, SE_MAP_ID
+move_word NE_MAP_LOC, SE_MAP_LOC
; Get new NW section
; Load new NW section
+startLoad
LDY #00
LDA (SW_MAP_LOC),Y
PLA
STA NW_MAP_ID
+loadSection NW_MAP_LOC
; Get the new NE section
LDA (SE_MAP_LOC),Y
; Load the new NE section
PLA
STA NE_MAP_ID
+loadSection NE_MAP_LOC
+loadAllTiles
+finishLoad
+loadAllTiles
RTS
.noMap INC REL_Y
JMP bell
;----------------------------------------------------------------------
; >> CROSS EAST BOUNDARY (Load next section to the east)
!zone
CROSS_EAST
LDA NE_MAP_ID
CMP #$FF
BEQ .noMap
; Get new NE section
LDY #EAST
LDA (NE_MAP_LOC),Y
CMP #$FF
BEQ .noMap
TAX
; Get new SE section
LDA (SE_MAP_LOC),Y
PHA
TXA
PHA
+freeAllTiles
+freeResource NW_MAP_LOC
+freeResource SW_MAP_LOC
@ -285,24 +340,38 @@ CROSS_EAST
+move_word NE_MAP_LOC, NW_MAP_LOC
+move_byte SE_MAP_ID, SW_MAP_ID
+move_word SE_MAP_LOC, SW_MAP_LOC
; Get new NE section
; Load new NE section
+startLoad
LDY #EAST
LDA (NW_MAP_LOC),Y
PLA
STA NE_MAP_ID
+loadSection NE_MAP_LOC
; Get the new SE section
LDY #EAST
LDA (SW_MAP_LOC),Y
; Load the new SE section
PLA
STA SE_MAP_ID
+loadSection SE_MAP_LOC
+loadAllTiles
+finishLoad
+loadAllTiles
RTS
.noMap DEC REL_X
JMP bell
;----------------------------------------------------------------------
; >> CROSS SOUTH BOUNDARY (Load next section to the south)
!zone
CROSS_SOUTH
LDA SW_MAP_ID
CMP #$FF
BEQ .noMap
; Get new SW section
LDY #SOUTH
LDA (SW_MAP_LOC),Y
CMP #$FF
BEQ .noMap
TAX
; Get the new SE section
LDA (SE_MAP_LOC),Y
PHA
TXA
PHA
+freeAllTiles
+freeResource NW_MAP_LOC
+freeResource NE_MAP_LOC
@ -314,24 +383,35 @@ CROSS_SOUTH
+move_word SW_MAP_LOC, NW_MAP_LOC
+move_byte SE_MAP_ID, NE_MAP_ID
+move_word SE_MAP_LOC, NE_MAP_LOC
; Get new SW section
; Load new SW section
+startLoad
LDY #SOUTH
LDA (NW_MAP_LOC),Y
PLA
STA SW_MAP_ID
+loadSection SW_MAP_LOC
; Get the new SE section
LDY #SOUTH
LDA (NE_MAP_LOC),Y
; Load the new SE section
PLA
STA SE_MAP_ID
+loadSection SE_MAP_LOC
+loadAllTiles
+finishLoad
+loadAllTiles
RTS
.noMap DEC REL_Y
JMP bell
;----------------------------------------------------------------------
; >> CROSS WEST BOUNDARY (load next section to the west)
!zone
CROSS_WEST
; Get new NW section
LDY #WEST
LDA (NW_MAP_LOC),Y
CMP #$FF
BEQ .noMap
TAX
; Get the new SW section
LDA (SW_MAP_LOC),Y
PHA
TXA
PHA
+freeAllTiles
+freeResource NE_MAP_LOC
+freeResource SE_MAP_LOC
@ -343,20 +423,20 @@ CROSS_WEST
+move_word NW_MAP_LOC, NE_MAP_LOC
+move_byte SW_MAP_ID, SE_MAP_ID
+move_word SW_MAP_LOC, SE_MAP_LOC
; Get new NW section
; Load new NW section
+startLoad
LDY #WEST
LDA (NE_MAP_LOC),Y
PLA
STA NW_MAP_ID
+loadSection NW_MAP_LOC
; Get the new SE section
LDY #WEST
LDA (SE_MAP_LOC),Y
; Load the new SW section
PLA
STA SW_MAP_ID
+loadSection SW_MAP_LOC
+loadAllTiles
+finishLoad
+loadAllTiles
RTS
.noMap INC REL_X
JMP bell
;----------------------------------------------------------------------
; >> SET PLAYER TILE (A = tile)
;----------------------------------------------------------------------
@ -411,33 +491,42 @@ CROSS_WEST
DRAW
; For each quadrant, display relevant parts of screen
!if DEBUG { +prStr : !text "In draw.",0 }
.checkNWQuad
LDA #00
STA DRAW_Y_START
STA DRAW_X_START
+drawMapSection NW_MAP_LOC, NW_TILESET_LOC, 0, 0
.checkNEQuad
LDA DRAW_WIDTH
STA DRAW_X_START
+drawMapSection NE_MAP_LOC, NE_TILESET_LOC, SECTION_WIDTH, 0
.checkSWQuad
LDA DRAW_HEIGHT
STA DRAW_Y_START
LDA #00
STA DRAW_X_START
+drawMapSection SW_MAP_LOC, SW_TILESET_LOC, 0, SECTION_HEIGHT
.checkSEQuad
LDA DRAW_WIDTH
STA DRAW_X_START
+drawMapSection SE_MAP_LOC, SE_TILESET_LOC, SECTION_WIDTH, SECTION_HEIGHT
!if DEBUG {
+prStr : !text "Draw complete, REL_X=",0
!if DEBUG >= 2 {
+prStr : !text "Draw: REL_X=",0
+prByte REL_X
+prStr : !text "REL_Y=",0
+prByte REL_Y
+crout
}
.checkNWQuad
LDA #0
STA DRAW_Y_START
STA DRAW_X_START
!if DEBUG >= 2 { +prStr : !text "NW quad.",0 }
+drawMapSection NW_MAP_LOC, NW_TILESET_LOC, 0, 0
.checkNEQuad
LDA DRAW_WIDTH
BPL +
LDA #0
+ STA DRAW_X_START
!if DEBUG >= 2 { +prStr : !text "NE quad.",0 }
+drawMapSection NE_MAP_LOC, NE_TILESET_LOC, SECTION_WIDTH, 0
.checkSWQuad
LDA DRAW_HEIGHT
BPL +
LDA #0
+ STA DRAW_Y_START
LDA #0
STA DRAW_X_START
!if DEBUG >= 2 { +prStr : !text "SW quad.",0 }
+drawMapSection SW_MAP_LOC, SW_TILESET_LOC, 0, SECTION_HEIGHT
.checkSEQuad
LDA DRAW_WIDTH
BPL +
LDA #0
+ STA DRAW_X_START
!if DEBUG >= 2 { +prStr : !text "SE quad.",0 }
+drawMapSection SE_MAP_LOC, SE_TILESET_LOC, SECTION_WIDTH, SECTION_HEIGHT
RTS
MainDraw
@ -457,37 +546,47 @@ MainDraw
; and if there is not then the tile is skipped. Otherwise the tile is drawn, etc.
;--------------------------------------
; COL_OFFSET and ROW_OFFSET specify where on the screen the whole map gets drawn.
; Adjust these so it lands at the right place in the frame image.
COL_OFFSET = 2
ROW_OFFSET = 3
!if DEBUG >= 2 {
+prStr : !text " DR_X_ST=",0
+prByte DRAW_X_START
+prStr : !text "SEC_X_ST=",0
+prByte SECTION_X_START
+prStr : !text "DR_W=", 0
+prByte DRAW_WIDTH
+crout
+prStr : !text " +DR_Y_ST=",0
+prByte DRAW_Y_START
+prStr : !text "SEC_Y_ST=",0
+prByte SECTION_Y_START
+prStr : !text "DR_H=", 0
+prByte DRAW_HEIGHT
+crout
}
LDA DRAW_SECTION+1 ; skip if no map section here
BNE .gotMap
.noDraw
RTS
.gotMap
!if DEBUG >= 1 {
+prStr : !text "SECTION_X_START=",0
+prByte SECTION_X_START
+prStr : !text "DRAW_WIDTH=", 0
+prByte DRAW_WIDTH
+prStr : !text "SECTION_Y_START=",0
+prByte SECTION_Y_START
+prStr : !text "DRAW_HEIGHT=", 0
+prByte DRAW_HEIGHT
+crout
}
LDA DRAW_HEIGHT
BEQ .noDraw
BMI .noDraw
STA Y_COUNTER
LDA DRAW_Y_START
BMI .noDraw
STA Y_LOC
.rowLoop
LDA DRAW_WIDTH
BEQ .noDraw
BMI .noDraw
STA X_COUNTER
LDA DRAW_X_START
BMI .noDraw
; Identify start of map data (upper left)
; Self-modifying code: Update all the STA statements in the drawTile section
LDA Y_LOC
@ -523,35 +622,27 @@ ROW_OFFSET = 3
}
}
;Calculate data offset == DRAW_SECTION + (row * 22) + 6 == DRAW_SECTION + (row * 2 + row * 4 + row * 16) + 6
;Look up data offset (old bit shifting multiplication logic was buggy)
LDA DRAW_SECTION
LDY DRAW_SECTION + 1
CLC
LDA SECTION_Y_START ;row * 2
ASL
ADC #HEADER_LENGTH ; +6
ADC SECTION_X_START
STA ROW_LOCATION
LDA SECTION_Y_START ; row * 4
ASL
ASL
ADC ROW_LOCATION
STA ROW_LOCATION
LDA SECTION_Y_START ; row * 16 -- possibly carry
ASL
ASL
ASL
ASL
ADC ROW_LOCATION
STA ROW_LOCATION
LDA DRAW_SECTION + 1
ADC #$00 ; This is a short way for handling carry without a branch
STA ROW_LOCATION + 1
LDA DRAW_SECTION ; DRAW_SECTION is done at the very end in case it causes an overflow
ADC ROW_LOCATION
STA ROW_LOCATION
; Handle carry if needed
BCC .doneCalculatingLocation
INC ROW_LOCATION + 1
.doneCalculatingLocation
LDX SECTION_Y_START
ADC tblMAPl,X
BCC +
INY ; handle carry from prev add
+ CPX #12 ; rows 0-11 are on 1st page of map, 12-22 on 2nd page
BCC +
INY ; go to 2nd pg
CLC
+ ADC SECTION_X_START
BCC +
INY ; handle carry from prev add
+ SEC
SBC DRAW_X_START ; because it gets added back in later by indexing with X
BCS +
DEY
+ STA ROW_LOCATION
STY ROW_LOCATION + 1
LDX DRAW_X_START
; Display row of tiles
.next_col
@ -590,12 +681,6 @@ ROW_OFFSET = 3
TXA ; In the drawing part, we need X=X*2
ASL
TAX
!if DEBUG >= 2 {
+prStr : !text "Draw at ",0
+prX
+crout
+waitKey
}
.drawTile !for row, 16 {
LDA (TILE_SOURCE),Y ;0
STA $2000, X ;2
@ -657,8 +742,8 @@ INIT
LDA (SW_MAP_LOC),Y
STA SE_MAP_ID
+loadSection SE_MAP_LOC
+ +loadAllTiles
+finishLoad
+ +finishLoad
+loadAllTiles
; set up the X and Y coordinates
LDX #VIEWPORT_HORIZ_PAD
LDY #VIEWPORT_VERT_PAD
@ -673,4 +758,8 @@ tblHGRl
tblHGRh
!byte $20,$20,$21,$21,$22,$22,$23,$23
!byte $20,$20,$21,$21,$22,$22,$23,$23
!byte $20,$20,$21,$21,$22,$22,$23,$23
!byte $20,$20,$21,$21,$22,$22,$23,$23
tblMAPl !for row, 23 {
!byte <((row-1)*22)+6
}